Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-8]: src/sys/dev/pci Pull up following revision(s) (requested by k...
details: https://anonhg.NetBSD.org/src/rev/4287ceeaa02b
branches: netbsd-8
changeset: 434659:4287ceeaa02b
user: snj <snj%NetBSD.org@localhost>
date: Mon Feb 26 00:00:53 2018 +0000
description:
Pull up following revision(s) (requested by knakahara in ticket #564):
sys/dev/pci/if_wm.c: 1.563
Fix a bug that RX and TX may stall on heavy load on wm(4) like ixgbe.c:r1.121.
wm_rxeof() and wm_txeof() have loop limit and the function returns true
if a packet still exists.
diffstat:
sys/dev/pci/if_wm.c | 55 +++++++++++++++++++++++++++++++++++++---------------
1 files changed, 39 insertions(+), 16 deletions(-)
diffs (182 lines):
diff -r 358d06fd7ac2 -r 4287ceeaa02b sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Sun Feb 25 23:57:51 2018 +0000
+++ b/sys/dev/pci/if_wm.c Mon Feb 26 00:00:53 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.508.4.13 2018/02/05 15:07:30 martin Exp $ */
+/* $NetBSD: if_wm.c,v 1.508.4.14 2018/02/26 00:00:53 snj Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -83,7 +83,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.508.4.13 2018/02/05 15:07:30 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.508.4.14 2018/02/26 00:00:53 snj Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -775,8 +775,8 @@
static void wm_deferred_start_locked(struct wm_txqueue *);
static void wm_handle_queue(void *);
/* Interrupt */
-static int wm_txeof(struct wm_txqueue *, u_int);
-static void wm_rxeof(struct wm_rxqueue *, u_int);
+static bool wm_txeof(struct wm_txqueue *, u_int);
+static bool wm_rxeof(struct wm_rxqueue *, u_int);
static void wm_linkintr_gmii(struct wm_softc *, uint32_t);
static void wm_linkintr_tbi(struct wm_softc *, uint32_t);
static void wm_linkintr_serdes(struct wm_softc *, uint32_t);
@@ -8066,7 +8066,7 @@
*
* Helper; handle transmit interrupts.
*/
-static int
+static bool
wm_txeof(struct wm_txqueue *txq, u_int limit)
{
struct wm_softc *sc = txq->txq_sc;
@@ -8076,11 +8076,12 @@
int i;
uint8_t status;
struct wm_queue *wmq = container_of(txq, struct wm_queue, wmq_txq);
+ bool more = false;
KASSERT(mutex_owned(txq->txq_lock));
if (txq->txq_stopping)
- return 0;
+ return false;
txq->txq_flags &= ~WM_TXQ_NO_SPACE;
/* for ALTQ and legacy(not use multiqueue) ethernet controller */
@@ -8093,8 +8094,13 @@
*/
for (i = txq->txq_sdirty; txq->txq_sfree != WM_TXQUEUELEN(txq);
i = WM_NEXTTXS(txq, i), txq->txq_sfree++) {
- if (limit-- == 0)
- break;
+ if (limit-- == 0) {
+ more = true;
+ DPRINTF(WM_DEBUG_TX,
+ ("%s: TX: loop limited, job %d is not processed\n",
+ device_xname(sc->sc_dev), i));
+ break;
+ }
txs = &txq->txq_soft[i];
@@ -8168,7 +8174,7 @@
if (txq->txq_sfree == WM_TXQUEUELEN(txq))
txq->txq_watchdog = false;
- return count;
+ return more;
}
static inline uint32_t
@@ -8381,7 +8387,7 @@
*
* Helper; handle receive interrupts.
*/
-static void
+static bool
wm_rxeof(struct wm_rxqueue *rxq, u_int limit)
{
struct wm_softc *sc = rxq->rxq_sc;
@@ -8392,12 +8398,17 @@
int count = 0;
uint32_t status, errors;
uint16_t vlantag;
+ bool more = false;
KASSERT(mutex_owned(rxq->rxq_lock));
for (i = rxq->rxq_ptr;; i = WM_NEXTRX(i)) {
if (limit-- == 0) {
rxq->rxq_ptr = i;
+ more = true;
+ DPRINTF(WM_DEBUG_RX,
+ ("%s: RX: loop limited, descriptor %d is not processed\n",
+ device_xname(sc->sc_dev), i));
break;
}
@@ -8571,6 +8582,8 @@
DPRINTF(WM_DEBUG_RX,
("%s: RX: rxptr -> %d\n", device_xname(sc->sc_dev), i));
+
+ return more;
}
/*
@@ -9009,6 +9022,8 @@
struct wm_softc *sc = txq->txq_sc;
u_int txlimit = sc->sc_tx_intr_process_limit;
u_int rxlimit = sc->sc_rx_intr_process_limit;
+ bool txmore;
+ bool rxmore;
KASSERT(wmq->wmq_intr_idx == wmq->wmq_id);
@@ -9025,7 +9040,7 @@
}
WM_Q_EVCNT_INCR(txq, txdw);
- wm_txeof(txq, txlimit);
+ txmore = wm_txeof(txq, txlimit);
/* wm_deferred start() is done in wm_handle_queue(). */
mutex_exit(txq->txq_lock);
@@ -9039,12 +9054,15 @@
}
WM_Q_EVCNT_INCR(rxq, rxintr);
- wm_rxeof(rxq, rxlimit);
+ rxmore = wm_rxeof(rxq, rxlimit);
mutex_exit(rxq->rxq_lock);
wm_itrs_writereg(sc, wmq);
- softint_schedule(wmq->wmq_si);
+ if (txmore || rxmore)
+ softint_schedule(wmq->wmq_si);
+ else
+ wm_txrxintr_enable(wmq);
return 1;
}
@@ -9058,13 +9076,15 @@
struct wm_softc *sc = txq->txq_sc;
u_int txlimit = sc->sc_tx_process_limit;
u_int rxlimit = sc->sc_rx_process_limit;
+ bool txmore;
+ bool rxmore;
mutex_enter(txq->txq_lock);
if (txq->txq_stopping) {
mutex_exit(txq->txq_lock);
return;
}
- wm_txeof(txq, txlimit);
+ txmore = wm_txeof(txq, txlimit);
wm_deferred_start_locked(txq);
mutex_exit(txq->txq_lock);
@@ -9074,10 +9094,13 @@
return;
}
WM_Q_EVCNT_INCR(rxq, rxdefer);
- wm_rxeof(rxq, rxlimit);
+ rxmore = wm_rxeof(rxq, rxlimit);
mutex_exit(rxq->rxq_lock);
- wm_txrxintr_enable(wmq);
+ if (txmore || rxmore)
+ softint_schedule(wmq->wmq_si);
+ else
+ wm_txrxintr_enable(wmq);
}
/*
Home |
Main Index |
Thread Index |
Old Index