[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>

authored by Bhanu Gollapudi and committed by James Bottomley fee78712 2dcb0a61

+4 -6
+4 -6
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
··· 437 set_current_state(TASK_INTERRUPTIBLE); 438 while (!kthread_should_stop()) { 439 schedule(); 440 - set_current_state(TASK_RUNNING); 441 spin_lock_bh(&bg->fcoe_rx_list.lock); 442 while ((skb = __skb_dequeue(&bg->fcoe_rx_list)) != NULL) { 443 spin_unlock_bh(&bg->fcoe_rx_list.lock); 444 bnx2fc_recv_frame(skb); 445 spin_lock_bh(&bg->fcoe_rx_list.lock); 446 } 447 spin_unlock_bh(&bg->fcoe_rx_list.lock); 448 - set_current_state(TASK_INTERRUPTIBLE); 449 } 450 - set_current_state(TASK_RUNNING); 451 return 0; 452 } 453 ··· 568 set_current_state(TASK_INTERRUPTIBLE); 569 while (!kthread_should_stop()) { 570 schedule(); 571 - set_current_state(TASK_RUNNING); 572 spin_lock_bh(&p->fp_work_lock); 573 while (!list_empty(&p->work_list)) { 574 list_splice_init(&p->work_list, &work_list); ··· 581 582 spin_lock_bh(&p->fp_work_lock); 583 } 584 spin_unlock_bh(&p->fp_work_lock); 585 - set_current_state(TASK_INTERRUPTIBLE); 586 } 587 - set_current_state(TASK_RUNNING); 588 589 return 0; 590 }
··· 437 set_current_state(TASK_INTERRUPTIBLE); 438 while (!kthread_should_stop()) { 439 schedule(); 440 spin_lock_bh(&bg->fcoe_rx_list.lock); 441 while ((skb = __skb_dequeue(&bg->fcoe_rx_list)) != NULL) { 442 spin_unlock_bh(&bg->fcoe_rx_list.lock); 443 bnx2fc_recv_frame(skb); 444 spin_lock_bh(&bg->fcoe_rx_list.lock); 445 } 446 + __set_current_state(TASK_INTERRUPTIBLE); 447 spin_unlock_bh(&bg->fcoe_rx_list.lock); 448 } 449 + __set_current_state(TASK_RUNNING); 450 return 0; 451 } 452 ··· 569 set_current_state(TASK_INTERRUPTIBLE); 570 while (!kthread_should_stop()) { 571 schedule(); 572 spin_lock_bh(&p->fp_work_lock); 573 while (!list_empty(&p->work_list)) { 574 list_splice_init(&p->work_list, &work_list); ··· 583 584 spin_lock_bh(&p->fp_work_lock); 585 } 586 + __set_current_state(TASK_INTERRUPTIBLE); 587 spin_unlock_bh(&p->fp_work_lock); 588 } 589 + __set_current_state(TASK_RUNNING); 590 591 return 0; 592 }