NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/60175: panic: igc_rxrefill: msix=0 id=351



The following reply was made to PR kern/60175; it has been noted by GNATS.

From: Thomas Klausner <wiz%netbsd.org@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: rin%netbsd.org@localhost
Subject: Re: kern/60175: panic: igc_rxrefill: msix=0 id=351
Date: Sun, 24 May 2026 23:20:03 +0200

 --jxm65gqetppbszrs
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 I'm testing the attached diff now.
  Thomas
 
 --jxm65gqetppbszrs
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="if_igc.diff"
 
 Index: if_igc.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/pci/igc/if_igc.c,v
 retrieving revision 1.24
 diff -u -r1.24 if_igc.c
 --- if_igc.c	3 Jan 2026 20:17:16 -0000	1.24
 +++ if_igc.c	23 May 2026 20:35:17 -0000
 @@ -196,7 +196,8 @@
  static int	igc_rxrinfo(struct igc_softc *, struct if_rxrinfo *);
  #endif
  static void	igc_rxfill(struct rx_ring *);
 -static void	igc_rxrefill(struct rx_ring *, int);
 +static bool	igc_rxrefill(struct rx_ring *);
 +static void	igc_rxrefill_callout(void *);
  static bool	igc_rxeof(struct rx_ring *, u_int);
  static int	igc_rx_checksum(struct igc_queue *, uint64_t, uint32_t,
  		    uint32_t);
 @@ -692,6 +693,9 @@
  #ifdef OPENBSD
  		timeout_set(&rxr->rx_refill, igc_rxrefill, rxr);
  #endif
 +		callout_init(&rxr->rx_refill, CALLOUT_MPSAFE);
 +		callout_setfunc(&rxr->rx_refill, igc_rxrefill_callout, rxr);
 +
  		if (igc_dma_malloc(sc, rsize, &rxr->rxdma)) {
  			aprint_error_dev(dev,
  			    "unable to allocate RX descriptor\n");
 @@ -1919,6 +1923,7 @@
  	for (int iq = 0; iq < sc->sc_nqueues; iq++) {
  		struct rx_ring *rxr = &sc->rx_rings[iq];
  
 +		callout_halt(&rxr->rx_refill, &rxr->rxr_lock);
  		igc_clear_receive_status(rxr);
  	}
  
 @@ -2044,25 +2049,39 @@
  	rxr->next_to_check = 0;
  }
  
 -static void
 -igc_rxrefill(struct rx_ring *rxr, int end)
 +static bool
 +igc_rxrefill(struct rx_ring *rxr)
  {
  	struct igc_softc *sc = rxr->sc;
  	int id;
 +	const int start = igc_rxdesc_incr(sc, rxr->last_desc_filled);
  
 -	for (id = rxr->next_to_check; id != end; id = igc_rxdesc_incr(sc, id)) {
 -		if (igc_get_buf(rxr, id, true)) {
 -			/* XXXRO */
 -			panic("%s: msix=%d id=%d\n", __func__, rxr->me, id);
 -		}
 +	for (id = start; id != rxr->next_to_check; id = igc_rxdesc_incr(sc, id)) {
 +		if (igc_get_buf(rxr, id, true))
 +			break;
  	}
  
 -	id = igc_rxdesc_decr(sc, id);
 -	DPRINTF(RX, "%s RDT %d id %d\n",
 -	    rxr->last_desc_filled == id ? "same" : "diff",
 -	    rxr->last_desc_filled, id);
 -	rxr->last_desc_filled = id;
 -	IGC_WRITE_REG(&sc->hw, IGC_RDT(rxr->me), id);
 +        if (id != start) {
 +		int last = igc_rxdesc_decr(sc, id);
 +		DPRINTF(RX, "%s RDT %d last%d\n",
 +			rxr->last_desc_filled == last ? "same" : "diff",
 +			rxr->last_desc_filled, last);
 +		rxr->last_desc_filled = last;
 +		IGC_WRITE_REG(&sc->hw, IGC_RDT(rxr->me), last);
 +	}
 +
 +	return id != rxr->next_to_check;
 +}
 +
 +static void
 +igc_rxrefill_callout(void *callout_arg)
 +{
 +	struct rx_ring *rxr = callout_arg;
 +
 +	mutex_enter(&rxr->rxr_lock);
 +	if (igc_rxrefill(rxr))
 +		callout_schedule(&rxr->rx_refill, 1);
 +	mutex_exit(&rxr->rxr_lock);
  }
  
  /*********************************************************************
 @@ -2217,14 +2236,15 @@
  		id = igc_rxdesc_incr(sc, id);
  	}
  
 -	DPRINTF(RX, "fill queue[%d]\n", rxr->me);
 -	igc_rxrefill(rxr, id);
 -
  	DPRINTF(RX, "%s n2c %d id %d\n",
  	    rxr->next_to_check == id ? "same" : "diff",
  	    rxr->next_to_check, id);
  	rxr->next_to_check = id;
  
 +	DPRINTF(RX, "fill queue[%d]\n", rxr->me);
 +	if (igc_rxrefill(rxr))
 +		callout_schedule(&rxr->rx_refill, 1);
 +
  #ifdef OPENBSD
  	if (!(staterr & IGC_RXD_STAT_DD))
  		return 0;
 @@ -3555,6 +3575,9 @@
  {
  	struct igc_softc *sc = rxr->sc;
  
 +	callout_halt(&rxr->rx_refill, &rxr->rxr_lock);
 +	callout_destroy(&rxr->rx_refill);
 +
  	if (rxr->rx_buffers != NULL) {
  		for (int id = 0; id < sc->num_rx_desc; id++) {
  			struct igc_rx_buf *rxbuf = &rxr->rx_buffers[id];
 Index: if_igc.h
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/pci/igc/if_igc.h,v
 retrieving revision 1.3
 diff -u -r1.3 if_igc.h
 --- if_igc.h	27 Jun 2024 07:31:41 -0000	1.3
 +++ if_igc.h	23 May 2026 20:35:17 -0000
 @@ -40,6 +40,7 @@
  
  #include <sys/types.h>
  #include <sys/atomic.h>
 +#include <sys/callout.h>
  #include <sys/pcq.h>
  #include <sys/workqueue.h>
  
 @@ -315,6 +316,7 @@
  	struct if_rxring	rx_ring;
  #endif
  
 +	callout_t		rx_refill;
  	kmutex_t		rxr_lock;
  
  	struct igc_queue	*rxr_igcq;
 
 --jxm65gqetppbszrs--
 



Home | Main Index | Thread Index | Old Index