diff options
| author | Hannes Reinecke <hare@suse.de> | 2020-03-11 00:25:35 +0800 |
|---|---|---|
| committer | Hannes Reinecke <hare@suse.de> | 2021-11-06 16:53:31 +0100 |
| commit | 4c6835d49046d493aa4186e6d357842ef885bd97 (patch) | |
| tree | 78d180c9c98a044e269e68a0452f20c02c6ee191 | |
| parent | ab62e1bf357cb49bc1202b317666790b4eb1fc12 (diff) | |
| download | scsi-devel-4c6835d49046d493aa4186e6d357842ef885bd97.tar.gz | |
fnic: use internal commands
Remove hack to get tag for the reset command by using internal
commands. We're setting one tag aside for internal commands as
it's only used for device reset where the SCSI Host is running
in single-threaded mode anyway.
Signed-off-by: Hannes Reinecke <hare@suse.de>
| -rw-r--r-- | drivers/scsi/fnic/fnic_main.c | 3 | ||||
| -rw-r--r-- | drivers/scsi/fnic/fnic_scsi.c | 123 |
2 files changed, 41 insertions, 85 deletions
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 44dbaa662d940..41865045b748d 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -119,7 +119,8 @@ static struct scsi_host_template fnic_host_template = { .change_queue_depth = scsi_change_queue_depth, .this_id = -1, .cmd_per_lun = 3, - .can_queue = FNIC_DFLT_IO_REQ, + .can_queue = FNIC_DFLT_IO_REQ - 1, + .nr_reserved_cmds = 1, .sg_tablesize = FNIC_MAX_SG_DESC_CNT, .max_sectors = 0xffff, .shost_groups = fnic_host_groups, diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 88c549f257dbf..cca6707bd63f6 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -2189,39 +2189,6 @@ clean_pending_aborts_end: } /* - * fnic_scsi_host_start_tag - * Allocates tagid from host's tag list - **/ -static inline int -fnic_scsi_host_start_tag(struct fnic *fnic, struct scsi_cmnd *sc) -{ - struct request *rq = scsi_cmd_to_rq(sc); - struct request_queue *q = rq->q; - struct request *dummy; - - dummy = blk_mq_alloc_request(q, REQ_OP_WRITE, BLK_MQ_REQ_NOWAIT); - if (IS_ERR(dummy)) - return SCSI_NO_TAG; - - rq->tag = dummy->tag; - sc->host_scribble = (unsigned char *)dummy; - - return dummy->tag; -} - -/* - * fnic_scsi_host_end_tag - * frees tag allocated by fnic_scsi_host_start_tag. - **/ -static inline void -fnic_scsi_host_end_tag(struct fnic *fnic, struct scsi_cmnd *sc) -{ - struct request *dummy = (struct request *)sc->host_scribble; - - blk_mq_free_request(dummy); -} - -/* * SCSI Eh thread issues a Lun Reset when one or more commands on a LUN * fail to get aborted. It calls driver's eh_device_reset with a SCSI command * on the LUN. @@ -2243,8 +2210,7 @@ int fnic_device_reset(struct scsi_cmnd *sc) struct reset_stats *reset_stats; int tag = rq->tag; DECLARE_COMPLETION_ONSTACK(tm_done); - int tag_gen_flag = 0; /*to track tags allocated by fnic driver*/ - bool new_sc = 0; + struct scsi_cmnd *reset_sc = NULL; /* Wait for rport to unblock */ fc_block_scsi_eh(sc); @@ -2272,41 +2238,30 @@ int fnic_device_reset(struct scsi_cmnd *sc) goto fnic_device_reset_end; } - CMD_FLAGS(sc) = FNIC_DEVICE_RESET; - /* Allocate tag if not present */ + reset_sc = scsi_get_internal_cmd(sc->device, DMA_NONE, REQ_NOWAIT); + if (unlikely(!reset_sc)) + goto fnic_device_reset_end; - if (unlikely(tag < 0)) { - /* - * Really should fix the midlayer to pass in a proper - * request for ioctls... - */ - tag = fnic_scsi_host_start_tag(fnic, sc); - if (unlikely(tag == SCSI_NO_TAG)) - goto fnic_device_reset_end; - tag_gen_flag = 1; - new_sc = 1; - } - io_lock = fnic_io_lock_hash(fnic, sc); + CMD_FLAGS(reset_sc) = FNIC_DEVICE_RESET; + tag = reset_sc->request->tag; + io_lock = fnic_io_lock_hash(fnic, reset_sc); spin_lock_irqsave(io_lock, flags); - io_req = (struct fnic_io_req *)CMD_SP(sc); /* - * If there is a io_req attached to this command, then use it, - * else allocate a new one. + * Allocate a new io_req. */ + io_req = mempool_alloc(fnic->io_req_pool, GFP_ATOMIC); if (!io_req) { - io_req = mempool_alloc(fnic->io_req_pool, GFP_ATOMIC); - if (!io_req) { - spin_unlock_irqrestore(io_lock, flags); - goto fnic_device_reset_end; - } - memset(io_req, 0, sizeof(*io_req)); - io_req->port_id = rport->port_id; - CMD_SP(sc) = (char *)io_req; + spin_unlock_irqrestore(io_lock, flags); + goto fnic_device_reset_end; } + memset(io_req, 0, sizeof(*io_req)); + io_req->port_id = rport->port_id; + CMD_SP(reset_sc) = (char *)io_req; + io_req->dr_done = &tm_done; - CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING; - CMD_LR_STATUS(sc) = FCPIO_INVALID_CODE; + CMD_STATE(reset_sc) = FNIC_IOREQ_CMD_PENDING; + CMD_LR_STATUS(reset_sc) = FCPIO_INVALID_CODE; spin_unlock_irqrestore(io_lock, flags); FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "TAG %x\n", tag); @@ -2315,15 +2270,15 @@ int fnic_device_reset(struct scsi_cmnd *sc) * issue the device reset, if enqueue failed, clean up the ioreq * and break assoc with scsi cmd */ - if (fnic_queue_dr_io_req(fnic, sc, io_req)) { + if (fnic_queue_dr_io_req(fnic, reset_sc, io_req)) { spin_lock_irqsave(io_lock, flags); - io_req = (struct fnic_io_req *)CMD_SP(sc); + io_req = (struct fnic_io_req *)CMD_SP(reset_sc); if (io_req) io_req->dr_done = NULL; goto fnic_device_reset_clean; } spin_lock_irqsave(io_lock, flags); - CMD_FLAGS(sc) |= FNIC_DEV_RST_ISSUED; + CMD_FLAGS(reset_sc) |= FNIC_DEV_RST_ISSUED; spin_unlock_irqrestore(io_lock, flags); /* @@ -2334,16 +2289,16 @@ int fnic_device_reset(struct scsi_cmnd *sc) msecs_to_jiffies(FNIC_LUN_RESET_TIMEOUT)); spin_lock_irqsave(io_lock, flags); - io_req = (struct fnic_io_req *)CMD_SP(sc); + io_req = (struct fnic_io_req *)CMD_SP(reset_sc); if (!io_req) { spin_unlock_irqrestore(io_lock, flags); FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, - "io_req is null tag 0x%x sc 0x%p\n", tag, sc); + "io_req is null tag 0x%x sc 0x%p\n", tag, reset_sc); goto fnic_device_reset_end; } io_req->dr_done = NULL; - status = CMD_LR_STATUS(sc); + status = CMD_LR_STATUS(reset_sc); /* * If lun reset not completed, bail out with failed. io_req @@ -2353,16 +2308,16 @@ int fnic_device_reset(struct scsi_cmnd *sc) atomic64_inc(&reset_stats->device_reset_timeouts); FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "Device reset timed out\n"); - CMD_FLAGS(sc) |= FNIC_DEV_RST_TIMED_OUT; + CMD_FLAGS(reset_sc) |= FNIC_DEV_RST_TIMED_OUT; spin_unlock_irqrestore(io_lock, flags); - int_to_scsilun(sc->device->lun, &fc_lun); + int_to_scsilun(recet_sc->device->lun, &fc_lun); /* * Issue abort and terminate on device reset request. * If q'ing of terminate fails, retry it after a delay. */ while (1) { spin_lock_irqsave(io_lock, flags); - if (CMD_FLAGS(sc) & FNIC_DEV_RST_TERM_ISSUED) { + if (CMD_FLAGS(reset_sc) & FNIC_DEV_RST_TERM_ISSUED) { spin_unlock_irqrestore(io_lock, flags); break; } @@ -2375,25 +2330,25 @@ int fnic_device_reset(struct scsi_cmnd *sc) msecs_to_jiffies(FNIC_ABT_TERM_DELAY_TIMEOUT)); } else { spin_lock_irqsave(io_lock, flags); - CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; - CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING; + CMD_FLAGS(reset_sc) |= FNIC_DEV_RST_TERM_ISSUED; + CMD_STATE(reset_sc) = FNIC_IOREQ_ABTS_PENDING; io_req->abts_done = &tm_done; spin_unlock_irqrestore(io_lock, flags); FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "Abort and terminate issued on Device reset " - "tag 0x%x sc 0x%p\n", tag, sc); + "tag 0x%x sc 0x%p\n", tag, reset_sc); break; } } while (1) { spin_lock_irqsave(io_lock, flags); - if (!(CMD_FLAGS(sc) & FNIC_DEV_RST_DONE)) { + if (!(CMD_FLAGS(reset_sc) & FNIC_DEV_RST_DONE)) { spin_unlock_irqrestore(io_lock, flags); wait_for_completion_timeout(&tm_done, msecs_to_jiffies(FNIC_LUN_RESET_TIMEOUT)); break; } else { - io_req = (struct fnic_io_req *)CMD_SP(sc); + io_req = (struct fnic_io_req *)CMD_SP(reset_sc); io_req->abts_done = NULL; goto fnic_device_reset_clean; } @@ -2408,7 +2363,7 @@ int fnic_device_reset(struct scsi_cmnd *sc) FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "Device reset completed - failed\n"); - io_req = (struct fnic_io_req *)CMD_SP(sc); + io_req = (struct fnic_io_req *)CMD_SP(reset_sc); goto fnic_device_reset_clean; } @@ -2419,7 +2374,7 @@ int fnic_device_reset(struct scsi_cmnd *sc) * the lun reset cmd. If all cmds get cleaned, the lun reset * succeeds */ - if (fnic_clean_pending_aborts(fnic, sc, new_sc)) { + if (fnic_clean_pending_aborts(fnic, reset_sc)) { spin_lock_irqsave(io_lock, flags); io_req = (struct fnic_io_req *)CMD_SP(sc); FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, @@ -2430,20 +2385,20 @@ int fnic_device_reset(struct scsi_cmnd *sc) /* Clean lun reset command */ spin_lock_irqsave(io_lock, flags); - io_req = (struct fnic_io_req *)CMD_SP(sc); + io_req = (struct fnic_io_req *)CMD_SP(reset_sc); if (io_req) /* Completed, and successful */ ret = SUCCESS; fnic_device_reset_clean: if (io_req) - CMD_SP(sc) = NULL; + CMD_SP(reset_sc) = NULL; spin_unlock_irqrestore(io_lock, flags); if (io_req) { start_time = io_req->start_time; - fnic_release_ioreq_buf(fnic, io_req, sc); + fnic_release_ioreq_buf(fnic, io_req, reset_sc); mempool_free(io_req, fnic->io_req_pool); } @@ -2455,9 +2410,9 @@ fnic_device_reset_end: (u64)sc->cmnd[4] << 8 | sc->cmnd[5]), (((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc))); - /* free tag if it is allocated */ - if (unlikely(tag_gen_flag)) - fnic_scsi_host_end_tag(fnic, sc); + /* free internal command if it is allocated */ + if (reset_sc) + scsi_put_internal_cmd(reset_sc); FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "Returning from device reset %s\n", |
