Index: sys/kern/init_main.c =================================================================== --- sys/kern/init_main.c +++ sys/kern/init_main.c @@ -52,7 +52,6 @@ #include #include -#include #include #include #include @@ -511,7 +510,6 @@ td->td_pflags = TDP_KTHREAD; td->td_cpuset = cpuset_thread0(); td->td_domain.dr_policy = td->td_cpuset->cs_domain; - epoch_thread_init(td); prison0_init(); p->p_peers = 0; p->p_leader = p; Index: sys/kern/kern_thread.c =================================================================== --- sys/kern/kern_thread.c +++ sys/kern/kern_thread.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -273,7 +272,6 @@ td->td_rlqe = NULL; EVENTHANDLER_DIRECT_INVOKE(thread_init, td); umtx_thread_init(td); - epoch_thread_init(td); td->td_kstack = 0; td->td_sel = NULL; return (0); @@ -293,7 +291,6 @@ turnstile_free(td->td_turnstile); sleepq_free(td->td_sleepqueue); umtx_thread_fini(td); - epoch_thread_fini(td); seltdfini(td); } Index: sys/kern/subr_epoch.c =================================================================== --- sys/kern/subr_epoch.c +++ sys/kern/subr_epoch.c @@ -656,17 +656,3 @@ { return (in_epoch_verbose(epoch, 0)); } - -void -epoch_thread_init(struct thread *td) -{ - - td->td_et = malloc(sizeof(struct epoch_tracker), M_EPOCH, M_WAITOK); -} - -void -epoch_thread_fini(struct thread *td) -{ - - free(td->td_et, M_EPOCH); -} Index: sys/net/if.c =================================================================== --- sys/net/if.c +++ sys/net/if.c @@ -62,6 +62,8 @@ #include #include #include +#include +#include #include #include @@ -1758,6 +1760,30 @@ ifd->ifi_noproto = ifp->if_get_counter(ifp, IFCOUNTER_NOPROTO); } +struct ifnet_read_lock { + struct mtx mtx; /* lock protecting tracker below */ + struct epoch_tracker et; +}; + +DPCPU_DEFINE_STATIC(struct ifnet_read_lock, ifnet_addr_read_lock); +DPCPU_DEFINE_STATIC(struct ifnet_read_lock, ifnet_maddr_read_lock); + +static void +ifnet_read_lock_init(void __unused *arg) +{ + struct ifnet_read_lock *pifrl; + int cpu; + + CPU_FOREACH(cpu) { + pifrl = DPCPU_ID_PTR(cpu, ifnet_addr_read_lock); + mtx_init(&pifrl->mtx, "ifnet_addr_read_lock", NULL, MTX_DEF); + + pifrl = DPCPU_ID_PTR(cpu, ifnet_maddr_read_lock); + mtx_init(&pifrl->mtx, "ifnet_maddr_read_lock", NULL, MTX_DEF); + } +} +SYSINIT(ifnet_read_lock_init, SI_SUB_CPU + 1, SI_ORDER_FIRST, &ifnet_read_lock_init, NULL); + /* * Wrapper functions for struct ifnet address list locking macros. These are * used by kernel modules to avoid encoding programming interface or binary @@ -1767,29 +1793,47 @@ void if_addr_rlock(struct ifnet *ifp) { + struct ifnet_read_lock *pifrl; - epoch_enter_preempt(net_epoch_preempt, curthread->td_et); + sched_pin(); + pifrl = DPCPU_PTR(ifnet_addr_read_lock); + mtx_lock(&pifrl->mtx); + epoch_enter_preempt(net_epoch_preempt, &pifrl->et); } void if_addr_runlock(struct ifnet *ifp) { + struct ifnet_read_lock *pifrl; - epoch_exit_preempt(net_epoch_preempt, curthread->td_et); + pifrl = DPCPU_PTR(ifnet_addr_read_lock); + + epoch_exit_preempt(net_epoch_preempt, &pifrl->et); + mtx_unlock(&pifrl->mtx); + sched_unpin(); } void if_maddr_rlock(if_t ifp) { + struct ifnet_read_lock *pifrl; - epoch_enter_preempt(net_epoch_preempt, curthread->td_et); + sched_pin(); + pifrl = DPCPU_PTR(ifnet_maddr_read_lock); + mtx_lock(&pifrl->mtx); + epoch_enter_preempt(net_epoch_preempt, &pifrl->et); } void if_maddr_runlock(if_t ifp) { + struct ifnet_read_lock *pifrl; - epoch_exit_preempt(net_epoch_preempt, curthread->td_et); + pifrl = DPCPU_PTR(ifnet_maddr_read_lock); + + epoch_exit_preempt(net_epoch_preempt, &pifrl->et); + mtx_unlock(&pifrl->mtx); + sched_unpin(); } /* Index: sys/sys/epoch.h =================================================================== --- sys/sys/epoch.h +++ sys/sys/epoch.h @@ -82,8 +82,5 @@ void epoch_enter(epoch_t epoch); void epoch_exit(epoch_t epoch); -void epoch_thread_init(struct thread *); -void epoch_thread_fini(struct thread *); - #endif /* _KERNEL */ #endif /* _SYS_EPOCH_H_ */ Index: sys/sys/proc.h =================================================================== --- sys/sys/proc.h +++ sys/sys/proc.h @@ -193,7 +193,6 @@ struct turnstile; struct vm_map; struct vm_map_entry; -struct epoch_tracker; /* * XXX: Does this belong in resource.h or resourcevar.h instead? @@ -361,7 +360,6 @@ int td_lastcpu; /* (t) Last cpu we were on. */ int td_oncpu; /* (t) Which cpu we are on. */ void *td_lkpi_task; /* LinuxKPI task struct pointer */ - struct epoch_tracker *td_et; /* (k) compat KPI spare tracker */ int td_pmcpend; };