Commit Graph

294711 Commits

Author SHA1 Message Date
riastradh 5c509362df usbnet drivers: Omit needless usbnet core lock and assertions.
During attach, the caller has exclusive access to the usbnet until
usbnet_attach_ifp.  At other times, register access is serialized
either by the usbnet multicast lock or by IFNET_LOCK.
2022-03-03 05:54:37 +00:00
riastradh 47bf81df8f usbnet: Make usbnet_mii_readreg/writereg/statchg private to usbnet.c.
No drivers need to use these.
2022-03-03 05:54:28 +00:00
riastradh 9e1fa980c8 usbnet drivers: Avoid undefined behaviour if read reg fails.
Some callers don't check the error code, e.g. ~all the mii phy
drivers using PHY_READ.  Just return zero if the device is gone or
the xfer fails for any other reason.
2022-03-03 05:54:21 +00:00
riastradh 8cf9a9747f axen(4): Use axen mii read/write reg routines, not usbnet ones.
The usbnet wrappers don't add anything important.  We already test
usbnet_isdying in axen_cmd, and that's already a best-effort thing
(which should probably be done better by having usbd_do_request fail
promptly if detaching anyway).
2022-03-03 05:54:11 +00:00
riastradh bb5afa0974 usbnet drivers: Assert IFNET_LOCKED in if ioctl routines.
These only happen either during the transition up or down (init or
stop), or while that transition is excluded (ioctl).

This may be called from ioctl or from init, which both hold the ifnet
lock.

XXX smsc_setoe_locked should maybe trigger reinit because the rx loop
behaves differently depending on whether checksumming is enabled.

XXX mue_sethwcsum_locked needs to exclude mcast updates.
2022-03-03 05:54:03 +00:00
riastradh 4295ae1b78 udav(4): Stop asserting !usbnet_isdying.
This can change at any moment; no software lock can prevent the
device from being detached.  Any test of it is necessarily
best-effort just to avoid wasting time later on waiting for requests
to fail or time out.
2022-03-03 05:53:56 +00:00
riastradh c9221c8403 aue(4): Simplify. No functional change. 2022-03-03 05:53:48 +00:00
riastradh 0e793ef4b9 aue(4): Enable rx/tx registers on init before usbnet_init_rx_tx.
This way, we still have exclusive access to the registers before
calls to aue_uno_mcast can start happening without the usbnet core
lock.
2022-03-03 05:53:41 +00:00
riastradh 2d75ebfa29 usbnet drivers: Omit redundant multicast filter update on init. 2022-03-03 05:53:33 +00:00
riastradh f59d8c9753 usbnet: Apply hardware multicast filter updates synchronously again.
To make this work:

1. Do it only under a new lock, unp_mcastlock.  This lock lives at
   IPL_SOFTCLOCK so it can be taken from network stack callouts.  It
   is forbidden to acquire the usbnet core lock under unp_mcastlock.

2. Do it only after usbnet_init_rx_tx and before usbnet_stop; if
   issued at any other time, drop the update on the floor.

3. Make usbnet_init_rx_tx apply any pending multicast filter updates
   under the lock before setting the flag that allows SIOCADDMULTI or
   SIOCDELMULTI to apply the updates.

4. Remove core lock asserts from various drivers' register access
   routines.  This is necessary because the multicast filter updates
   are done with register reads/writes, but _cannot_ take the core
   lock when the caller holds softnet_lock.

This now programs the hardware multicast filter redundantly in many
drivers which already explicitly call *_uno_mcast from the *_uno_init
routines.  This is probably harmless, but it will likely be better to
remove the explicit calls.
2022-03-03 05:53:23 +00:00
riastradh 4f98063591 usbnet drivers: Stop abusing ifp->if_flags & IFF_ALLMULTI.
This legacy flag is a figment of userland's imagination.  The actual
kernel state is ec->ec_flags & ETHER_F_ALLMULTI, protected by the
ETHER_LOCK, so that multicast filter updates -- which run without
IFNET_LOCK -- need not attempt to write racily to ifp->if_flags.
2022-03-03 05:53:14 +00:00
riastradh 2a987a0a95 usbnet drivers: Omit needless uno_mcast locked subroutines.
uno_mcast is now called with the core lock already held so there is
no need for a separate locked subroutine.
2022-03-03 05:53:04 +00:00
riastradh cb0d28a94d aue(4): Reduce aue_uno_mcast from aue_uno_init to aue_setiff_locked.
This operation only needs to update the hardware to reflect
SIOCADDMULTI/SIOCDELMULTI.  Not clear that everything in aue(4) needs
to be reset -- in fact I'm pretty sure that's undesirable!

WARNING: I have not tested this with a real aue(4) device.
2022-03-03 05:52:55 +00:00
riastradh c499beaef1 usbnet: Take the core lock around uno_mcast.
Every driver does this already.  This will enable us to change the
lock that serializes access to the registers so we can go back to
doing this synchronously in SIOCADDMULTI/SIOCDELMULTI.
2022-03-03 05:52:46 +00:00
riastradh 1da4c1563d usbnet drivers: Omit needless uno_init locked subroutines.
uno_init is now called with the core lock already held so there is no
need for a separate locked subroutine.
2022-03-03 05:52:35 +00:00
riastradh 751cff0160 usbnet: No need for the core lock in usbnet_ifflags_cb.
The only state this touches is unp_if_flags, and all paths touching
it also hold IFNET_LOCK -- not to mention this is the only path that
touches unp_if_flags in the first place!
2022-03-03 05:52:27 +00:00
riastradh 5c872ef115 usbnet: Make the tx/rx locks private to usbnet.c.
Suffice it for the drivers to know that uno_tx_prepare and
uno_rx_loop have exclusive access to the chain, and, for tx,
exclusive access to the mbuf.
2022-03-03 05:52:20 +00:00
riastradh 62449b2057 usbnet: usbnet_busy is no longer referenced; release it! 2022-03-03 05:52:11 +00:00
riastradh c4fe84699e usbnet: No need for usbnet_busy in mii callbacks.
After mii_detach, these have all completed and no new ones can be
made, and detach doesn't start destroying anything until after
mii_detach has returned, so there is no need to hang onto a reference
count here.
2022-03-03 05:52:03 +00:00
riastradh 8b5b750b9f usbnet: No need for usbnet_busy in usbnet_init_rx_tx or usbnet_stop.
These run with IFNET_LOCK held, and the interface cannot be detached
until the IFNET_LOCK is released, so there is no need to hang onto a
reference count here.
2022-03-03 05:51:56 +00:00
riastradh 8b61d7e2b9 usbnet drivers: No need for usbnet_busy during attach.
usbnet_detach cannot run until the attach routine has finished
(unless a driver goes out of its way to tie its shoelaces together
and explicitly call it during the attach routine, which none of them
do), so there is no need to hang onto a reference count that we
release before attach returns.
2022-03-03 05:51:44 +00:00
riastradh ea9ce4a6d7 usbnet drivers: No need for usbnet_busy in uno_ioctl.
This callback always runs with the IFNET_LOCK held, and the interface
cannot be detached until the IFNET_LOCK is released, so there is no
need to hang onto a reference count here.  (None of the subnet
drivers touch the IFNET_LOCK except to verify it is held sometimes.)
2022-03-03 05:51:35 +00:00
riastradh 23fe390cac usbnet drivers: No need for usbnet_busy in uno_mcast.
This callback always runs with IFNET_LOCK held, and during a task
that usbnet_detach prevents scheduling anew and waits for finishing
before completing the detach, so there is no need to hang onto a
reference count here.
2022-03-03 05:51:27 +00:00
riastradh 9cfb26a542 usbnet drivers: No need for usbnet_busy in uno_init.
This callback always runs with the IFNET_LOCK held, and the interface
cannot be detached until the IFNET_LOCK is released, so there is no
need to hang onto a reference count here.  (None of the usbnet
drivers touch the IFNET_LOCK except to verify it is held sometimes.)
2022-03-03 05:51:17 +00:00
riastradh d9c770e700 usbnet: Split multicast filter reprogramming into separate operation. 2022-03-03 05:51:06 +00:00
riastradh 7f15b7014c usbnet drivers: Stop timeout loops early if device is detaching. 2022-03-03 05:50:57 +00:00
riastradh 839d7b202a usbnet: Omit needless locking around usbnet_isdying.
Now that is tested and set with atomic_load/store, there is no need
to hold the lock -- which means we can set it while the core lock is
held during, e.g., a reset sequence, and use that to interrupt the
sequence so it doesn't get stuck waiting to time out when the device
is physically removed.
2022-03-03 05:50:47 +00:00
riastradh 4c7e9da15d usbnet: Use atomic_load/store_relaxed for unp_dying.
This way we don't need to hold the core lock to avoid upsetting
sanitizers (which probably find the current code upsetting), and we
can use it to exit early from timeout loops that run under the core
lock (which is probably not necessary for them to do anyway, but
let's worry about that later).
2022-03-03 05:50:39 +00:00
riastradh ad98cb4e29 usbnet: Print diagnostic about refcnt stragglers.
I don't think there can be any, but this message, if printed, would
falsify my hypothesis!
2022-03-03 05:50:31 +00:00
riastradh 2cb1302a9a usbnet: Enter uno_init with the core lock held.
This reduces code in all drivers except urndis(4) and aue(4).

However, it's still safe for urndis to drop the core lock because the
ifnet is locked, and the ifnet lock covers the DOWN->UP (uno_init)
and UP->DOWN (uno_stop) transitions.
2022-03-03 05:50:22 +00:00
riastradh d8ab860341 usbnet: Assert ioctl locking. 2022-03-03 05:50:12 +00:00
riastradh a2ab7acfd5 usbnet: Impart blame on whose ifnet is unlocked in uno_init. 2022-03-03 05:50:05 +00:00
riastradh 42232f3bdc usbnet: Don't waste time calling uno_stop if device is detaching.
The hardware is most likely gone, so trying to write to its registers
(and, in some cases, wait until a timeout for a device to reset) is a
waste of time.  Even if it was detached only in software with drvctl,
reattaching it will reset the device anyway.
2022-03-03 05:49:58 +00:00
riastradh 59c4aff91f cue(4): Return real error code, not -1, on init when detaching. 2022-03-03 05:49:51 +00:00
riastradh d7d8fa7bb7 usbnet: Avoid IFNET_LOCK on detach if we never attached the ifp. 2022-03-03 05:49:44 +00:00
riastradh 5a426bee10 usbnet: Clear watchdog timer before stopping hardware.
No need to take the lock again -- which might not be necessary
because the callout and task have completed, but let's obviate the
need to think about that.
2022-03-03 05:49:37 +00:00
riastradh 4edd6c2299 usbnet: Omit needless locking/busying/testing in usbnet_tick_task.
usbnet_stop waits for the task to complete before resetting the
hardware, and usbnet_detach waits for usbnet_stop to complete before
destroying anything, so there's no need for any of this.
2022-03-03 05:49:29 +00:00
riastradh 1995b67805 usbnet: Omit needless tests in usbnet_tick.
It's harmless for us to schedule the tick task even if unp_dying or
unp_stopping is set by now, because usbnet_stop will just wait for it
to finish anyway, and the callout can't be scheduled again until the
interface is done stopping and is brought back up again.

No need for unp == NULL test -- un->un_pri is initialized well before
this callout can be scheduled, and is nulled out only at the end of
usbnet_detach, at which point we have already halted this callout.
2022-03-03 05:49:22 +00:00
riastradh 329b5b66ad usbnet: Uncomment and fix assertion for ifp->if_flags |= IFF_RUNNING.
We always hold IFNET_LOCK for ioctls that end up here -- the ones
that don't hold it are only SIOCADDMULTI/SIOCDELMULTI, which don't
end up here.  However, urndis(4) throws a spanner in the works by
doing weird device initialization.
2022-03-03 05:49:14 +00:00
riastradh 486844a43a usbnet: Don't issue a detach event if we never issued an attach one. 2022-03-03 05:49:07 +00:00
riastradh 313c62bb2b usbnet: Make detach order reverse attach order, for unp_stat_ch.
No functional change intended.
2022-03-03 05:49:00 +00:00
riastradh 719b8cc5f1 usbnet: Detach interface and mii before waiting for refcnt to drain.
All outstanding software activity under usbnet's control -- which is
all that participates in the refcnting -- should be quiesced by
stopping and detaching everything.
2022-03-03 05:48:52 +00:00
riastradh c0ae7fcc64 usbnet: Omit needless callout_halt and usb_rem_task_wait.
The callout and tasks cannot be pending at this point -- it is a bug
if usbnet_if_stop failed to quiesce everything, so turn these into
KASSERTs.
2022-03-03 05:48:45 +00:00
riastradh fd68bbd03a usbnet: Refuse to bring interfaces back up once dying.
Make this happen uniformly across all usbnet drivers, not on a
per-driver basis.

This ensures new activity on the interface can't happen by the time
we have stopped existing activity and waited for it to complete.
2022-03-03 05:48:37 +00:00
riastradh 36ee3f20ab usbnet: Assert IFNET_LOCKED in usbnet_media_upd.
This ensures, if the device is being initialized or stopped,
usbnet_media_upd will not run until it's done, so the reset sequence
has exclusive access to the device registers used by mii.
2022-03-03 05:48:30 +00:00
riastradh d9ce0ea7ad usbnet: Fix ordering of actions in usbnet_stop.
Make sure all software activity is quiescent (callouts and tasks,
including ifmedia and mii callbacks -- anything that might trigger
register access) before asking the driver to stop the hardware.  This
way, the driver uno_stop routine is guaranteed exclusive access to
the registers.

This will also enable us to simplify the callouts and tasks so they
don't have to check the software state -- to be done in a separate
commit.
2022-03-03 05:48:22 +00:00
riastradh 0bada8de69 usbnet: Remove usbnet_set_dying.
Not necessary for the one caller that did it (url(4)): usbnet_detach
handles failed attach just fine without it.
2022-03-03 05:48:14 +00:00
riastradh d7781aff9e axen(4), mue(4), smsc(4): Omit irrelevant cases in ioctl.
SIOCSIFFLAGS and SIOCSETHERCAP always end up in ether_ioctl_reinit,
which triggers the same logic to reprogram the multicast filters
anyway.
2022-03-03 05:48:06 +00:00
riastradh aa6a453cd9 usbnet: Omit needless unp == NULL test in usbnet_tick_task.
The task is never scheduled until after un->un_pri is initialized,
and un->un_pri isn't nulled until after the callout and task are
quiescent.
2022-03-03 05:47:58 +00:00
riastradh 86170d4c99 usbnet: Don't check if_flags for IFF_RUNNING in usbnet_pipe_intr.
The one user of this interface in tree, aue(4), doesn't care --
if_statinc is safe whether IFF_RUNNING or not.
2022-03-03 05:47:50 +00:00