Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if.c
Show First 20 Lines • Show All 604 Lines • ▼ Show 20 Lines | #endif /* MAC */ | ||||
for (int i = 0; i < IFCOUNTERS; i++) | for (int i = 0; i < IFCOUNTERS; i++) | ||||
counter_u64_free(ifp->if_counters[i]); | counter_u64_free(ifp->if_counters[i]); | ||||
free(ifp, M_IFNET); | free(ifp, M_IFNET); | ||||
} | } | ||||
static void | static void | ||||
if_destroy(epoch_context_t ctx) | if_destroy(epoch_context_t *ctx) | ||||
{ | { | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
ifp = __containerof(ctx, struct ifnet, if_epoch_ctx); | ifp = __containerof(ctx, struct ifnet, if_epoch_ctx); | ||||
if_free_internal(ifp); | if_free_internal(ifp); | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 1,137 Lines • ▼ Show 20 Lines | |||||
* Wrapper functions for struct ifnet address list locking macros. These are | * Wrapper functions for struct ifnet address list locking macros. These are | ||||
* used by kernel modules to avoid encoding programming interface or binary | * used by kernel modules to avoid encoding programming interface or binary | ||||
* interface assumptions that may be violated when kernel-internal locking | * interface assumptions that may be violated when kernel-internal locking | ||||
* approaches change. | * approaches change. | ||||
*/ | */ | ||||
void | void | ||||
if_addr_rlock(struct ifnet *ifp) | if_addr_rlock(struct ifnet *ifp) | ||||
{ | { | ||||
MPASS(*(uint64_t *)&ifp->if_addr_et == 0); | |||||
epoch_enter_preempt(net_epoch_preempt, &ifp->if_addr_et); | epoch_enter_preempt(net_epoch_preempt, curthread->td_et); | ||||
markj: I'm surprised by this - what prevented multiple readers from sharing the tracker? | |||||
markjUnsubmitted Not Done Inline ActionsNothing is preventing curthread->td_et from being reused in a nested context. We should panic if that happens, at the very least. markj: Nothing is preventing curthread->td_et from being reused in a nested context. We should panic… | |||||
} | } | ||||
void | void | ||||
if_addr_runlock(struct ifnet *ifp) | if_addr_runlock(struct ifnet *ifp) | ||||
{ | { | ||||
epoch_exit_preempt(net_epoch_preempt, &ifp->if_addr_et); | |||||
#ifdef INVARIANTS | epoch_exit_preempt(net_epoch_preempt, curthread->td_et); | ||||
bzero(&ifp->if_addr_et, sizeof(struct epoch_tracker)); | |||||
#endif | |||||
} | } | ||||
void | void | ||||
if_maddr_rlock(if_t ifp) | if_maddr_rlock(if_t ifp) | ||||
{ | { | ||||
MPASS(*(uint64_t *)&ifp->if_maddr_et == 0); | epoch_enter_preempt(net_epoch_preempt, curthread->td_et); | ||||
epoch_enter_preempt(net_epoch_preempt, &ifp->if_maddr_et); | |||||
} | } | ||||
void | void | ||||
if_maddr_runlock(if_t ifp) | if_maddr_runlock(if_t ifp) | ||||
{ | { | ||||
epoch_exit_preempt(net_epoch_preempt, &ifp->if_maddr_et); | epoch_exit_preempt(net_epoch_preempt, curthread->td_et); | ||||
#ifdef INVARIANTS | |||||
bzero(&ifp->if_maddr_et, sizeof(struct epoch_tracker)); | |||||
#endif | |||||
} | } | ||||
/* | /* | ||||
* Initialization, destruction and refcounting functions for ifaddrs. | * Initialization, destruction and refcounting functions for ifaddrs. | ||||
*/ | */ | ||||
struct ifaddr * | struct ifaddr * | ||||
ifa_alloc(size_t size, int flags) | ifa_alloc(size_t size, int flags) | ||||
{ | { | ||||
Show All 33 Lines | |||||
void | void | ||||
ifa_ref(struct ifaddr *ifa) | ifa_ref(struct ifaddr *ifa) | ||||
{ | { | ||||
refcount_acquire(&ifa->ifa_refcnt); | refcount_acquire(&ifa->ifa_refcnt); | ||||
} | } | ||||
static void | static void | ||||
ifa_destroy(epoch_context_t ctx) | ifa_destroy(epoch_context_t *ctx) | ||||
{ | { | ||||
struct ifaddr *ifa; | struct ifaddr *ifa; | ||||
ifa = __containerof(ctx, struct ifaddr, ifa_epoch_ctx); | ifa = __containerof(ctx, struct ifaddr, ifa_epoch_ctx); | ||||
counter_u64_free(ifa->ifa_opackets); | counter_u64_free(ifa->ifa_opackets); | ||||
counter_u64_free(ifa->ifa_ipackets); | counter_u64_free(ifa->ifa_ipackets); | ||||
counter_u64_free(ifa->ifa_obytes); | counter_u64_free(ifa->ifa_obytes); | ||||
counter_u64_free(ifa->ifa_ibytes); | counter_u64_free(ifa->ifa_ibytes); | ||||
▲ Show 20 Lines • Show All 1,580 Lines • ▼ Show 20 Lines | #ifdef MCAST_VERBOSE | ||||
kdb_backtrace(); | kdb_backtrace(); | ||||
printf("%s freeing ifma: %p\n", __func__, ifma); | printf("%s freeing ifma: %p\n", __func__, ifma); | ||||
#endif | #endif | ||||
free(ifma->ifma_addr, M_IFMADDR); | free(ifma->ifma_addr, M_IFMADDR); | ||||
free(ifma, M_IFMADDR); | free(ifma, M_IFMADDR); | ||||
} | } | ||||
static void | static void | ||||
if_destroymulti(epoch_context_t ctx) | if_destroymulti(epoch_context_t *ctx) | ||||
{ | { | ||||
struct ifmultiaddr *ifma; | struct ifmultiaddr *ifma; | ||||
ifma = __containerof(ctx, struct ifmultiaddr, ifma_epoch_ctx); | ifma = __containerof(ctx, struct ifmultiaddr, ifma_epoch_ctx); | ||||
if_freemulti_internal(ifma); | if_freemulti_internal(ifma); | ||||
} | } | ||||
void | void | ||||
▲ Show 20 Lines • Show All 1,140 Lines • Show Last 20 Lines |
I'm surprised by this - what prevented multiple readers from sharing the tracker?