Re: [usb-storage] [PATCH] usb: storage: Fix a possible data race in uas_queuecommand_lck
On 2018/5/8 16:27, Oliver Neukum wrote: Am Dienstag, den 08.05.2018, 15:47 +0800 schrieb Jia-Ju Bai: The write operations to "cmnd->result" and "cmnd->scsi_done" are protected by the lock on line 642-643, but the write operations to these data on line 634-635 are not protected by the lock. Thus, there may exist a data race for "cmnd->result" and "cmnd->scsi_done". No, the write operations need no lock. The low level driver at this point owns the command. We cannot race with abort() for a command within queuecommand(). We take the lock where we take it to protect dev->resetting. I don't see why the scope of the lock would need to be enlarged. Okay, thanks for your reply and explanation. Best wishes, Jia-Ju Bai
[PATCH] usb: storage: Fix a possible data race in uas_queuecommand_lck
The write operations to "cmnd->result" and "cmnd->scsi_done" are protected by the lock on line 642-643, but the write operations to these data on line 634-635 are not protected by the lock. Thus, there may exist a data race for "cmnd->result" and "cmnd->scsi_done". To fix this data race, the write operations on line 634-635 should be also protected by the lock. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/usb/storage/uas.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 6034c39b67d1..dde7a43ad491 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -627,17 +627,18 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, if (cmnd->device->host->host_self_blocked) return SCSI_MLQUEUE_DEVICE_BUSY; + spin_lock_irqsave(>lock, flags); + if ((devinfo->flags & US_FL_NO_ATA_1X) && (cmnd->cmnd[0] == ATA_12 || cmnd->cmnd[0] == ATA_16)) { memcpy(cmnd->sense_buffer, usb_stor_sense_invalidCDB, sizeof(usb_stor_sense_invalidCDB)); cmnd->result = SAM_STAT_CHECK_CONDITION; cmnd->scsi_done(cmnd); + spin_unlock_irqrestore(>lock, flags); return 0; } - spin_lock_irqsave(>lock, flags); - if (devinfo->resetting) { cmnd->result = DID_ERROR << 16; cmnd->scsi_done(cmnd); -- 2.17.0
[PATCH 2/2] scsi: st: Replace GFP_ATOMIC with GFP_KERNEL in new_tape_buffer
new_tape_buffer() is never called in atomic context. new_tape_buffer() is only called by st_probe(), which is only set as ".probe" in struct scsi_driver. Despite never getting called from atomic context, new_tape_buffer() calls kzalloc() with GFP_ATOMIC, which does not sleep for allocation. GFP_ATOMIC is not necessary and can be replaced with GFP_KERNEL, which can sleep and improve the possibility of sucessful allocation. This is found by a static analysis tool named DCNS written by myself. And I also manually check it. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/scsi/st.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 94e402e..b987f6d 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3878,7 +3878,7 @@ static struct st_buffer *new_tape_buffer(int need_dma, int max_sg) { struct st_buffer *tb; - tb = kzalloc(sizeof(struct st_buffer), GFP_ATOMIC); + tb = kzalloc(sizeof(struct st_buffer), GFP_KERNEL); if (!tb) { printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n"); return NULL; @@ -3889,7 +3889,7 @@ static struct st_buffer *new_tape_buffer(int need_dma, int max_sg) tb->buffer_size = 0; tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *), -GFP_ATOMIC); +GFP_KERNEL); if (!tb->reserved_pages) { kfree(tb); return NULL; -- 1.9.1
[PATCH 1/2] scsi: st: Replace GFP_ATOMIC with GFP_KERNEL in st_probe
st_probe() is never called in atomic context. st_probe() is only set as ".probe" in struct scsi_driver. Despite never getting called from atomic context, st_probe() calls kzalloc() with GFP_ATOMIC, which does not sleep for allocation. GFP_ATOMIC is not necessary and can be replaced with GFP_KERNEL, which can sleep and improve the possibility of sucessful allocation. This is found by a static analysis tool named DCNS written by myself. And I also manually check it. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/scsi/st.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 94e402e..1da42f3 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -4290,7 +4290,7 @@ static int st_probe(struct device *dev) goto out_buffer_free; } - tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC); + tpnt = kzalloc(sizeof(struct scsi_tape), GFP_KERNEL); if (tpnt == NULL) { sdev_printk(KERN_ERR, SDp, "st: Can't allocate device descriptor.\n"); -- 1.9.1
[PATCH] scsi: imm: Replace mdelay with msleep in imm_init
imm_init is not called in an interrupt handler nor holding a spinlock. The function mdelay in it can be replaced with msleep, to reduce busy wait. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/scsi/imm.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 87c9419..4805c0e 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -591,9 +591,9 @@ static int imm_init(imm_struct *dev) if (imm_connect(dev, 0) != 1) return -EIO; imm_reset_pulse(dev->base); - mdelay(1); /* Delay to allow devices to settle */ + msleep(1); /* Delay to allow devices to settle */ imm_disconnect(dev); - mdelay(1); /* Another delay to allow devices to settle */ + msleep(1); /* Another delay to allow devices to settle */ return device_check(dev); } -- 1.7.9.5
[PATCH] scsi: imm: Replace mdelay with msleep in imm_init
imm_init is not called in an interrupt handler nor holding a spinlock. The function mdelay in it can be replaced with msleep, to reduce busy wait. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/scsi/imm.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 87c9419..4805c0e 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -591,9 +591,9 @@ static int imm_init(imm_struct *dev) if (imm_connect(dev, 0) != 1) return -EIO; imm_reset_pulse(dev->base); - mdelay(1); /* Delay to allow devices to settle */ + msleep(1); /* Delay to allow devices to settle */ imm_disconnect(dev); - mdelay(1); /* Another delay to allow devices to settle */ + msleep(1); /* Another delay to allow devices to settle */ return device_check(dev); } -- 1.7.9.5
[PATCH] qedi: Fix a possible sleep-in-atomic bug in qedi_process_tmf_resp
The driver may sleep under a spinlock. The function call path is: qedi_cpu_offline (acquire the spinlock) qedi_fp_process_cqes qedi_mtask_completion qedi_process_tmf_resp kzalloc(GFP_KERNEL) --> may sleep To fix it, GFP_KERNEL is replaced with GFP_ATOMIC. This bug is found by my static analysis tool(DSAC) and checked by my code review. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/scsi/qedi/qedi_fw.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c index bd302d3..20a9259 100644 --- a/drivers/scsi/qedi/qedi_fw.c +++ b/drivers/scsi/qedi/qedi_fw.c @@ -198,7 +198,7 @@ static void qedi_process_tmf_resp(struct qedi_ctx *qedi, cqe_tmp_response = >cqe_common.iscsi_hdr.tmf_response; qedi_cmd = task->dd_data; - qedi_cmd->tmf_resp_buf = kzalloc(sizeof(*resp_hdr_ptr), GFP_KERNEL); + qedi_cmd->tmf_resp_buf = kzalloc(sizeof(*resp_hdr_ptr), GFP_ATOMIC); if (!qedi_cmd->tmf_resp_buf) { QEDI_ERR(>dbg_ctx, "Failed to allocate resp buf, cid=0x%x\n", -- 1.7.9.5
Re: [BUG] scsi/qla2xxx: a possible sleep-in-atomic bug in qlt_get_tag
On 2017/12/13 12:42, James Bottomley wrote: On Wed, 2017-12-13 at 11:18 +0800, Jia-Ju Bai wrote: The driver may sleep under a spinlock. The function call paths are: qlt_handle_abts_recv_work (acquire the spinlock) qlt_response_pkt_all_vps qlt_response_pkt qlt_handle_cmd_for_atio qlt_get_tag percpu_ida_alloc --> may sleep qla82xx_msix_rsp_q (acquire the spinlock) qla24xx_process_response_queue qlt_handle_abts_recv qlt_response_pkt_all_vps qlt_response_pkt qlt_handle_cmd_for_atio qlt_get_tag percpu_ida_alloc --> may sleep-in-atomic qla24xx_intr_handler (acquire the spinlock) qla24xx_process_response_queue qlt_handle_abts_recv qlt_response_pkt qlt_handle_cmd_for_atio qlt_get_tag percpu_ida_alloc --> may sleep I do not find a good way to fix it, so I only report. This possible bug is found by my static analysis tool (DSAC) and checked by my code review. The report is incorrect: percpu_ida_alloc with state==TASK_RUNNING is atomic (and interrupt) safe which appears to be the case here. James Thanks for your reply :) I have checked the definition of percpu_ida_alloc, and I think you are right. Sorry for my incorrect bug report. Thanks, Jia-Ju Bai
[BUG] scsi/qla2xxx: a possible sleep-in-atomic bug in qlt_get_tag
The driver may sleep under a spinlock. The function call paths are: qlt_handle_abts_recv_work (acquire the spinlock) qlt_response_pkt_all_vps qlt_response_pkt qlt_handle_cmd_for_atio qlt_get_tag percpu_ida_alloc --> may sleep qla82xx_msix_rsp_q (acquire the spinlock) qla24xx_process_response_queue qlt_handle_abts_recv qlt_response_pkt_all_vps qlt_response_pkt qlt_handle_cmd_for_atio qlt_get_tag percpu_ida_alloc --> may sleep-in-atomic qla24xx_intr_handler (acquire the spinlock) qla24xx_process_response_queue qlt_handle_abts_recv qlt_response_pkt qlt_handle_cmd_for_atio qlt_get_tag percpu_ida_alloc --> may sleep I do not find a good way to fix it, so I only report. This possible bug is found by my static analysis tool (DSAC) and checked by my code review. Thanks, Jia-Ju Bai
[PATCH] arcmsr: Fix possible sleep-in-atomic bugs in arcmsr_queue_command
From: Jia-Ju Bai <baijiaju1...@163.com> The driver may sleep under a spinlock, and the function call paths are: arcmsr_queue_command(acquire the spinlock) arcmsr_queue_command_lck arcmsr_handle_virtual_command arcmsr_iop_message_xfer arcmsr_iop_parking arcmsr_stop_adapter_bgrb arcmsr_hbaA_stop_bgrb arcmsr_hbaA_wait_msgint_ready msleep --> may sleep arcmsr_queue_command(acquire the spinlock) arcmsr_queue_command_lck arcmsr_handle_virtual_command arcmsr_iop_message_xfer arcmsr_iop_parking arcmsr_stop_adapter_bgrb arcmsr_hbaB_stop_bgrb arcmsr_hbaB_wait_msgint_ready msleep --> may sleep arcmsr_queue_command(acquire the spinlock) arcmsr_queue_command_lck arcmsr_handle_virtual_command arcmsr_iop_message_xfer arcmsr_iop_parking arcmsr_stop_adapter_bgrb arcmsr_hbaC_stop_bgrb arcmsr_hbaC_wait_msgint_ready msleep --> may sleep arcmsr_queue_command(acquire the spinlock) arcmsr_queue_command_lck arcmsr_handle_virtual_command arcmsr_iop_message_xfer arcmsr_iop_parking arcmsr_stop_adapter_bgrb arcmsr_hbaD_stop_bgrb arcmsr_hbaD_wait_msgint_ready msleep --> may sleep To fix them, msleep is replaced with mdelay. These bugs are found by my static analysis tool and my code review. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/scsi/arcmsr/arcmsr_hba.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index af032c4..31d94bd 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -347,7 +347,7 @@ static uint8_t arcmsr_hbaA_wait_msgint_ready(struct AdapterControlBlock *acb) >outbound_intstatus); return true; } - msleep(10); + mdelay(10); } /* max 20 seconds */ return false; @@ -367,7 +367,7 @@ static uint8_t arcmsr_hbaB_wait_msgint_ready(struct AdapterControlBlock *acb) reg->drv2iop_doorbell); return true; } - msleep(10); + mdelay(10); } /* max 20 seconds */ return false; @@ -385,7 +385,7 @@ static uint8_t arcmsr_hbaC_wait_msgint_ready(struct AdapterControlBlock *pACB) >outbound_doorbell_clear); /*clear interrupt*/ return true; } - msleep(10); + mdelay(10); } /* max 20 seconds */ return false; @@ -403,7 +403,7 @@ static bool arcmsr_hbaD_wait_msgint_ready(struct AdapterControlBlock *pACB) reg->outbound_doorbell); return true; } - msleep(10); + mdelay(10); } /* max 20 seconds */ return false; } -- 1.7.9.5
[PATCH] esas2r: Fix a possible sleep-in-atomic bug in esas2r_wait_request
The driver may sleep in the interrupt handler. The function call path is: esas2r_adapter_tasklet (interrupt handler) esas2r_do_tasklet_tasks esas2r_handle_chip_rst_during_tasklet esas2r_init_adapter_hw esas2r_init_msgs esas2r_wait_request schedule_timeout_interruptible --> may sleep To fix it, schedule_timeout_uninterruptible is replaced with mdelay. This bug is found by my static analysis tool(DSAC) and checked by my code review. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/scsi/esas2r/esas2r_main.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c index 4eb1430..4cd8f79 100644 --- a/drivers/scsi/esas2r/esas2r_main.c +++ b/drivers/scsi/esas2r/esas2r_main.c @@ -1307,7 +1307,7 @@ void esas2r_wait_request(struct esas2r_adapter *a, struct esas2r_request *rq) if (rq->req_stat != RS_STARTED) break; - schedule_timeout_interruptible(msecs_to_jiffies(100)); + mdelay(100); if ((jiffies_to_msecs(jiffies) - starttime) > timeout) { esas2r_hdebug("request TMO"); -- 1.7.9.5
[PATCH] esas2r: Fix a possible sleep-in-atomic bug in esas2r_flash_access
The driver may sleep in the interrupt handler. The function call path is: esas2r_adapter_tasklet (interrupt handler) esas2r_do_tasklet_tasks esas2r_handle_chip_rst_during_tasklet esas2r_init_adapter_hw esas2r_nvram_read_direct esas2r_read_flash_block esas2r_flash_access schedule_timeout_interruptible --> may sleep To fix it, schedule_timeout_uninterruptible is replaced with mdelay. This bug is found by my static analysis tool(DSAC) and checked by my code review. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/scsi/esas2r/esas2r_flash.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/esas2r/esas2r_flash.c b/drivers/scsi/esas2r/esas2r_flash.c index 7bd376d..9b3da4c 100644 --- a/drivers/scsi/esas2r/esas2r_flash.c +++ b/drivers/scsi/esas2r/esas2r_flash.c @@ -965,7 +965,7 @@ static bool esas2r_flash_access(struct esas2r_adapter *a, u32 function) break; } - schedule_timeout_interruptible(msecs_to_jiffies(100)); + mdelay(100); if ((jiffies_to_msecs(jiffies) - starttime) > timeout) { /* -- 1.7.9.5
[BUG] drivers/scsi/esas2r: a possible sleep-in-atomic bug in esas2r_nvram_read_direct
The driver may sleep in the interrupt handler. The function call path is: esas2r_adapter_tasklet (interrupt handler) esas2r_do_tasklet_tasks esas2r_handle_chip_rst_during_tasklet esas2r_init_adapter_hw esas2r_nvram_read_direct down_interruptible --> may sleep I do not find a good way to fix it, so I only report. This possible bug is found by my static analysis tool (DSAC) and checked by my code review. Thanks, Jia-Ju Bai
[PATCH] esas2r: Fix possible sleep-in-atomic bugs in esas2r_check_adapter
The driver may sleep in the interrupt handler. The function call path is: esas2r_adapter_tasklet (interrupt handler) esas2r_do_tasklet_tasks esas2r_handle_chip_rst_during_tasklet esas2r_check_adapter schedule_timeout_interruptible To fix it, schedule_timeout_uninterruptible is replaced with mdelay. This bug is found by my static analysis tool(DSAC) and checked by my code review. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/scsi/esas2r/esas2r_init.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/esas2r/esas2r_init.c b/drivers/scsi/esas2r/esas2r_init.c index 5b14dd2..0b9f547 100644 --- a/drivers/scsi/esas2r/esas2r_init.c +++ b/drivers/scsi/esas2r/esas2r_init.c @@ -1068,7 +1068,7 @@ bool esas2r_check_adapter(struct esas2r_adapter *a) break; } - schedule_timeout_interruptible(msecs_to_jiffies(100)); + mdelay(100); if ((jiffies_to_msecs(jiffies) - starttime) > 18) { esas2r_hdebug("FW ready TMO"); @@ -1091,7 +1091,7 @@ bool esas2r_check_adapter(struct esas2r_adapter *a) break; } - schedule_timeout_interruptible(msecs_to_jiffies(50)); + mdelay(50); if ((jiffies_to_msecs(jiffies) - starttime) > 3000) { esas2r_hdebug("timeout waiting for interface down"); @@ -1180,7 +1180,7 @@ bool esas2r_check_adapter(struct esas2r_adapter *a) break; } - schedule_timeout_interruptible(msecs_to_jiffies(100)); + mdelay(100); if ((jiffies_to_msecs(jiffies) - starttime) > 3000) { esas2r_hdebug( -- 1.7.9.5
Re: [PATCH] NCR5380: Fix a possible sleep-in-atomic bug in NCR5380_poll_politely2
Thanks for your reply :) On 2017/12/12 11:38, Finn Thain wrote: On Tue, 12 Dec 2017, Jia-Ju Bai wrote: From: Jia-Ju Bai <baijiaju1...@gmail.com> The kernel module may sleep under a spinlock. The spinlock is always taken in irq mode, and the schedule_timeout_uninterruptible() is conditional on !irqs_disabled(). I think I ignore this check, which causes a false bug report, sorry. Thanks, Jia-Ju Bai
[BUG] drivers/scsi/wd719x: a possible sleep-in-atomic bug in wd719x_host_reset
According to drivers/scsi/wd719x.c, the kernel module may sleep under a spinlock. The function call path is: wd719x_host_reset (acquire the spinlock) wd719x_chip_init request_firmware --> may sleep I do not find a good way to fix it, so I only report. This possible bug is found by my static analysis tool (DSAC) and checked by my code review. Thanks, Jia-Ju Bai
[BUG] drivers/scsi/ipr: two possible sleep-in-atomic bugs
According to drivers/scsi/ipr.c, the kernel module may sleep under a spinlock. The function call paths are: ipr_shutdown (acquire the spinlock) irq_poll_disable msleep --> may sleep ipr_ata_post_internal (acquire the spinlock) ipr_device_reset ipr_send_blocking_cmd wait_for_completion --> may sleep (>_lock is still held) I do not find a good way to fix them, so I only report. These possible bugs are found by my static analysis tool (DSAC) and checked by my code review. Thanks, Jia-Ju Bai
[PATCH] NCR5380: Fix a possible sleep-in-atomic bug in NCR5380_poll_politely2
From: Jia-Ju Bai <baijiaju1...@gmail.com> The kernel module may sleep under a spinlock. The function call paths are: NCR5380_select (acquire the spinlock) NCR5380_reselect NCR5380_poll_politely NCR5380_poll_politely2 schedule_timeout_uninterruptible --> may sleep NCR5380_abort (acquire the spinlock) do_abort NCR5380_poll_politely NCR5380_poll_politely2 schedule_timeout_uninterruptible --> may sleep To fix it, schedule_timeout_uninterruptible is replaced with mdelay. This bug is found by my static analysis tool(DSAC) and checked by my code review. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/scsi/NCR5380.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 90ea0f5..4176aca 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -202,7 +202,7 @@ static int NCR5380_poll_politely2(struct NCR5380_hostdata *hostdata, /* Repeatedly sleep for 1 ms until deadline */ while (time_is_after_jiffies(deadline)) { - schedule_timeout_uninterruptible(1); + mdelay(1); if ((NCR5380_read(reg1) & bit1) == val1) return 0; if ((NCR5380_read(reg2) & bit2) == val2) -- 1.7.9.5
[BUG] drivers/scsi/dpt_i2o: a possible sleep-in-atomic bug in adpt_i2o_status_get
According to drivers/scsi/dpt_i2o.c, the kernel module may sleep under a spinlock. The function call paths are: adpt_reset (acquire the spinlock) __adpt_reset adpt_hba_reset adpt_i2o_activate_hba adpt_i2o_status_get dma_alloc_coherent(GFP_KERNEL) --> may sleep schedule_timeout_uninterruptible --> may sleep A possible fixing is to replace "schedule_timeout_uninterruptible" with "mdelay" and replace "GFP_KERNEL" with "GFP_ATOMIC". If this fixing is correct, I can send a patch. This possible bug is found by my static analysis tool (DSAC) and checked by my code review. Thanks, Jia-Ju Bai
[BUG] drivers/scsi/dpt_i2o: a possible sleep-in-atomic bug in adpt_i2o_post_this
According to drivers/scsi/dpt_i2o.c, the kernel module may sleep under a spinlock. The function call paths are: adpt_abort (acquire the spinlock) adpt_i2o_post_wait adpt_i2o_post_this schedule_timeout_uninterruptible--> may sleep adpt_device_reset (acquire the spinlock) adpt_i2o_post_wait adpt_i2o_post_this schedule_timeout_uninterruptible--> may sleep adpt_bus_reset (acquire the spinlock) adpt_i2o_post_wait adpt_i2o_post_this schedule_timeout_uninterruptible--> may sleep A possible fixing is to replace "schedule_timeout_uninterruptible" with "mdelay". If this fixing is correct, I can send a patch. This possible bug is found by my static analysis tool (DSAC) and checked by my code review. Thanks, Jia-Ju Bai
[BUG] drivers/scsi/dpt_i2o: a possible sleep-in-atomic bug in adpt_isr
According to drivers/scsi/dpt_i2o.c, the kernel module may sleep in the interrupt handler. The function call path is: adpt_isr (interrupt handler) adpt_send_nop schedule_timeout_uninterruptible --> may sleep A possible fixing is to replace "schedule_timeout_uninterruptible" with "mdelay". If this fixing is correct, I can send a patch. This possible is found by my static analysis tool (DSAC) and checked by my code review. Thanks, Jia-Ju Bai
[BUG] drivers/scsi/advansys: three possible sleep-in-atomic bugs in advansys_interrupt
According to drivers/scsi/advansys.c, the kernel module may sleep in the interrupt handler. The function call paths are: advansys_interrupt (interrupt handler) AdvISR adv_async_callback AdvResetChipAndSB AdvInitAsc38C1600Driver request_firmware --> may sleep AdvInitAsc38C0800Driver request_firmware --> may sleep AdvInitAsc3550Driver request_firmware --> may sleep I do not find a good way to fix them, so I only report. These possible bugs are found by my static analysis tool (DSAC) and checked by my code review. Thanks, Jia-Ju Bai
[PATCH] arcmsr: Fix possible sleep-in-atomic bugs in arcmsr_queue_command
The driver may sleep under a spinlock, and the function call paths are: arcmsr_queue_command(acquire the spinlock) arcmsr_queue_command_lck arcmsr_handle_virtual_command arcmsr_iop_message_xfer arcmsr_iop_parking arcmsr_stop_adapter_bgrb arcmsr_hbaA_stop_bgrb arcmsr_hbaA_wait_msgint_ready msleep --> may sleep arcmsr_queue_command(acquire the spinlock) arcmsr_queue_command_lck arcmsr_handle_virtual_command arcmsr_iop_message_xfer arcmsr_iop_parking arcmsr_stop_adapter_bgrb arcmsr_hbaB_stop_bgrb arcmsr_hbaB_wait_msgint_ready msleep --> may sleep arcmsr_queue_command(acquire the spinlock) arcmsr_queue_command_lck arcmsr_handle_virtual_command arcmsr_iop_message_xfer arcmsr_iop_parking arcmsr_stop_adapter_bgrb arcmsr_hbaC_stop_bgrb arcmsr_hbaC_wait_msgint_ready msleep --> may sleep arcmsr_queue_command(acquire the spinlock) arcmsr_queue_command_lck arcmsr_handle_virtual_command arcmsr_iop_message_xfer arcmsr_iop_parking arcmsr_stop_adapter_bgrb arcmsr_hbaD_stop_bgrb arcmsr_hbaD_wait_msgint_ready msleep --> may sleep To fix them, msleep is replaced with mdelay. These bugs are found by my static analysis tool and my code review. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/scsi/arcmsr/arcmsr_hba.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index af032c4..31d94bd 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -347,7 +347,7 @@ static uint8_t arcmsr_hbaA_wait_msgint_ready(struct AdapterControlBlock *acb) >outbound_intstatus); return true; } - msleep(10); + mdelay(10); } /* max 20 seconds */ return false; @@ -367,7 +367,7 @@ static uint8_t arcmsr_hbaB_wait_msgint_ready(struct AdapterControlBlock *acb) reg->drv2iop_doorbell); return true; } - msleep(10); + mdelay(10); } /* max 20 seconds */ return false; @@ -385,7 +385,7 @@ static uint8_t arcmsr_hbaC_wait_msgint_ready(struct AdapterControlBlock *pACB) >outbound_doorbell_clear); /*clear interrupt*/ return true; } - msleep(10); + mdelay(10); } /* max 20 seconds */ return false; @@ -403,7 +403,7 @@ static bool arcmsr_hbaD_wait_msgint_ready(struct AdapterControlBlock *pACB) reg->outbound_doorbell); return true; } - msleep(10); + mdelay(10); } /* max 20 seconds */ return false; } -- 1.7.9.5
[BUG] scsi/fcoe: Sleep-in-atomic bugs in fcoe driver
According to fcoe_ctlr.c, the driver may sleep under a RCU lock, and the function call paths are: fcoe_ctlr_disc_stop_locked (acquire the RCU lock) fc_rport_logoff mutex_lock --> may sleep fcoe_ctlr_vn_disc fc_rport_login mutex_lock --> may sleep fcoe_ctlr_vn_age fc_rport_logoff mutex_lock --> may sleep These bugs are found by my static analysis tool and my code review. Thanks, Jia-Ju Bai
[BUG] scsi/libfc: Sleep-in-atomic bugs in libfc
According to fc_disc.c, the driver may sleep under a RCU lock, and the function call paths are: fc_disc_done (acquire the RCU lock) fc_rport_logoff mutex_lock --> may sleep fc_disc_done (acquire the RCU lock) fc_rport_login mutex_lock --> may sleep fc_disc_stop_rports fc_rport_logoff mutex_lock --> may sleep These bugs are found by my static analysis tool and my code review. Thanks, Jia-Ju Bai
[PATCH] scsi/fnic: Fix a sleep-in-atomic bug in fnic_handle_event
The driver may sleep under a spinlock, and the function call path is: fnic_handle_event (acquire the spinlock) fnic_fcoe_start_fcf_disc fcoe_ctlr_link_up mutec_lock --> may sleep To fix it, the spinlock can be released before fnic_fcoe_start_fcf_disc, and acquired again after this function. This bug is found by my static analysis tool and my code review. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/scsi/fnic/fnic_fcs.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 999fc75..4c99c96 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -265,7 +265,9 @@ void fnic_handle_event(struct work_struct *work) case FNIC_EVT_START_FCF_DISC: FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "Start FCF Discovery\n"); + spin_unlock_irqrestore(>fnic_lock, flags); fnic_fcoe_start_fcf_disc(fnic); + spin_lock_irqsave(>fnic_lock, flags); break; default: FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, -- 1.7.9.5
[PATCH] qla4xxx: Fix a sleep-in-atomic bug in qla4_82xx_crb_win_lock
The driver may sleep under a write spin lock, the function call path is: qla4_82xx_wr_32 (acquire the lock) qla4_82xx_crb_win_lock schedule or cpu_relax To fix it, the lock is released before "schedule" and "cpu_relax", and the lock is acquired again after "schedule" and "cpu_relax". Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/scsi/qla4xxx/ql4_glbl.h |2 +- drivers/scsi/qla4xxx/ql4_nx.c |8 +--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index bce96a5..b723bef 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h @@ -115,7 +115,7 @@ uint8_t qla4xxx_update_local_ifcb(struct scsi_qla_host *ha, void qla4_82xx_queue_iocb(struct scsi_qla_host *ha); void qla4_82xx_complete_iocb(struct scsi_qla_host *ha); -int qla4_82xx_crb_win_lock(struct scsi_qla_host *); +int qla4_82xx_crb_win_lock(struct scsi_qla_host *, unsigned long *); void qla4_82xx_crb_win_unlock(struct scsi_qla_host *); int qla4_82xx_pci_get_crb_addr_2M(struct scsi_qla_host *, ulong *); void qla4_82xx_wr_32(struct scsi_qla_host *, ulong, u32); diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index e91abb3..1cf5f4a 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -386,7 +386,7 @@ if (rv == 1) { write_lock_irqsave(>hw_lock, flags); - qla4_82xx_crb_win_lock(ha); + qla4_82xx_crb_win_lock(ha, ); qla4_82xx_pci_set_crbwindow_2M(ha, ); } @@ -410,7 +410,7 @@ uint32_t qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off) if (rv == 1) { write_lock_irqsave(>hw_lock, flags); - qla4_82xx_crb_win_lock(ha); + qla4_82xx_crb_win_lock(ha, ); qla4_82xx_pci_set_crbwindow_2M(ha, ); } data = readl((void __iomem *)off); @@ -476,7 +476,7 @@ int qla4_82xx_md_wr_32(struct scsi_qla_host *ha, uint32_t off, uint32_t data) #define CRB_WIN_LOCK_TIMEOUT 1 -int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha) +int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha, unsigned long *flags) { int i; int done = 0, timeout = 0; @@ -491,6 +491,7 @@ int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha) timeout++; + write_unlock_irqrestore(>hw_lock, *flags); /* Yield CPU */ if (!in_interrupt()) schedule(); @@ -498,6 +499,7 @@ int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha) for (i = 0; i < 20; i++) cpu_relax();/*This a nop instr on i386*/ } + write_lock_irqsave(>hw_lock, *flags); } qla4_82xx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->func_num); return 0; -- 1.7.9.5
Re: [PATCH] iscsi: Fix a sleep-in-atomic bug
On 06/01/2017 02:21 PM, Nicholas A. Bellinger wrote: Hi Jia-Ju, On Wed, 2017-05-31 at 11:26 +0800, Jia-Ju Bai wrote: The driver may sleep under a spin lock, and the function call path is: iscsit_tpg_enable_portal_group (acquire the lock by spin_lock) iscsi_update_param_value kstrdup(GFP_KERNEL) --> may sleep To fix it, the "GFP_KERNEL" is replaced with "GFP_ATOMIC". Signed-off-by: Jia-Ju Bai<baijiaju1...@163.com> --- drivers/target/iscsi/iscsi_target_parameters.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Btw, the use of tpg->tpg_state_lock in iscsit_tpg_enable_portal_group() while checking existing state and calling iscsi_update_param_value() is not necessary, since lio_target_tpg_enable_store() is already holding iscsit_get_tpg() -> tpg->tpg_access_lock. How about the following instead to only take tpg->tpg_state_lock when updating tpg->tpg_state instead..? diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index 2e7e08d..abaabba 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c @@ -311,11 +311,9 @@ int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg) struct iscsi_tiqn *tiqn = tpg->tpg_tiqn; int ret; - spin_lock(>tpg_state_lock); if (tpg->tpg_state == TPG_STATE_ACTIVE) { pr_err("iSCSI target portal group: %hu is already" " active, ignoring request.\n", tpg->tpgt); - spin_unlock(>tpg_state_lock); return -EINVAL; } /* @@ -324,10 +322,8 @@ int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg) * is enforced (as per default), and remove the NONE option. */ param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list); - if (!param) { - spin_unlock(>tpg_state_lock); + if (!param) return -EINVAL; - } if (tpg->tpg_attrib.authentication) { if (!strcmp(param->value, NONE)) { @@ -341,6 +337,7 @@ int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg) goto err; } + spin_lock(>tpg_state_lock); tpg->tpg_state = TPG_STATE_ACTIVE; spin_unlock(>tpg_state_lock); @@ -353,7 +350,6 @@ int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg) return 0; err: - spin_unlock(>tpg_state_lock); return ret; } I think it is fine to me. Thanks, Jia-Ju Bai
Re: [PATCH] megaraid: Fix a sleep-in-atomic bug
On 05/31/2017 06:18 PM, Sumit Saxena wrote: -Original Message- From: Jia-Ju Bai [mailto:baijiaju1...@163.com] Sent: Wednesday, May 31, 2017 8:27 AM To: kashyap.de...@broadcom.com; sumit.sax...@broadcom.com; shivasharan.srikanteshw...@broadcom.com; j...@linux.vnet.ibm.com; martin.peter...@oracle.com Cc: megaraidlinux@broadcom.com; linux-scsi@vger.kernel.org; linux- ker...@vger.kernel.org; Jia-Ju Bai Subject: [PATCH] megaraid: Fix a sleep-in-atomic bug The driver may sleep under a spin lock, and the function call path is: mraid_mm_attach_buf (acquire the lock by spin_lock_irqsave) pci_pool_alloc(GFP_KERNEL) --> may sleep To fix it, the "GFP_KERNEL" is replaced with "GFP_ATOMIC". Signed-off-by: Jia-Ju Bai<baijiaju1...@163.com> --- drivers/scsi/megaraid/megaraid_mm.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index 4cf9ed9..c43afb8 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -574,7 +574,7 @@ kioc->pool_index = right_pool; kioc->free_buf = 1; - kioc->buf_vaddr = pci_pool_alloc(pool->handle, GFP_KERNEL, + kioc->buf_vaddr = pci_pool_alloc(pool->handle, GFP_ATOMIC, >buf_paddr); spin_unlock_irqrestore(>lock, flags); This is very old driver and reached EOL. Did you face any issue because of this bug or discover this through code review? Anyways patch looks good to me. Acked-by: Sumit Saxena<sumit.sax...@broadcom.com> -- 1.7.9.5 Hi, This bug is found by a static analysis tool and my code review. Jia-Ju Bai
[PATCH V2] qla4xxx: Fix a sleep-in-atomic bug
The driver may sleep under a write spin lock, the function call path is: qla4_82xx_wr_32 (acquire the lock) qla4_82xx_crb_win_lock schedule or cpu_relax To fix it, the lock is released before "schedule" and "cpu_relax", and the lock is acquired again after "schedule" and "cpu_relax". Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/scsi/qla4xxx/ql4_glbl.h |2 +- drivers/scsi/qla4xxx/ql4_nx.c |8 +--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index bce96a5..b723bef 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h @@ -115,7 +115,7 @@ uint8_t qla4xxx_update_local_ifcb(struct scsi_qla_host *ha, void qla4_82xx_queue_iocb(struct scsi_qla_host *ha); void qla4_82xx_complete_iocb(struct scsi_qla_host *ha); -int qla4_82xx_crb_win_lock(struct scsi_qla_host *); +int qla4_82xx_crb_win_lock(struct scsi_qla_host *, unsigned long); void qla4_82xx_crb_win_unlock(struct scsi_qla_host *); int qla4_82xx_pci_get_crb_addr_2M(struct scsi_qla_host *, ulong *); void qla4_82xx_wr_32(struct scsi_qla_host *, ulong, u32); diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index e91abb3..1cf5f4a 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -386,7 +386,7 @@ if (rv == 1) { write_lock_irqsave(>hw_lock, flags); - qla4_82xx_crb_win_lock(ha); + qla4_82xx_crb_win_lock(ha, flags); qla4_82xx_pci_set_crbwindow_2M(ha, ); } @@ -410,7 +410,7 @@ uint32_t qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off) if (rv == 1) { write_lock_irqsave(>hw_lock, flags); - qla4_82xx_crb_win_lock(ha); + qla4_82xx_crb_win_lock(ha, flags); qla4_82xx_pci_set_crbwindow_2M(ha, ); } data = readl((void __iomem *)off); @@ -476,7 +476,7 @@ int qla4_82xx_md_wr_32(struct scsi_qla_host *ha, uint32_t off, uint32_t data) #define CRB_WIN_LOCK_TIMEOUT 1 -int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha) +int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha, unsigned long flags) { int i; int done = 0, timeout = 0; @@ -491,6 +491,7 @@ int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha) timeout++; + write_unlock_irqrestore(>hw_lock, flags); /* Yield CPU */ if (!in_interrupt()) schedule(); @@ -498,6 +499,7 @@ int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha) for (i = 0; i < 20; i++) cpu_relax();/*This a nop instr on i386*/ } + write_lock_irqsave(>hw_lock, flags); } qla4_82xx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->func_num); return 0; -- 1.7.9.5
[PATCH] iscsi: Fix a sleep-in-atomic bug
The driver may sleep under a spin lock, and the function call path is: iscsit_tpg_enable_portal_group (acquire the lock by spin_lock) iscsi_update_param_value kstrdup(GFP_KERNEL) --> may sleep To fix it, the "GFP_KERNEL" is replaced with "GFP_ATOMIC". Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/target/iscsi/iscsi_target_parameters.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index fce6276..8768916 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c @@ -702,7 +702,7 @@ int iscsi_update_param_value(struct iscsi_param *param, char *value) { kfree(param->value); - param->value = kstrdup(value, GFP_KERNEL); + param->value = kstrdup(value, GFP_ATOMIC); if (!param->value) { pr_err("Unable to allocate memory for value.\n"); return -ENOMEM; -- 1.7.9.5
[PATCH] megaraid: Fix a sleep-in-atomic bug
The driver may sleep under a spin lock, and the function call path is: mraid_mm_attach_buf (acquire the lock by spin_lock_irqsave) pci_pool_alloc(GFP_KERNEL) --> may sleep To fix it, the "GFP_KERNEL" is replaced with "GFP_ATOMIC". Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/scsi/megaraid/megaraid_mm.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index 4cf9ed9..c43afb8 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -574,7 +574,7 @@ kioc->pool_index= right_pool; kioc->free_buf = 1; - kioc->buf_vaddr = pci_pool_alloc(pool->handle, GFP_KERNEL, + kioc->buf_vaddr = pci_pool_alloc(pool->handle, GFP_ATOMIC, >buf_paddr); spin_unlock_irqrestore(>lock, flags); -- 1.7.9.5
[PATCH] [PATCH] qla4xxx: Fix a sleep-in-atomic bug
The driver may sleep under a write spin lock, the function call path is: qla4_82xx_wr_32 (acquire the lock) qla4_82xx_crb_win_lock schedule or cpu_relax To fixed it, the lock is released before "schedule" and "cpu_relax", and the lock is acquired again after "schedule" and "cpu_relax". Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/scsi/qla4xxx/ql4_nx.c |8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index e91abb3..1cf5f4a 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -386,7 +386,7 @@ if (rv == 1) { write_lock_irqsave(>hw_lock, flags); - qla4_82xx_crb_win_lock(ha); + qla4_82xx_crb_win_lock(ha, flags); qla4_82xx_pci_set_crbwindow_2M(ha, ); } @@ -410,7 +410,7 @@ uint32_t qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off) if (rv == 1) { write_lock_irqsave(>hw_lock, flags); - qla4_82xx_crb_win_lock(ha); + qla4_82xx_crb_win_lock(ha, flags); qla4_82xx_pci_set_crbwindow_2M(ha, ); } data = readl((void __iomem *)off); @@ -476,7 +476,7 @@ int qla4_82xx_md_wr_32(struct scsi_qla_host *ha, uint32_t off, uint32_t data) #define CRB_WIN_LOCK_TIMEOUT 1 -int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha) +int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha, unsigned long flags) { int i; int done = 0, timeout = 0; @@ -491,6 +491,7 @@ int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha) timeout++; + write_unlock_irqrestore(>hw_lock, flags); /* Yield CPU */ if (!in_interrupt()) schedule(); @@ -498,6 +499,7 @@ int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha) for (i = 0; i < 20; i++) cpu_relax();/*This a nop instr on i386*/ } + write_lock_irqsave(>hw_lock, flags); } qla4_82xx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->func_num); return 0; -- 1.7.9.5