Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if_epair.c
Show First 20 Lines • Show All 191 Lines • ▼ Show 20 Lines | struct epair_dpcpu { | ||||
struct mtx if_epair_mtx; /* Per-CPU locking. */ | struct mtx if_epair_mtx; /* Per-CPU locking. */ | ||||
int epair_drv_flags; /* Per-CPU ``hw'' drv flags. */ | int epair_drv_flags; /* Per-CPU ``hw'' drv flags. */ | ||||
struct eid_list epair_ifp_drain_list; /* Per-CPU list of ifps with | struct eid_list epair_ifp_drain_list; /* Per-CPU list of ifps with | ||||
* data in the ifq. */ | * data in the ifq. */ | ||||
}; | }; | ||||
DPCPU_DEFINE(struct epair_dpcpu, epair_dpcpu); | DPCPU_DEFINE(struct epair_dpcpu, epair_dpcpu); | ||||
static void | static void | ||||
epair_clear_mbuf(struct mbuf *m) | |||||
{ | |||||
/* Remove any CSUM_SND_TAG as ether_input will barf. */ | |||||
if (m->m_pkthdr.csum_flags & CSUM_SND_TAG) { | |||||
m_snd_tag_rele(m->m_pkthdr.snd_tag); | |||||
m->m_pkthdr.snd_tag = NULL; | |||||
m->m_pkthdr.csum_flags &= ~CSUM_SND_TAG; | |||||
} | |||||
m_tag_delete_nonpersistent(m); | |||||
} | |||||
static void | |||||
epair_dpcpu_init(void) | epair_dpcpu_init(void) | ||||
{ | { | ||||
struct epair_dpcpu *epair_dpcpu; | struct epair_dpcpu *epair_dpcpu; | ||||
struct eid_list *s; | struct eid_list *s; | ||||
u_int cpuid; | u_int cpuid; | ||||
CPU_FOREACH(cpuid) { | CPU_FOREACH(cpuid) { | ||||
epair_dpcpu = DPCPU_ID_PTR(cpuid, epair_dpcpu); | epair_dpcpu = DPCPU_ID_PTR(cpuid, epair_dpcpu); | ||||
▲ Show 20 Lines • Show All 222 Lines • ▼ Show 20 Lines | for (;;) { | ||||
if ((oifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || | if ((oifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || | ||||
(oifp->if_flags & IFF_UP) ==0) { | (oifp->if_flags & IFF_UP) ==0) { | ||||
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | ||||
m_freem(m); | m_freem(m); | ||||
continue; | continue; | ||||
} | } | ||||
DPRINTF("packet %s -> %s\n", ifp->if_xname, oifp->if_xname); | DPRINTF("packet %s -> %s\n", ifp->if_xname, oifp->if_xname); | ||||
epair_clear_mbuf(m); | |||||
/* | /* | ||||
* Add a reference so the interface cannot go while the | * Add a reference so the interface cannot go while the | ||||
* packet is in transit as we rely on rcvif to stay valid. | * packet is in transit as we rely on rcvif to stay valid. | ||||
*/ | */ | ||||
EPAIR_REFCOUNT_AQUIRE(&sc->refcount); | EPAIR_REFCOUNT_AQUIRE(&sc->refcount); | ||||
m->m_pkthdr.rcvif = oifp; | m->m_pkthdr.rcvif = oifp; | ||||
CURVNET_SET_QUIET(oifp->if_vnet); | CURVNET_SET_QUIET(oifp->if_vnet); | ||||
bz: Not sure if the other review we were discussion already has this but in my working branch I… | |||||
error = netisr_queue(NETISR_EPAIR, m); | error = netisr_queue(NETISR_EPAIR, m); | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
if (!error) { | if (!error) { | ||||
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); | if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); | ||||
/* Someone else received the packet. */ | /* Someone else received the packet. */ | ||||
if_inc_counter(oifp, IFCOUNTER_IPACKETS, 1); | if_inc_counter(oifp, IFCOUNTER_IPACKETS, 1); | ||||
} else { | } else { | ||||
/* The packet was freed already. */ | /* The packet was freed already. */ | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | if (!error) { | ||||
epair_start_locked(ifp); | epair_start_locked(ifp); | ||||
else | else | ||||
(void)epair_add_ifp_for_draining(ifp); | (void)epair_add_ifp_for_draining(ifp); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
IF_UNLOCK(&ifp->if_snd); | IF_UNLOCK(&ifp->if_snd); | ||||
#endif | #endif | ||||
epair_clear_mbuf(m); | |||||
bzUnsubmitted Not Done Inline ActionsGiven you do the same in epair_start_locked() can we move the call down after the if() block below to save us a tiny little work in an already pressing situation? bz: Given you do the same in epair_start_locked() can we move the call down after the if() block… | |||||
if ((epair_dpcpu->epair_drv_flags & IFF_DRV_OACTIVE) != 0) { | if ((epair_dpcpu->epair_drv_flags & IFF_DRV_OACTIVE) != 0) { | ||||
/* | /* | ||||
* Our hardware queue is full, try to fall back | * Our hardware queue is full, try to fall back | ||||
* queuing to the ifq but do not call ifp->if_start. | * queuing to the ifq but do not call ifp->if_start. | ||||
* Either we are lucky or the packet is gone. | * Either we are lucky or the packet is gone. | ||||
*/ | */ | ||||
IFQ_ENQUEUE(&ifp->if_snd, m, error); | IFQ_ENQUEUE(&ifp->if_snd, m, error); | ||||
▲ Show 20 Lines • Show All 500 Lines • Show Last 20 Lines |
Not sure if the other review we were discussion already has this but in my working branch I also have (note: the code looks different so the surroundings are different):
I don't think m_tag_delete_nonpersistent() takes send tags into account?