diff options
author | Bhanu Gollapudi <bprakash@broadcom.com> | 2011-03-21 21:51:13 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-03-23 13:53:06 -0400 |
commit | fee787129d4d6a5e967a69ea3dea3e38ba556b3d (patch) | |
tree | aa81010d8a41fe15eebbca19e7d0e9d970860129 /drivers | |
parent | 2dcb0a61041a003f439bbd38005b6e454c368be0 (diff) |
[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: Michael Chan <mchan@broadcom.com>
Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 2056890b437a..e2e647509a73 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c | |||
@@ -437,17 +437,16 @@ static int bnx2fc_l2_rcv_thread(void *arg) | |||
437 | set_current_state(TASK_INTERRUPTIBLE); | 437 | set_current_state(TASK_INTERRUPTIBLE); |
438 | while (!kthread_should_stop()) { | 438 | while (!kthread_should_stop()) { |
439 | schedule(); | 439 | schedule(); |
440 | set_current_state(TASK_RUNNING); | ||
441 | spin_lock_bh(&bg->fcoe_rx_list.lock); | 440 | spin_lock_bh(&bg->fcoe_rx_list.lock); |
442 | while ((skb = __skb_dequeue(&bg->fcoe_rx_list)) != NULL) { | 441 | while ((skb = __skb_dequeue(&bg->fcoe_rx_list)) != NULL) { |
443 | spin_unlock_bh(&bg->fcoe_rx_list.lock); | 442 | spin_unlock_bh(&bg->fcoe_rx_list.lock); |
444 | bnx2fc_recv_frame(skb); | 443 | bnx2fc_recv_frame(skb); |
445 | spin_lock_bh(&bg->fcoe_rx_list.lock); | 444 | spin_lock_bh(&bg->fcoe_rx_list.lock); |
446 | } | 445 | } |
446 | __set_current_state(TASK_INTERRUPTIBLE); | ||
447 | spin_unlock_bh(&bg->fcoe_rx_list.lock); | 447 | spin_unlock_bh(&bg->fcoe_rx_list.lock); |
448 | set_current_state(TASK_INTERRUPTIBLE); | ||
449 | } | 448 | } |
450 | set_current_state(TASK_RUNNING); | 449 | __set_current_state(TASK_RUNNING); |
451 | return 0; | 450 | return 0; |
452 | } | 451 | } |
453 | 452 | ||
@@ -569,7 +568,6 @@ int bnx2fc_percpu_io_thread(void *arg) | |||
569 | set_current_state(TASK_INTERRUPTIBLE); | 568 | set_current_state(TASK_INTERRUPTIBLE); |
570 | while (!kthread_should_stop()) { | 569 | while (!kthread_should_stop()) { |
571 | schedule(); | 570 | schedule(); |
572 | set_current_state(TASK_RUNNING); | ||
573 | spin_lock_bh(&p->fp_work_lock); | 571 | spin_lock_bh(&p->fp_work_lock); |
574 | while (!list_empty(&p->work_list)) { | 572 | while (!list_empty(&p->work_list)) { |
575 | list_splice_init(&p->work_list, &work_list); | 573 | list_splice_init(&p->work_list, &work_list); |
@@ -583,10 +581,10 @@ int bnx2fc_percpu_io_thread(void *arg) | |||
583 | 581 | ||
584 | spin_lock_bh(&p->fp_work_lock); | 582 | spin_lock_bh(&p->fp_work_lock); |
585 | } | 583 | } |
584 | __set_current_state(TASK_INTERRUPTIBLE); | ||
586 | spin_unlock_bh(&p->fp_work_lock); | 585 | spin_unlock_bh(&p->fp_work_lock); |
587 | set_current_state(TASK_INTERRUPTIBLE); | ||
588 | } | 586 | } |
589 | set_current_state(TASK_RUNNING); | 587 | __set_current_state(TASK_RUNNING); |
590 | 588 | ||
591 | return 0; | 589 | return 0; |
592 | } | 590 | } |