History

bnx2x: prevent WARN during driver unload

Starting with commit 80c33dd "net: add might_sleep() call to napi_disable" bnx2x fails the might_sleep tests causing a stack trace to appear whenever the driver is unloaded, as local_bh_disable() is being called before napi_disable(). This changes the locking schematics related to CONFIG_NET_RX_BUSY_POLL, preventing the need for calling local_bh_disable() and thus eliminating the issue.

Yuval Mintz committed 12 years ago

Commit 9a2620c1 parent a04c0e22 files · +38 −18Browse files

Unified · Split

2 files
  1. drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +34 −10
  2. drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +4 −8
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h+34−10
@@ -520,10 +520,12 @@ struct bnx2x_fastpath { · 519 unmodified lines
520#define BNX2X_FP_STATE_IDLE 0520#define BNX2X_FP_STATE_IDLE 0
521#define BNX2X_FP_STATE_NAPI (1 << 0) /* NAPI owns this FP */521#define BNX2X_FP_STATE_NAPI (1 << 0) /* NAPI owns this FP */
522#define BNX2X_FP_STATE_POLL (1 << 1) /* poll owns this FP */522#define BNX2X_FP_STATE_POLL (1 << 1) /* poll owns this FP */
523#define BNX2X_FP_STATE_NAPI_YIELD (1 << 2) /* NAPI yielded this FP */523#define BNX2X_FP_STATE_DISABLED (1 << 2)
524#define BNX2X_FP_STATE_POLL_YIELD (1 << 3) /* poll yielded this FP */524#define BNX2X_FP_STATE_NAPI_YIELD (1 << 3) /* NAPI yielded this FP */
525#define BNX2X_FP_STATE_POLL_YIELD (1 << 4) /* poll yielded this FP */
526#define BNX2X_FP_OWNED (BNX2X_FP_STATE_NAPI | BNX2X_FP_STATE_POLL)
525#define BNX2X_FP_YIELD (BNX2X_FP_STATE_NAPI_YIELD | BNX2X_FP_STATE_POLL_YIELD)527#define BNX2X_FP_YIELD (BNX2X_FP_STATE_NAPI_YIELD | BNX2X_FP_STATE_POLL_YIELD)
526#define BNX2X_FP_LOCKED (BNX2X_FP_STATE_NAPI | BNX2X_FP_STATE_POLL)528#define BNX2X_FP_LOCKED (BNX2X_FP_OWNED | BNX2X_FP_STATE_DISABLED)
527#define BNX2X_FP_USER_PEND (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_POLL_YIELD)529#define BNX2X_FP_USER_PEND (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_POLL_YIELD)
528 /* protect state */530 /* protect state */
529 spinlock_t lock;531 spinlock_t lock;
@@ -613,7 +615,7 @@ static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp) · 83 unmodified lines
613{615{
614 bool rc = true;616 bool rc = true;
615 617
616 spin_lock(&fp->lock);618 spin_lock_bh(&fp->lock);
617 if (fp->state & BNX2X_FP_LOCKED) {619 if (fp->state & BNX2X_FP_LOCKED) {
618 WARN_ON(fp->state & BNX2X_FP_STATE_NAPI);620 WARN_ON(fp->state & BNX2X_FP_STATE_NAPI);
619 fp->state |= BNX2X_FP_STATE_NAPI_YIELD;621 fp->state |= BNX2X_FP_STATE_NAPI_YIELD;
@@ -622,7 +624,7 @@ static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp) · 2 unmodified lines
622 /* we don't care if someone yielded */624 /* we don't care if someone yielded */
623 fp->state = BNX2X_FP_STATE_NAPI;625 fp->state = BNX2X_FP_STATE_NAPI;
624 }626 }
625 spin_unlock(&fp->lock);627 spin_unlock_bh(&fp->lock);
626 return rc;628 return rc;
627}629}
628 630
@@ -631,14 +633,16 @@ static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp) · 2 unmodified lines
631{633{
632 bool rc = false;634 bool rc = false;
633 635
634 spin_lock(&fp->lock);636 spin_lock_bh(&fp->lock);
635 WARN_ON(fp->state &637 WARN_ON(fp->state &
636 (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_NAPI_YIELD));638 (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_NAPI_YIELD));
637 639
638 if (fp->state & BNX2X_FP_STATE_POLL_YIELD)640 if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
639 rc = true;641 rc = true;
640 fp->state = BNX2X_FP_STATE_IDLE;642
641 spin_unlock(&fp->lock);643 /* state ==> idle, unless currently disabled */
644 fp->state &= BNX2X_FP_STATE_DISABLED;
645 spin_unlock_bh(&fp->lock);
642 return rc;646 return rc;
643}647}
644 648
@@ -669,7 +673,9 @@ static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp) · 24 unmodified lines
669 673
670 if (fp->state & BNX2X_FP_STATE_POLL_YIELD)674 if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
671 rc = true;675 rc = true;
672 fp->state = BNX2X_FP_STATE_IDLE;676
677 /* state ==> idle, unless currently disabled */
678 fp->state &= BNX2X_FP_STATE_DISABLED;
673 spin_unlock_bh(&fp->lock);679 spin_unlock_bh(&fp->lock);
674 return rc;680 return rc;
675}681}
@@ -677,9 +683,23 @@ static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp) · 1 unmodified line
677/* true if a socket is polling, even if it did not get the lock */683/* true if a socket is polling, even if it did not get the lock */
678static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)684static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
679{685{
680 WARN_ON(!(fp->state & BNX2X_FP_LOCKED));686 WARN_ON(!(fp->state & BNX2X_FP_OWNED));
681 return fp->state & BNX2X_FP_USER_PEND;687 return fp->state & BNX2X_FP_USER_PEND;
682}688}
689
690/* false if fp is currently owned */
691static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp)
692{
693 int rc = true;
694
695 spin_lock_bh(&fp->lock);
696 if (fp->state & BNX2X_FP_OWNED)
697 rc = false;
698 fp->state |= BNX2X_FP_STATE_DISABLED;
699 spin_unlock_bh(&fp->lock);
700
701 return rc;
702}
683#else703#else
684static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp)704static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp)
685{705{
@@ -709,6 +729,10 @@ static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp) · 23 unmodified lines
709{729{
710 return false;730 return false;
711}731}
732static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp)
733{
734 return true;
735}
712#endif /* CONFIG_NET_RX_BUSY_POLL */736#endif /* CONFIG_NET_RX_BUSY_POLL */
713 737
714/* Use 2500 as a mini-jumbo MTU for FCoE */738/* Use 2500 as a mini-jumbo MTU for FCoE */
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c+4−8
@@ -1790,26 +1790,22 @@ static void bnx2x_napi_disable_cnic(struct bnx2x *bp) · 1789 unmodified lines
1790{1790{
1791 int i;1791 int i;
1792 1792
1793 local_bh_disable();
1794 for_each_rx_queue_cnic(bp, i) {1793 for_each_rx_queue_cnic(bp, i) {
1795 napi_disable(&bnx2x_fp(bp, i, napi));1794 napi_disable(&bnx2x_fp(bp, i, napi));
1796 while (!bnx2x_fp_lock_napi(&bp->fp[i]))1795 while (!bnx2x_fp_ll_disable(&bp->fp[i]))
1797 mdelay(1);1796 usleep_range(1000, 2000);
1798 }1797 }
1799 local_bh_enable();
1800}1798}
1801 1799
1802static void bnx2x_napi_disable(struct bnx2x *bp)1800static void bnx2x_napi_disable(struct bnx2x *bp)
1803{1801{
1804 int i;1802 int i;
1805 1803
1806 local_bh_disable();
1807 for_each_eth_queue(bp, i) {1804 for_each_eth_queue(bp, i) {
1808 napi_disable(&bnx2x_fp(bp, i, napi));1805 napi_disable(&bnx2x_fp(bp, i, napi));
1809 while (!bnx2x_fp_lock_napi(&bp->fp[i]))1806 while (!bnx2x_fp_ll_disable(&bp->fp[i]))
1810 mdelay(1);1807 usleep_range(1000, 2000);
1811 }1808 }
1812 local_bh_enable();
1813}1809}
1814 1810
1815void bnx2x_netif_start(struct bnx2x *bp)1811void bnx2x_netif_start(struct bnx2x *bp)