Hold GIF_LOCK() for almost all of gif_start(). It is required to be held
across in_gif_output() and in6_gif_output() anyway, and once it is held across those it might as well be held for the entire loop. This simplifies the code and removes the need for the custom IFF_GIF_WANTED flag (which belonged in the softc and not as an IFF_* flag anyway). Tested by: Vincent Hoffman vince unsane co uk
This commit is contained in:
parent
436f647402
commit
304050dde0
@ -153,7 +153,6 @@ struct if_data {
|
||||
#define IFF_STATICARP 0x80000 /* (n) static ARP */
|
||||
#define IFF_DYING 0x200000 /* (n) interface is winding down */
|
||||
#define IFF_RENAMING 0x400000 /* (n) interface is being renamed */
|
||||
#define IFF_GIF_WANTED 0x1000000 /* (n) The gif tunnel is wanted */
|
||||
/*
|
||||
* Old names for driver flags so that user space tools can continue to use
|
||||
* the old (portable) names.
|
||||
|
@ -359,15 +359,7 @@ gif_start(struct ifnet *ifp)
|
||||
|
||||
sc = ifp->if_softc;
|
||||
GIF_LOCK(sc);
|
||||
if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
|
||||
/* Already active */
|
||||
ifp->if_drv_flags |= IFF_GIF_WANTED;
|
||||
GIF_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||
GIF_UNLOCK(sc);
|
||||
keep_going:
|
||||
while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
|
||||
|
||||
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
|
||||
@ -424,16 +416,6 @@ gif_start(struct ifnet *ifp)
|
||||
ifp->if_oerrors++;
|
||||
|
||||
}
|
||||
GIF_LOCK(sc);
|
||||
if (ifp->if_drv_flags & IFF_GIF_WANTED) {
|
||||
/* Someone did a start while
|
||||
* we were unlocked and processing
|
||||
* lets clear the flag and try again.
|
||||
*/
|
||||
ifp->if_drv_flags &= ~IFF_GIF_WANTED;
|
||||
GIF_UNLOCK(sc);
|
||||
goto keep_going;
|
||||
}
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
GIF_UNLOCK(sc);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user