tech-net archive

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

Re: if_txtimer API to replace (*if_watchdog)()



Hi,

Sorry for my late reply.

On 2020/01/22 9:21, Jason Thorpe wrote:

On Jan 20, 2020, at 2:48 PM, Jason Thorpe <thorpej%me.com@localhost> wrote:

Folks --

The legacy (*if_watchdog)() interface has a couple of problems:

1- It does not have any way to represent multiple hardware-managed transmit queues.

2- It's not easy to make MP-safe because it relies on modifying the ifnet structure periodically outside of the normal locking mechanisms.

The wm(4) driver solved the problem in a reasonable way, and to make it easier for the other drivers in the tree to adopt it's strategy, I re-factored it into a new if_txtimer structure and API.

So save typing, I'll paste the relevant section of <net/if.h>:

I spent some time thinking about this a little more, especially around making it easier to convert drivers that don't have a periodic tick already (this is mainly drivers that don't use MII), so I added some extra support for such drivers and as a proof of concept, converted the SGI "sq" driver.  You can see that it's a very easy mechanical conversion for legacy drivers, that still gives them a simple NET_MPSAFE migration path (there's a provision for providing a tx queue interlock to the timer expiration callback).

If there is consensus that this is a reasonable direction, then I'll start migrating drivers and, when complete, remove the legacy (*if_watchdog)() and if_timer fields from struct ifnet.

Looks good for me.  Thank you for detailed comments.


Thanks,

For completeness, here's the big block comment:

/*
  * if_txtimer --
  *
  * Transmission timer (to replace the legacy ifnet watchdog timer).
  *
  * The driver should allocate one if_txtimer per hardware-managed
  * transmission queue.  There are two different ways to allocate
  * the and use the timer, based on the driver's structure.
  *
  * DRIVERS THAT PROVIDE THEIR OWN PERIODIC CALLOUT
  * ===============================================
  *
  * ==> Allocate timers using if_txtimer_alloc().
  * ==> In the periodic callout, check for txtimer expiration using
  *     if_txtimer_is_expired() or if_txtimer_is_expired_explicit()
  *     (see below).
  *
  * DRIVERS THAT DO NOT PROVIDE THEIR OWN PERIODIC CALLOUT
  * ======================================================
  *
  * ==> Allocate timers using if_txtimer_alloc_with_callback().
  *     This variant allocates a callout and provides a facility
  *     for the callout to invoke a driver-provided callack when
  *     the timer expires, with an optional interlock (typically
  *     the transmit queue mutex).
  *
  *     If an interlock is provided, the interlock will be acquired
  *     before checking for timer expiration, and will invoke the
  *     callback with the interlock held if the timer has expired.
  *     NOTE: the callback is responsible for releasing the interlock.
  *     If an interlock is NOT provided, then IPL will be raised to
  *     splnet() before checking for timer expiration and invoking
  *     the callback.  In this case, the IPL will be restored on
  *     the callback's behalf when it returns.
  * ==> In the driver's (*if_init)() routine, the timer's callout
  *     should be started with if_txtimer_start().  In the driver's
  *     (*if_stop)() routine, the timer's callout should be stopped
  *     with if_txtimer_stop() or if_txtimer_halt() (see callout(9)
  *     for the difference between stop and halt).
  *
  * In both cases, all locking of the if_txtimer is the responsibility
  * of the driver.  The if_txtimer should be protected by the same lock
  * that protects the associated transmission queue.  The queue
  * associated with the timer should be locked when arming and disarming
  * the timer and when checking the timer for expiration.
  *
  * When the driver gives packets to the hardware to transmit, it should
  * arm the timer by calling if_txtimer_arm().  When it is sweeping up
  * completed transmit jobs, it should disarm the timer by calling
  * if_txtimer_disarm() if there are no outstanding jobs remaining.
  *
  * If a driver needs to check multiple transmission queues, an
  * optimization is available that avoids repeated calls to fetch
  * the compare time.  In this case, the driver can get the compare
  * time by calling if_txtimer_now() and can check for timer expiration
  * using if_txtimer_is_expired_explicit().
  *
  * The granularity of the if_txtimer is 1 second.
  */




-- thorpej


--
//////////////////////////////////////////////////////////////////////
Internet Initiative Japan Inc.

Device Engineering Section,
Product Development Department,
Product Division,
Technology Unit

Kengo NAKAHARA <k-nakahara%iij.ad.jp@localhost>


Home | Main Index | Thread Index | Old Index