Message ID | 20201218231916.279833-5-tyreld@linux.ibm.com |
---|---|
State | Superseded |
Headers | show |
Series | ibmvfc: MQ preparatory locking work | expand |
Hi Tyrel, I love your patch! Perhaps something to improve: [auto build test WARNING on next-20201218] [also build test WARNING on v5.11-rc1] [cannot apply to powerpc/next v5.10 v5.10-rc7 v5.10-rc6] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Tyrel-Datwyler/ibmvfc-MQ-preparatory-locking-work/20201219-072334 base: 0d52778b8710eb11cb616761a02aee0a7fd60425 config: powerpc-allyesconfig (attached as .config) compiler: powerpc64-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/2609a2691baaf1f06d8306a56575ae2eb076f625 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Tyrel-Datwyler/ibmvfc-MQ-preparatory-locking-work/20201219-072334 git checkout 2609a2691baaf1f06d8306a56575ae2eb076f625 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=powerpc If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): >> drivers/scsi/ibmvscsi/ibmvfc.c:1418:6: warning: no previous prototype for 'ibmvfc_locked_done' [-Wmissing-prototypes] 1418 | void ibmvfc_locked_done(struct ibmvfc_event *evt) | ^~~~~~~~~~~~~~~~~~ In file included from arch/powerpc/include/asm/paca.h:15, from arch/powerpc/include/asm/current.h:13, from include/linux/thread_info.h:21, from include/asm-generic/preempt.h:5, from ./arch/powerpc/include/generated/asm/preempt.h:1, from include/linux/preempt.h:78, from include/linux/spinlock.h:51, from include/linux/mmzone.h:8, from include/linux/gfp.h:6, from include/linux/umh.h:4, from include/linux/kmod.h:9, from include/linux/module.h:16, from drivers/scsi/ibmvscsi/ibmvfc.c:10: In function 'strncpy', inlined from 'ibmvfc_gather_partition_info' at drivers/scsi/ibmvscsi/ibmvfc.c:1267:3, inlined from 'ibmvfc_npiv_login' at drivers/scsi/ibmvscsi/ibmvfc.c:4538:2: include/linux/string.h:291:30: warning: '__builtin_strncpy' specified bound 97 equals destination size [-Wstringop-truncation] 291 | #define __underlying_strncpy __builtin_strncpy | ^ include/linux/string.h:301:9: note: in expansion of macro '__underlying_strncpy' 301 | return __underlying_strncpy(p, q, size); | ^~~~~~~~~~~~~~~~~~~~ In function 'strncpy', inlined from 'ibmvfc_set_login_info' at drivers/scsi/ibmvscsi/ibmvfc.c:1307:2, inlined from 'ibmvfc_npiv_login' at drivers/scsi/ibmvscsi/ibmvfc.c:4539:2: include/linux/string.h:291:30: warning: '__builtin_strncpy' specified bound 256 equals destination size [-Wstringop-truncation] 291 | #define __underlying_strncpy __builtin_strncpy | ^ include/linux/string.h:301:9: note: in expansion of macro '__underlying_strncpy' 301 | return __underlying_strncpy(p, q, size); | ^~~~~~~~~~~~~~~~~~~~ In function 'strncpy', inlined from 'ibmvfc_set_login_info' at drivers/scsi/ibmvscsi/ibmvfc.c:1312:2, inlined from 'ibmvfc_npiv_login' at drivers/scsi/ibmvscsi/ibmvfc.c:4539:2: include/linux/string.h:291:30: warning: '__builtin_strncpy' specified bound 256 equals destination size [-Wstringop-truncation] 291 | #define __underlying_strncpy __builtin_strncpy | ^ include/linux/string.h:301:9: note: in expansion of macro '__underlying_strncpy' 301 | return __underlying_strncpy(p, q, size); | ^~~~~~~~~~~~~~~~~~~~ vim +/ibmvfc_locked_done +1418 drivers/scsi/ibmvscsi/ibmvfc.c 1409 1410 /** 1411 * ibmvfc_locked_done - Calls evt completion with host_lock held 1412 * @evt: ibmvfc evt to complete 1413 * 1414 * All non-scsi command completion callbacks have the expectation that the 1415 * host_lock is held. This callback is used by ibmvfc_init_event to wrap a 1416 * MAD evt with the host_lock. 1417 **/ > 1418 void ibmvfc_locked_done(struct ibmvfc_event *evt) 1419 { 1420 unsigned long flags; 1421 1422 spin_lock_irqsave(evt->vhost->host->host_lock, flags); 1423 evt->_done(evt); 1424 spin_unlock_irqrestore(evt->vhost->host->host_lock, flags); 1425 } 1426 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
On 1/4/21 2:17 PM, Tyrel Datwyler wrote: > The drivers queuecommand routine is still wrapped to hold the host lock > for the duration of the call. This will become problematic when moving > to multiple queues due to the lock contention preventing asynchronous > submissions to mulitple queues. There is no real legatimate reason to > hold the host lock, and previous patches have insured proper protection > of moving ibmvfc_event objects between free and sent lists. > > Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com> > Reviewed-by: Brian King <brking@linux.vnet.ibm.com> > --- Ignore. This is the wrong updated patch. -Tyrel
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 69a6401ca504..b74080489807 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -894,7 +894,7 @@ static void ibmvfc_scsi_eh_done(struct ibmvfc_event *evt) * @purge_list: list head of failed commands * * This function runs completions on commands to fail as a result of a - * host reset or platform migration. Caller must hold host_lock. + * host reset or platform migration. **/ static void ibmvfc_complete_purge(struct list_head *purge_list) { @@ -1407,6 +1407,23 @@ static struct ibmvfc_event *ibmvfc_get_event(struct ibmvfc_queue *queue) return evt; } +/** + * ibmvfc_locked_done - Calls evt completion with host_lock held + * @evt: ibmvfc evt to complete + * + * All non-scsi command completion callbacks have the expectation that the + * host_lock is held. This callback is used by ibmvfc_init_event to wrap a + * MAD evt with the host_lock. + **/ +void ibmvfc_locked_done(struct ibmvfc_event *evt) +{ + unsigned long flags; + + spin_lock_irqsave(evt->vhost->host->host_lock, flags); + evt->_done(evt); + spin_unlock_irqrestore(evt->vhost->host->host_lock, flags); +} + /** * ibmvfc_init_event - Initialize fields in an event struct that are always * required. @@ -1419,9 +1436,14 @@ static void ibmvfc_init_event(struct ibmvfc_event *evt, { evt->cmnd = NULL; evt->sync_iu = NULL; - evt->crq.format = format; - evt->done = done; evt->eh_comp = NULL; + evt->crq.format = format; + if (format == IBMVFC_CMD_FORMAT) + evt->done = done; + else { + evt->_done = done; + evt->done = ibmvfc_locked_done; + } } /** @@ -1640,7 +1662,9 @@ static void ibmvfc_relogin(struct scsi_device *sdev) struct ibmvfc_host *vhost = shost_priv(sdev->host); struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); struct ibmvfc_target *tgt; + unsigned long flags; + spin_lock_irqsave(vhost->host->host_lock, flags); list_for_each_entry(tgt, &vhost->targets, queue) { if (rport == tgt->rport) { ibmvfc_del_tgt(tgt); @@ -1649,6 +1673,7 @@ static void ibmvfc_relogin(struct scsi_device *sdev) } ibmvfc_reinit_host(vhost); + spin_unlock_irqrestore(vhost->host->host_lock, flags); } /** @@ -2901,7 +2926,8 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, * @vhost: ibmvfc host struct * **/ -static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost) +static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost, + struct list_head *evt_doneq) { long rc; struct ibmvfc_event *evt = (struct ibmvfc_event *)be64_to_cpu(crq->ioba); @@ -2972,12 +2998,9 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost) return; } - del_timer(&evt->timer); spin_lock(&evt->queue->l_lock); - list_del(&evt->queue_list); + list_move_tail(&evt->queue_list, evt_doneq); spin_unlock(&evt->queue->l_lock); - ibmvfc_trc_end(evt); - evt->done(evt); } /** @@ -3364,8 +3387,10 @@ static void ibmvfc_tasklet(void *data) struct vio_dev *vdev = to_vio_dev(vhost->dev); struct ibmvfc_crq *crq; struct ibmvfc_async_crq *async; + struct ibmvfc_event *evt, *temp; unsigned long flags; int done = 0; + LIST_HEAD(evt_doneq); spin_lock_irqsave(vhost->host->host_lock, flags); spin_lock(vhost->crq.q_lock); @@ -3379,7 +3404,7 @@ static void ibmvfc_tasklet(void *data) /* Pull all the valid messages off the CRQ */ while ((crq = ibmvfc_next_crq(vhost)) != NULL) { - ibmvfc_handle_crq(crq, vhost); + ibmvfc_handle_crq(crq, vhost, &evt_doneq); crq->valid = 0; wmb(); } @@ -3392,7 +3417,7 @@ static void ibmvfc_tasklet(void *data) wmb(); } else if ((crq = ibmvfc_next_crq(vhost)) != NULL) { vio_disable_interrupts(vdev); - ibmvfc_handle_crq(crq, vhost); + ibmvfc_handle_crq(crq, vhost, &evt_doneq); crq->valid = 0; wmb(); } else @@ -3401,6 +3426,13 @@ static void ibmvfc_tasklet(void *data) spin_unlock(vhost->crq.q_lock); spin_unlock_irqrestore(vhost->host->host_lock, flags); + + list_for_each_entry_safe(evt, temp, &evt_doneq, queue_list) { + del_timer(&evt->timer); + list_del(&evt->queue_list); + ibmvfc_trc_end(evt); + evt->done(evt); + } } /** @@ -4790,8 +4822,8 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) case IBMVFC_HOST_ACTION_RESET: vhost->action = IBMVFC_HOST_ACTION_TGT_DEL; list_splice_init(&vhost->purge, &purge); - ibmvfc_complete_purge(&purge); spin_unlock_irqrestore(vhost->host->host_lock, flags); + ibmvfc_complete_purge(&purge); rc = ibmvfc_reset_crq(vhost); spin_lock_irqsave(vhost->host->host_lock, flags); if (rc == H_CLOSED) @@ -4805,8 +4837,8 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) case IBMVFC_HOST_ACTION_REENABLE: vhost->action = IBMVFC_HOST_ACTION_TGT_DEL; list_splice_init(&vhost->purge, &purge); - ibmvfc_complete_purge(&purge); spin_unlock_irqrestore(vhost->host->host_lock, flags); + ibmvfc_complete_purge(&purge); rc = ibmvfc_reenable_crq_queue(vhost); spin_lock_irqsave(vhost->host->host_lock, flags); if (rc || (rc = ibmvfc_send_crq_init(vhost))) { @@ -5369,8 +5401,8 @@ static int ibmvfc_remove(struct vio_dev *vdev) spin_lock_irqsave(vhost->host->host_lock, flags); ibmvfc_purge_requests(vhost, DID_ERROR); list_splice_init(&vhost->purge, &purge); - ibmvfc_complete_purge(&purge); spin_unlock_irqrestore(vhost->host->host_lock, flags); + ibmvfc_complete_purge(&purge); ibmvfc_free_event_pool(vhost, &vhost->crq); ibmvfc_free_mem(vhost); diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h index faf5b50d65b9..632e977449c5 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/drivers/scsi/ibmvscsi/ibmvfc.h @@ -733,7 +733,8 @@ struct ibmvfc_event { struct scsi_cmnd *cmnd; atomic_t free; union ibmvfc_iu *xfer_iu; - void (*done) (struct ibmvfc_event *); + void (*done)(struct ibmvfc_event *evt); + void (*_done)(struct ibmvfc_event *evt); struct ibmvfc_crq crq; union ibmvfc_iu iu; union ibmvfc_iu *sync_iu;