From: Nicholas Bellinger Date: Fri, 20 May 2011 03:19:12 +0000 (-0700) Subject: target: Fix task->task_execute_queue=1 clear bug + LUN_RESET OOPs X-Git-Tag: v2.6.38.8~72 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a50d53922bcf9185e5b0fef94936577916a6b8d;p=thirdparty%2Fkernel%2Fstable.git target: Fix task->task_execute_queue=1 clear bug + LUN_RESET OOPs commit af57c3ac9947990da2608561b71f4799eb7795c6 upstream. This patch fixes a bug where task->task_execute_queue=1 was not being cleared once se_task had been removed from se_device->execute_task_list, resulting in an OOPs in core_tmr_lun_reset() for the task->task_active=0 case where transport_remove_task_from_execute_queue() was incorrectly being called. This patch fixes two cases in transport_get_task_from_execute_queue() and transport_remove_task_from_execute_queue() to properly clear task->task_execute_queue=0 once list_del(&task->t_execute_list) has been called. It also adds an explict check in transport_remove_task_from_execute_queue() to dump_stack + return if called with task->task_execute_queue=0. Signed-off-by: Nicholas Bellinger Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 0ddcc264ef316..d2a5768a5d93e 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1197,6 +1197,7 @@ transport_get_task_from_execute_queue(struct se_device *dev) break; list_del(&task->t_execute_list); + atomic_set(&task->task_execute_queue, 0); atomic_dec(&dev->execute_tasks); return task; @@ -1212,8 +1213,14 @@ void transport_remove_task_from_execute_queue( { unsigned long flags; + if (atomic_read(&task->task_execute_queue) == 0) { + dump_stack(); + return; + } + spin_lock_irqsave(&dev->execute_task_lock, flags); list_del(&task->t_execute_list); + atomic_set(&task->task_execute_queue, 0); atomic_dec(&dev->execute_tasks); spin_unlock_irqrestore(&dev->execute_task_lock, flags); }