Page MenuHomeFreeBSD

D60296.diff
No OneTemporary

D60296.diff

Index: sys/dev/mpi3mr/mpi3mr.h
===================================================================
--- sys/dev/mpi3mr/mpi3mr.h
+++ sys/dev/mpi3mr/mpi3mr.h
@@ -372,14 +372,15 @@
U16 io_throttle_data_length;
U16 io_throttle_low;
U16 io_throttle_high;
+ bool max_req_limit;
};
struct mpi3mr_op_req_queue {
U16 ci;
U16 pi;
U16 num_reqs;
- U8 qid;
- U8 reply_qid;
+ U16 qid;
+ U16 reply_qid;
U32 qsz;
void *q_base;
bus_dma_tag_t q_base_tag;
@@ -391,7 +392,7 @@
struct mpi3mr_op_reply_queue {
U16 ci;
U8 ephase;
- U8 qid;
+ U16 qid;
U16 num_replies;
U32 qsz;
bus_dma_tag_t q_base_tag;
@@ -401,6 +402,7 @@
mpi3mr_atomic_t pend_ios;
bool in_use;
struct mtx q_lock;
+ U16 qfull_watermark;
};
struct irq_info {
@@ -776,6 +778,8 @@
void *timestamp_chan;
u_int8_t timestamp_thread_active;
U32 ts_update_interval;
+ mpi3mr_atomic_t reply_qfull_count;
+ bool prevent_reply_qfull;
};
static __inline uint64_t
Index: sys/dev/mpi3mr/mpi3mr.c
===================================================================
--- sys/dev/mpi3mr/mpi3mr.c
+++ sys/dev/mpi3mr/mpi3mr.c
@@ -398,7 +398,8 @@
U8 *req_entry;
U16 req_sz = sc->facts.op_req_sz;
struct mpi3mr_irq_context *irq_ctx;
-
+ struct mpi3mr_op_reply_queue *op_reply_q = NULL;
+
mtx_lock_spin(&op_req_q->q_lock);
pi = op_req_q->pi;
@@ -415,6 +416,16 @@
}
}
+ /* If Reply queue is nearing to get full, pushback IOs to SML*/
+ op_reply_q = sc->op_reply_q + (op_req_q->reply_qid - 1);
+ if ((sc->prevent_reply_qfull == true) &&
+ (mpi3mr_atomic_read(&op_reply_q->pend_ios) >
+ (op_reply_q->qfull_watermark))) {
+ mpi3mr_atomic_inc(&sc->reply_qfull_count);
+ retval = EAGAIN;
+ goto out;
+ }
+
req_entry = (U8 *)op_req_q->q_base + (pi * req_sz);
memset(req_entry, 0, req_sz);
memcpy(req_entry, req, MPI3MR_AREQ_FRAME_SZ);
@@ -600,6 +611,8 @@
op_reply_q->qsz = op_reply_q->num_replies * sc->op_reply_sz;
op_reply_q->ephase = 1;
+ op_reply_q->qfull_watermark =
+ op_reply_q->num_replies - (MPI3MR_THRESHOLD_REPLY_COUNT * 2);
if (!op_reply_q->q_base) {
snprintf(q_lock_name, 32, "Reply Queue Lock[%d]", qid);
@@ -1617,6 +1630,8 @@
sc->op_reply_sz = 1 << ((ioc_config &
MPI3_SYSIF_IOC_CONFIG_OPER_RPY_ENT_SZ) >>
MPI3_SYSIF_IOC_CONFIG_OPER_RPY_ENT_SZ_SHIFT);
+ sc->facts.max_req_limit = (facts_flags &
+ MPI3_IOCFACTS_FLAGS_MAX_REQ_PER_REPLY_QUEUE_LIMIT);
sc->facts.ioc_num = facts_data->IOCNumber;
sc->facts.who_init = facts_data->WhoInit;
@@ -2952,6 +2967,9 @@
sc->num_io_throttle_group = sc->facts.max_io_throttle_group;
mpi3mr_atomic_set(&sc->pend_large_data_sz, 0);
+ if (sc->facts.max_req_limit)
+ sc->prevent_reply_qfull = true;
+
if (init_type == MPI3MR_INIT_TYPE_RESET) {
retval = mpi3mr_validate_fw_update(sc);
if (retval) {
Index: sys/dev/mpi3mr/mpi3mr_pci.c
===================================================================
--- sys/dev/mpi3mr/mpi3mr_pci.c
+++ sys/dev/mpi3mr/mpi3mr_pci.c
@@ -104,6 +104,17 @@
MODULE_DEPEND(mpi3mr, cam, 1, 1, 1);
+static int
+mpi3mr_sysctl_reply_qfull_count(SYSCTL_HANDLER_ARGS)
+{
+ struct mpi3mr_softc *sc = (struct mpi3mr_softc *)arg1;
+ uint32_t val;
+
+ val = mpi3mr_atomic_read(&sc->reply_qfull_count);
+
+ return (sysctl_handle_int(oidp, &val, 0, req));
+}
+
/*
* mpi3mr_setup_sysctl: setup sysctl values for mpi3mr
* input: Adapter instance soft state
@@ -165,6 +176,13 @@
SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
OID_AUTO, "iot_enable", CTLFLAG_RW, &sc->iot_enable, 0,
"IO throttling enable at driver level(for debug purpose)");
+
+ SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
+ OID_AUTO, "reply_qfull_count",
+ CTLTYPE_UINT | CTLFLAG_RD,
+ sc, 0,
+ mpi3mr_sysctl_reply_qfull_count, "IU",
+ "Number of times reply queue full prevention triggered");
}
/*

File Metadata

Mime Type
text/plain
Expires
Wed, Oct 7, 7:53 PM (6 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40350704
Default Alt Text
D60296.diff (3 KB)

Event Timeline