kern/64975: [PATCH] rl driver with polling enabled increase TX counters at each clock tick

artis at fbsd.lv artis at fbsd.lv
Wed Mar 31 00:10:18 PST 2004


>Number:         64975
>Category:       kern
>Synopsis:       [PATCH] rl driver with polling enabled increase TX counters at each clock tick
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Mar 31 00:10:17 PST 2004
>Closed-Date:
>Last-Modified:
>Originator:     Artis Caune
>Release:        FreeBSD 5.2.1-RELEASE-p3 i386
>Organization:
>Environment:
System: FreeBSD fbsd.lv 5.2.1-RELEASE-p3 FreeBSD 5.2.1-RELEASE-p3 #0: Thu Mar 18 13:01:46 EET 2004 root at fbsd.lv:/usr/obj/usr/src/sys/KERNEL i386

>Description:
	When device polling is enabled on rl interface, TX counters are
increased at every 'rl_poll() -> rl_txeof()' function call (at each clock tick).
When working in interupt mode, rl_txeof is called only when device needs atention
and it works correctly.
Actually with polling enabled I got ~600000 outgoing packets and ~15% CPU in interupts.

sys/pci/if_rl.c code is not very efficient: at every rl_poll() call
driver is doing while loop 4 times(4 TX rings?) and no meter what, it always update
    ifp->if_opackets++;
    ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24;
    ifp->if_flags &= ~IFF_OACTIVE;
So at every clock tick we update those counters 4 times

Same problem on 4.x and 5.x

This patch will only fix counter problem, not wasted CPU times!!!

p.s. this was PR misc/64690

>How-To-Repeat:
	recompile and run kernel with polling enabled and rl interface
>Fix:

--- if_rl.patch begins here ---
*** sys/pci/if_rl.c.orig	Fri Nov 28 07:28:29 2003
--- sys/pci/if_rl.c	Wed Mar 31 10:15:34 2004
***************
*** 1373,1386 ****
  		ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24;
  
  		if (RL_LAST_TXMBUF(sc) != NULL) {
  			bus_dmamap_unload(sc->rl_tag, RL_LAST_DMAMAP(sc));
  			bus_dmamap_destroy(sc->rl_tag, RL_LAST_DMAMAP(sc));
  			m_freem(RL_LAST_TXMBUF(sc));
  			RL_LAST_TXMBUF(sc) = NULL;
  		}
! 		if (txstat & RL_TXSTAT_TX_OK)
! 			ifp->if_opackets++;
! 		else {
  			int			oldthresh;
  			ifp->if_oerrors++;
  			if ((txstat & RL_TXSTAT_TXABRT) ||
--- 1373,1385 ----
  		ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24;
  
  		if (RL_LAST_TXMBUF(sc) != NULL) {
+ 			ifp->if_opackets++;
  			bus_dmamap_unload(sc->rl_tag, RL_LAST_DMAMAP(sc));
  			bus_dmamap_destroy(sc->rl_tag, RL_LAST_DMAMAP(sc));
  			m_freem(RL_LAST_TXMBUF(sc));
  			RL_LAST_TXMBUF(sc) = NULL;
  		}
! 		if (!(txstat & RL_TXSTAT_TX_OK)) {
  			int			oldthresh;
  			ifp->if_oerrors++;
  			if ((txstat & RL_TXSTAT_TXABRT) ||
--- if_rl.patch ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list