Commit fee78712 authored by Bhanu Gollapudi's avatar Bhanu Gollapudi Committed by James Bottomley
Browse files

[SCSI] bnx2fc: IO completion not processed due to missed wakeup



Driver does not detect a new CQE (completion queue entry) if a thread receives
the wakup when it is in TASK_RUNNING state. Fix is to set the state to
TASK_INTERRUPTIBLE while holding the fp_work_lock.

Also, Use __set_current_task() since it is now set inside a spinlock with
synchronization.

Two other related optimizations:

1.  After we exit the while (!kthread_should_stop()) loop, use
__set_current_state() since synchronization is no longer needed.

2.  Remove set_current_state(TASK_RUNNING) after schedule() since it
should always be TASK_RUNNING after schedule().

Reviewed-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarBhanu Prakash Gollapudi <bprakash@broadcom.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 2dcb0a61
Loading
Loading
Loading
Loading
+4 −6
Original line number Original line Diff line number Diff line
@@ -437,17 +437,16 @@ static int bnx2fc_l2_rcv_thread(void *arg)
	set_current_state(TASK_INTERRUPTIBLE);
	set_current_state(TASK_INTERRUPTIBLE);
	while (!kthread_should_stop()) {
	while (!kthread_should_stop()) {
		schedule();
		schedule();
		set_current_state(TASK_RUNNING);
		spin_lock_bh(&bg->fcoe_rx_list.lock);
		spin_lock_bh(&bg->fcoe_rx_list.lock);
		while ((skb = __skb_dequeue(&bg->fcoe_rx_list)) != NULL) {
		while ((skb = __skb_dequeue(&bg->fcoe_rx_list)) != NULL) {
			spin_unlock_bh(&bg->fcoe_rx_list.lock);
			spin_unlock_bh(&bg->fcoe_rx_list.lock);
			bnx2fc_recv_frame(skb);
			bnx2fc_recv_frame(skb);
			spin_lock_bh(&bg->fcoe_rx_list.lock);
			spin_lock_bh(&bg->fcoe_rx_list.lock);
		}
		}
		__set_current_state(TASK_INTERRUPTIBLE);
		spin_unlock_bh(&bg->fcoe_rx_list.lock);
		spin_unlock_bh(&bg->fcoe_rx_list.lock);
		set_current_state(TASK_INTERRUPTIBLE);
	}
	}
	set_current_state(TASK_RUNNING);
	__set_current_state(TASK_RUNNING);
	return 0;
	return 0;
}
}


@@ -569,7 +568,6 @@ int bnx2fc_percpu_io_thread(void *arg)
	set_current_state(TASK_INTERRUPTIBLE);
	set_current_state(TASK_INTERRUPTIBLE);
	while (!kthread_should_stop()) {
	while (!kthread_should_stop()) {
		schedule();
		schedule();
		set_current_state(TASK_RUNNING);
		spin_lock_bh(&p->fp_work_lock);
		spin_lock_bh(&p->fp_work_lock);
		while (!list_empty(&p->work_list)) {
		while (!list_empty(&p->work_list)) {
			list_splice_init(&p->work_list, &work_list);
			list_splice_init(&p->work_list, &work_list);
@@ -583,10 +581,10 @@ int bnx2fc_percpu_io_thread(void *arg)


			spin_lock_bh(&p->fp_work_lock);
			spin_lock_bh(&p->fp_work_lock);
		}
		}
		__set_current_state(TASK_INTERRUPTIBLE);
		spin_unlock_bh(&p->fp_work_lock);
		spin_unlock_bh(&p->fp_work_lock);
		set_current_state(TASK_INTERRUPTIBLE);
	}
	}
	set_current_state(TASK_RUNNING);
	__set_current_state(TASK_RUNNING);


	return 0;
	return 0;
}
}