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
520520 #define BNX2X_FP_STATE_IDLE 0
521521 #define BNX2X_FP_STATE_NAPI (1 << 0) /* NAPI owns this FP */
522522 #define BNX2X_FP_STATE_POLL (1 << 1) /* poll owns this FP */
523−#define BNX2X_FP_STATE_NAPI_YIELD (1 << 2) /* NAPI yielded this FP */
524−#define BNX2X_FP_STATE_POLL_YIELD (1 << 3) /* poll yielded this FP */
523+#define BNX2X_FP_STATE_DISABLED (1 << 2)
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)
525527 #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)
527529 #define BNX2X_FP_USER_PEND (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_POLL_YIELD)
528530 /* protect state */
529531 spinlock_t lock;
@@ -613,7 +615,7 @@ static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp) · 83 unmodified lines
613615 {
614616 bool rc = true;
615617
616− spin_lock(&fp->lock);
618+ spin_lock_bh(&fp->lock);
617619 if (fp->state & BNX2X_FP_LOCKED) {
618620 WARN_ON(fp->state & BNX2X_FP_STATE_NAPI);
619621 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
622624 /* we don't care if someone yielded */
623625 fp->state = BNX2X_FP_STATE_NAPI;
624626 }
625− spin_unlock(&fp->lock);
627+ spin_unlock_bh(&fp->lock);
626628 return rc;
627629 }
628630
@@ -631,14 +633,16 @@ static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp) · 2 unmodified lines
631633 {
632634 bool rc = false;
633635
634− spin_lock(&fp->lock);
636+ spin_lock_bh(&fp->lock);
635637 WARN_ON(fp->state &
636638 (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_NAPI_YIELD));
637639
638640 if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
639641 rc = true;
640− fp->state = BNX2X_FP_STATE_IDLE;
641− spin_unlock(&fp->lock);
642+
643+ /* state ==> idle, unless currently disabled */
644+ fp->state &= BNX2X_FP_STATE_DISABLED;
645+ spin_unlock_bh(&fp->lock);
642646 return rc;
643647 }
644648
@@ -669,7 +673,9 @@ static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp) · 24 unmodified lines
669673
670674 if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
671675 rc = true;
672− fp->state = BNX2X_FP_STATE_IDLE;
676+
677+ /* state ==> idle, unless currently disabled */
678+ fp->state &= BNX2X_FP_STATE_DISABLED;
673679 spin_unlock_bh(&fp->lock);
674680 return rc;
675681 }
@@ -677,9 +683,23 @@ static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp) · 1 unmodified line
677683 /* true if a socket is polling, even if it did not get the lock */
678684 static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
679685 {
680− WARN_ON(!(fp->state & BNX2X_FP_LOCKED));
686+ WARN_ON(!(fp->state & BNX2X_FP_OWNED));
681687 return fp->state & BNX2X_FP_USER_PEND;
682688 }
689+
690+/* false if fp is currently owned */
691+static 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+}
683703 #else
684704 static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp)
685705 {
@@ -709,6 +729,10 @@ static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp) · 23 unmodified lines
709729 {
710730 return false;
711731 }
732+static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp)
733+{
734+ return true;
735+}
712736 #endif /* CONFIG_NET_RX_BUSY_POLL */
713737
714738 /* 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
17901790 {
17911791 int i;
17921792
1793− local_bh_disable();
17941793 for_each_rx_queue_cnic(bp, i) {
17951794 napi_disable(&bnx2x_fp(bp, i, napi));
1796− while (!bnx2x_fp_lock_napi(&bp->fp[i]))
1797− mdelay(1);
1795+ while (!bnx2x_fp_ll_disable(&bp->fp[i]))
1796+ usleep_range(1000, 2000);
17981797 }
1799− local_bh_enable();
18001798 }
18011799
18021800 static void bnx2x_napi_disable(struct bnx2x *bp)
18031801 {
18041802 int i;
18051803
1806− local_bh_disable();
18071804 for_each_eth_queue(bp, i) {
18081805 napi_disable(&bnx2x_fp(bp, i, napi));
1809− while (!bnx2x_fp_lock_napi(&bp->fp[i]))
1810− mdelay(1);
1806+ while (!bnx2x_fp_ll_disable(&bp->fp[i]))
1807+ usleep_range(1000, 2000);
18111808 }
1812− local_bh_enable();
18131809 }
18141810
18151811 void bnx2x_netif_start(struct bnx2x *bp)