From: James Smart <jsmart2021@gmail.com>
To: linux-scsi@vger.kernel.org
Cc: maier@linux.ibm.com, dwagner@suse.de, bvanassche@acm.org,
James Smart <jsmart2021@gmail.com>,
Ram Vegesna <ram.vegesna@broadcom.com>
Subject: [PATCH v2 28/32] elx: efct: IO timeout handling routines
Date: Fri, 20 Dec 2019 14:37:19 -0800 [thread overview]
Message-ID: <20191220223723.26563-29-jsmart2021@gmail.com> (raw)
In-Reply-To: <20191220223723.26563-1-jsmart2021@gmail.com>
This patch continues the efct driver population.
This patch adds driver definitions for:
Add support for a WQE timer to handle the wqe and IO timeouts.
Signed-off-by: Ram Vegesna <ram.vegesna@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
---
drivers/scsi/elx/efct/efct_hw.c | 187 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 187 insertions(+)
diff --git a/drivers/scsi/elx/efct/efct_hw.c b/drivers/scsi/elx/efct/efct_hw.c
index fb33317caa0d..c18bda1351cc 100644
--- a/drivers/scsi/elx/efct/efct_hw.c
+++ b/drivers/scsi/elx/efct/efct_hw.c
@@ -276,6 +276,98 @@ efct_logfcfi(struct efct_hw *hw, u32 j, u32 i, u32 id)
j, hw->config.filter_def[j], i, id);
}
+static void
+target_wqe_timer_cb(struct timer_list *t);
+
+static int
+target_wqe_timer_nop_cb(struct efct_hw *hw, int status,
+ u8 *mqe, void *arg)
+{
+ struct efct_hw_io *io = NULL;
+ struct efct_hw_io *io_next = NULL;
+ u64 ticks_current = jiffies_64;
+ u32 sec_elapsed;
+ struct sli4_mbox_command_header *hdr =
+ (struct sli4_mbox_command_header *)mqe;
+ unsigned long flags = 0;
+
+ if (status || le16_to_cpu(hdr->status)) {
+ efc_log_debug(hw->os, "bad status st=%x hdr=%x\n",
+ status,
+ le16_to_cpu(hdr->status));
+ /* go ahead and proceed with wqe timer checks... */
+ }
+
+ /* loop through active WQE list and check for timeouts */
+ spin_lock_irqsave(&hw->io_lock, flags);
+ list_for_each_entry_safe(io, io_next, &hw->io_timed_wqe, wqe_link) {
+ sec_elapsed = ((u32)(ticks_current - io->submit_ticks) / HZ);
+
+ /*
+ * If elapsed time > timeout, abort it. No need to check type
+ * since it wouldn't be on this list unless it was a target WQE
+ */
+ if (sec_elapsed > io->tgt_wqe_timeout) {
+ efc_log_test(hw->os,
+ "IO timeout xri=0x%x tag=0x%x type=%d\n",
+ io->indicator, io->reqtag, io->type);
+
+ /*
+ * remove from active_wqe list so won't try to abort
+ * again
+ */
+ list_del(&io->list_entry);
+
+ /* save status of timed_out for when abort completes */
+ io->status_saved = true;
+ io->saved_status =
+ SLI4_FC_WCQE_STATUS_TARGET_WQE_TIMEOUT;
+ io->saved_ext = 0;
+ io->saved_len = 0;
+
+ /* now abort outstanding IO */
+ efct_hw_io_abort(hw, io, false, NULL, NULL);
+ }
+ /*
+ * need to go through entire list since each IO could have a
+ * different timeout value
+ */
+ }
+ spin_unlock_irqrestore(&hw->io_lock, flags);
+
+ /* if we're not in the middle of shutting down, schedule next timer */
+ if (!hw->active_wqe_timer_shutdown) {
+ timer_setup(&hw->wqe_timer,
+ &target_wqe_timer_cb, 0);
+
+ mod_timer(&hw->wqe_timer,
+ jiffies +
+ msecs_to_jiffies(EFCT_HW_WQ_TIMER_PERIOD_MS));
+ }
+ hw->in_active_wqe_timer = false;
+ return 0;
+}
+
+static void
+target_wqe_timer_cb(struct timer_list *t)
+{
+ struct efct_hw *hw = from_timer(hw, t, wqe_timer);
+
+ /*
+ * delete existing timer; will kick off new timer after checking wqe
+ * timeouts
+ */
+ hw->in_active_wqe_timer = true;
+ del_timer(&hw->wqe_timer);
+
+ /*
+ * Forward timer callback to execute in the mailbox completion
+ * processing context
+ */
+ if (efct_hw_async_call(hw, target_wqe_timer_nop_cb, hw))
+ efc_log_test(hw->os, "efct_hw_async_call failed\n");
+}
+
static inline void
efct_hw_init_free_io(struct efct_hw_io *io)
{
@@ -4572,6 +4664,40 @@ efct_hw_port_control(struct efct_hw *hw, enum efct_hw_port ctrl,
return rc;
}
+static void
+shutdown_target_wqe_timer(struct efct_hw *hw)
+{
+ u32 iters = 100;
+
+ if (hw->config.emulate_tgt_wqe_timeout) {
+ /*
+ * request active wqe timer shutdown, then wait for it to
+ * complete
+ */
+ hw->active_wqe_timer_shutdown = true;
+
+ /*
+ * delete WQE timer and wait for timer handler to complete
+ * (if necessary)
+ */
+ del_timer(&hw->wqe_timer);
+
+ /* now wait for timer handler to complete (if necessary) */
+ while (hw->in_active_wqe_timer && iters) {
+ /*
+ * if we happen to have just sent NOP mbox cmn, make
+ * sure completions are being processed
+ */
+ efct_hw_flush(hw);
+ iters--;
+ }
+
+ if (iters == 0)
+ efc_log_test(hw->os,
+ "Failed to shutdown active wqe timer\n");
+ }
+}
+
enum efct_hw_rtn
efct_hw_teardown(struct efct_hw *hw)
{
@@ -4920,3 +5046,64 @@ efct_hw_get_num_eq(struct efct_hw *hw)
{
return hw->eq_count;
}
+
+/* HW async call context structure */
+struct efct_hw_async_call_ctx {
+ efct_hw_async_cb_t callback;
+ void *arg;
+ u8 cmd[SLI4_BMBX_SIZE];
+};
+
+static void
+efct_hw_async_cb(struct efct_hw *hw, int status, u8 *mqe, void *arg)
+{
+ struct efct_hw_async_call_ctx *ctx = arg;
+
+ if (ctx) {
+ if (ctx->callback)
+ (*ctx->callback)(hw, status, mqe, ctx->arg);
+
+ kfree(ctx);
+ }
+}
+
+/*
+ * Post a NOP mbox cmd; the callback with argument is invoked upon completion
+ * while in the event processing context.
+ */
+int
+efct_hw_async_call(struct efct_hw *hw,
+ efct_hw_async_cb_t callback, void *arg)
+{
+ int rc = 0;
+ struct efct_hw_async_call_ctx *ctx;
+
+ /*
+ * Allocate a callback context (which includes the mbox cmd buffer),
+ * we need this to be persistent as the mbox cmd submission may be
+ * queued and executed later execution.
+ */
+ ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
+ if (!ctx)
+ return EFCT_HW_RTN_NO_MEMORY;
+
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->callback = callback;
+ ctx->arg = arg;
+
+ /* Build and send a NOP mailbox command */
+ if (!sli_cmd_common_nop(&hw->sli, ctx->cmd,
+ sizeof(ctx->cmd), 0) == 0) {
+ efc_log_err(hw->os, "COMMON_NOP format failure\n");
+ kfree(ctx);
+ rc = -1;
+ }
+
+ if (efct_hw_command(hw, ctx->cmd, EFCT_CMD_NOWAIT, efct_hw_async_cb,
+ ctx)) {
+ efc_log_err(hw->os, "COMMON_NOP command failure\n");
+ kfree(ctx);
+ rc = -1;
+ }
+ return rc;
+}
--
2.13.7
next prev parent reply other threads:[~2019-12-20 22:38 UTC|newest]
Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-12-20 22:36 [PATCH v2 00/32] [NEW] efct: Broadcom (Emulex) FC Target driver James Smart
2019-12-20 22:36 ` [PATCH v2 01/32] elx: libefc_sli: SLI-4 register offsets and field definitions James Smart
2020-01-08 7:11 ` Hannes Reinecke
2020-01-09 0:59 ` James Smart
2019-12-20 22:36 ` [PATCH v2 02/32] elx: libefc_sli: SLI Descriptors and Queue entries James Smart
2020-01-08 7:24 ` Hannes Reinecke
2020-01-09 1:00 ` James Smart
2019-12-20 22:36 ` [PATCH v2 03/32] elx: libefc_sli: Data structures and defines for mbox commands James Smart
2020-01-08 7:32 ` Hannes Reinecke
2020-01-09 1:03 ` James Smart
2019-12-20 22:36 ` [PATCH v2 04/32] elx: libefc_sli: queue create/destroy/parse routines James Smart
2020-01-08 7:45 ` Hannes Reinecke
2020-01-09 1:04 ` James Smart
2019-12-20 22:36 ` [PATCH v2 05/32] elx: libefc_sli: Populate and post different WQEs James Smart
2020-01-08 7:54 ` Hannes Reinecke
2020-01-09 1:04 ` James Smart
2019-12-20 22:36 ` [PATCH v2 06/32] elx: libefc_sli: bmbx routines and SLI config commands James Smart
2020-01-08 8:05 ` Hannes Reinecke
2019-12-20 22:36 ` [PATCH v2 07/32] elx: libefc_sli: APIs to setup SLI library James Smart
2020-01-08 8:22 ` Hannes Reinecke
2020-01-09 1:29 ` James Smart
2019-12-20 22:36 ` [PATCH v2 08/32] elx: libefc: Generic state machine framework James Smart
2020-01-09 7:05 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 09/32] elx: libefc: Emulex FC discovery library APIs and definitions James Smart
2020-01-09 7:16 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 10/32] elx: libefc: FC Domain state machine interfaces James Smart
2020-01-09 7:27 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 11/32] elx: libefc: SLI and FC PORT " James Smart
2020-01-09 7:34 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 12/32] elx: libefc: Remote node " James Smart
2020-01-09 8:31 ` Hannes Reinecke
2020-01-09 9:57 ` Daniel Wagner
2019-12-20 22:37 ` [PATCH v2 13/32] elx: libefc: Fabric " James Smart
2020-01-09 8:34 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 14/32] elx: libefc: FC node ELS and state handling James Smart
2020-01-09 8:39 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 15/32] elx: efct: Data structures and defines for hw operations James Smart
2020-01-09 8:41 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 16/32] elx: efct: Driver initialization routines James Smart
2020-01-09 9:01 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 17/32] elx: efct: Hardware queues creation and deletion James Smart
2020-01-09 9:10 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 18/32] elx: efct: RQ buffer, memory pool allocation and deallocation APIs James Smart
2020-01-09 9:13 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 19/32] elx: efct: Hardware IO and SGL initialization James Smart
2020-01-09 9:22 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 20/32] elx: efct: Hardware queues processing James Smart
2020-01-09 9:24 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 21/32] elx: efct: Unsolicited FC frame processing routines James Smart
2020-01-09 9:26 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 22/32] elx: efct: Extended link Service IO handling James Smart
2020-01-09 9:38 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 23/32] elx: efct: SCSI IO handling routines James Smart
2020-01-09 9:41 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 24/32] elx: efct: LIO backend interface routines James Smart
2020-01-09 3:56 ` Bart Van Assche
2019-12-20 22:37 ` [PATCH v2 25/32] elx: efct: Hardware IO submission routines James Smart
2020-01-09 9:52 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 26/32] elx: efct: link statistics and SFP data James Smart
2020-01-09 10:12 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 27/32] elx: efct: xport and hardware teardown routines James Smart
2020-01-09 10:14 ` Hannes Reinecke
2019-12-20 22:37 ` James Smart [this message]
2020-01-09 11:27 ` [PATCH v2 28/32] elx: efct: IO timeout handling routines Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 29/32] elx: efct: Firmware update, async link processing James Smart
2020-01-09 11:45 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 30/32] elx: efct: scsi_transport_fc host interface support James Smart
2020-01-09 11:46 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 31/32] elx: efct: Add Makefile and Kconfig for efct driver James Smart
2019-12-20 23:17 ` Randy Dunlap
2020-01-09 11:47 ` Hannes Reinecke
2019-12-20 22:37 ` [PATCH v2 32/32] elx: efct: Tie into kernel Kconfig and build process James Smart
2019-12-24 7:45 ` kbuild test robot
2019-12-24 21:01 ` Nathan Chancellor
2019-12-25 16:09 ` James Smart
2020-01-09 11:47 ` Hannes Reinecke
2019-12-29 18:27 ` [PATCH v2 00/32] [NEW] efct: Broadcom (Emulex) FC Target driver Sebastian Herbszt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191220223723.26563-29-jsmart2021@gmail.com \
--to=jsmart2021@gmail.com \
--cc=bvanassche@acm.org \
--cc=dwagner@suse.de \
--cc=linux-scsi@vger.kernel.org \
--cc=maier@linux.ibm.com \
--cc=ram.vegesna@broadcom.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).