Hi, Thanks for identifying this bug. To fix this, we will set the error variable to "-ENOMEM" value as shown below before jumping to the out_mptfc_probe code section. And we will post these changes patch to the Upstream ASAP. ioc->fc_rescan_work_q = create_singlethread_workqueue(ioc->fc_rescan_work_q_name); if (!ioc->fc_rescan_work_q) { error = -ENOMEM; goto out_mptfc_probe; } Thanks, Sreekanth On Mon, May 18, 2015 at 2:39 PM, 张燕 <zy900702@xxxxxxx> wrote: > Summary: > there exists a wrong return value of function mptfc_probe(). > Bug Description: > > In function mptfc_probe() at drivers/message/fusion/mptfc.c:1177, the call > to create_singlethread_workqueue() in line 1327 may return a negative error > code, and thus function mptfc_probe() will return the value of variable > error. And, the function mptfc_probe() will return 0 at last when it runs > well. However, when the call to create_singlethread_workqueuee() in line > 1327 return a negative error code, the value of error is 0. So the function > mptfc_probe() will return 0 to its caller functions when it runs error > because of the failing call to create_singlethread_workqueue(), leading to a > wrong return value of function mptfc_probe(). > The related code snippets in mptfc_probe() is as following. > mptfc_probe @@ drivers/message/fusion/mptfc.c:1177 > 1177mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) > 1178{ > ... > 1315 error = scsi_add_host (sh, &ioc->pcidev->dev); > 1316 if(error) { > 1317 dprintk(ioc, printk(MYIOC_s_ERR_FMT > 1318 "scsi_add_host failed\n", ioc->name)); > 1319 goto out_mptfc_probe; > 1320 } > 1321 > 1322 /* initialize workqueue */ > 1323 > 1324 snprintf(ioc->fc_rescan_work_q_name, > sizeof(ioc->fc_rescan_work_q_name), > 1325 "mptfc_wq_%d", sh->host_no); > 1326 ioc->fc_rescan_work_q = > 1327 > create_singlethread_workqueue(ioc->fc_rescan_work_q_name); > 1328 if (!ioc->fc_rescan_work_q) > 1329 goto out_mptfc_probe; > ... > 1350out_mptfc_probe: > 1351 > 1352 mptscsih_remove(pdev); > 1353 return error; > 1354} > > Generally, when the call to create_singlethread_workqueue() fails, the > return value of caller functions should be different from another return > value set when the call to create_singlethread_workqueue() succeeds, like > the following codes in another file. > rds_threads_init @@ net/rds/threads.c:215 > 215int rds_threads_init(void) > 216{ > 217 rds_wq = create_singlethread_workqueue("krdsd"); > 218 if (!rds_wq) > 219 return -ENOMEM; > 220 > 221 return 0; > 222} > > Kernel version: > 3.19.1 > > > -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html