Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 563585ec authored by James Bottomley's avatar James Bottomley
Browse files

[SCSI] qla2xxx: Fix race that could hang kthread_stop()



There is a small race window in qla2x00_do_dpc() between
checking for kthread_should_stop() and going to sleep after
setting TASK_INTERRUPTIBLE. If qla2x00_free_device() is called
in this window, kthread_stop will wait forever because there
will be no one to wake up the process.

Fix by making sure we only set TASK_INTERRUPTIBLE before checking
kthread_stop().

Reported-by: default avatarBandan Das <bandan.das@stratus.com>
Acked-by: default avatarMadhuranath Iyengar <Madhu.Iyengar@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 3c6c0d6c
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -3282,10 +3282,10 @@ qla2x00_do_dpc(void *data)


	set_user_nice(current, -20);
	set_user_nice(current, -20);


	set_current_state(TASK_INTERRUPTIBLE);
	while (!kthread_should_stop()) {
	while (!kthread_should_stop()) {
		DEBUG3(printk("qla2x00: DPC handler sleeping\n"));
		DEBUG3(printk("qla2x00: DPC handler sleeping\n"));


		set_current_state(TASK_INTERRUPTIBLE);
		schedule();
		schedule();
		__set_current_state(TASK_RUNNING);
		__set_current_state(TASK_RUNNING);


@@ -3454,7 +3454,9 @@ qla2x00_do_dpc(void *data)
		qla2x00_do_dpc_all_vps(base_vha);
		qla2x00_do_dpc_all_vps(base_vha);


		ha->dpc_active = 0;
		ha->dpc_active = 0;
		set_current_state(TASK_INTERRUPTIBLE);
	} /* End of while(1) */
	} /* End of while(1) */
	__set_current_state(TASK_RUNNING);


	DEBUG(printk("scsi(%ld): DPC handler exiting\n", base_vha->host_no));
	DEBUG(printk("scsi(%ld): DPC handler exiting\n", base_vha->host_no));