| @@ -49,6 +49,7 @@ · 48 unmodified lines |
| 49 | 49 | static int debug_fcoe; |
| 50 | 50 | |
| 51 | 51 | #define FCOE_MAX_QUEUE_DEPTH 256 |
| 52 | +#define FCOE_LOW_QUEUE_DEPTH 32 |
| 52 | 53 | |
| 53 | 54 | /* destination address mode */ |
| 54 | 55 | #define FCOE_GW_ADDR_MODE 0x00 |
| @@ -723,21 +724,12 @@ static void fcoe_recv_flogi(struct fcoe_softc *fc, struct fc_frame *fp, u8 *sa) · 668 unmodified lines |
| 723 | 724 | */ |
| 724 | 725 | void fcoe_watchdog(ulong vp) |
| 725 | 726 | { |
| 726 | | − struct fc_lport *lp; |
| 727 | 727 | struct fcoe_softc *fc; |
| 728 | | − int qfilled = 0; |
| 729 | 728 | |
| 730 | 729 | read_lock(&fcoe_hostlist_lock); |
| 731 | 730 | list_for_each_entry(fc, &fcoe_hostlist, list) { |
| 732 | | − lp = fc->lp; |
| 733 | | − if (lp) { |
| 734 | | − if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) |
| 735 | | − qfilled = 1; |
| 736 | | − if (fcoe_check_wait_queue(lp) < FCOE_MAX_QUEUE_DEPTH) { |
| 737 | | − if (qfilled) |
| 738 | | − lp->qfull = 0; |
| 739 | | − } |
| 740 | | − } |
| 731 | + if (fc->lp) |
| 732 | + fcoe_check_wait_queue(fc->lp); |
| 741 | 733 | } |
| 742 | 734 | read_unlock(&fcoe_hostlist_lock); |
| 743 | 735 | |
| @@ -753,8 +745,8 @@ void fcoe_watchdog(ulong vp) · 9 unmodified lines |
| 753 | 745 | * |
| 754 | 746 | * This empties the wait_queue, dequeue the head of the wait_queue queue |
| 755 | 747 | * and calls fcoe_start_io() for each packet, if all skb have been |
| 756 | | − * transmitted, return 0 if a error occurs, then restore wait_queue and |
| 757 | | − * try again later. |
| 748 | + * transmitted, return qlen or -1 if a error occurs, then restore |
| 749 | + * wait_queue and try again later. |
| 758 | 750 | * |
| 759 | 751 | * The wait_queue is used when the skb transmit fails. skb will go |
| 760 | 752 | * in the wait_queue which will be emptied by the time function OR |
| @@ -764,33 +756,38 @@ void fcoe_watchdog(ulong vp) · 3 unmodified lines |
| 764 | 756 | */ |
| 765 | 757 | static int fcoe_check_wait_queue(struct fc_lport *lp) |
| 766 | 758 | { |
| 767 | | − int rc; |
| 768 | 759 | struct sk_buff *skb; |
| 769 | 760 | struct fcoe_softc *fc; |
| 761 | + int rc = -1; |
| 770 | 762 | |
| 771 | 763 | fc = lport_priv(lp); |
| 772 | 764 | spin_lock_bh(&fc->fcoe_pending_queue.lock); |
| 773 | 765 | |
| 774 | | − /* |
| 775 | | − * if interface pending queue full then set qfull in lport. |
| 776 | | − */ |
| 777 | | − if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) |
| 778 | | − lp->qfull = 1; |
| 766 | + if (fc->fcoe_pending_queue_active) |
| 767 | + goto out; |
| 768 | + fc->fcoe_pending_queue_active = 1; |
| 779 | 769 | if (fc->fcoe_pending_queue.qlen) { |
| 780 | 770 | while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) { |
| 781 | 771 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); |
| 782 | 772 | rc = fcoe_start_io(skb); |
| 783 | | − if (rc) { |
| 773 | + if (rc) |
| 784 | 774 | fcoe_insert_wait_queue_head(lp, skb); |
| 785 | | − return rc; |
| 786 | | − } |
| 787 | 775 | spin_lock_bh(&fc->fcoe_pending_queue.lock); |
| 776 | + if (rc) |
| 777 | + break; |
| 788 | 778 | } |
| 789 | | − if (fc->fcoe_pending_queue.qlen < FCOE_MAX_QUEUE_DEPTH) |
| 779 | + /* |
| 780 | + * if interface pending queue is below FCOE_LOW_QUEUE_DEPTH |
| 781 | + * then clear qfull flag. |
| 782 | + */ |
| 783 | + if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) |
| 790 | 784 | lp->qfull = 0; |
| 791 | 785 | } |
| 786 | + fc->fcoe_pending_queue_active = 0; |
| 787 | + rc = fc->fcoe_pending_queue.qlen; |
| 788 | +out: |
| 792 | 789 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); |
| 793 | | − return fc->fcoe_pending_queue.qlen; |
| 790 | + return rc; |
| 794 | 791 | } |
| 795 | 792 | |
| 796 | 793 | /** |