From d552b6fe480d4086e05aa88c4bcf23baf0c470a3 Mon Sep 17 00:00:00 2001 From: rwatson Date: Tue, 22 Feb 2005 14:20:29 +0000 Subject: [PATCH] Convert the aa_ifaddr timeout to a callout, and run the aarprobe callout MPSAFE. Acquire the aarptab_mtx to make sure that the callout and msleep in the ioctl thread don't race. MFC after: 1 week --- sys/netatalk/aarp.c | 17 ++++++++--------- sys/netatalk/at_control.c | 12 ++++++++---- sys/netatalk/at_extern.h | 7 +++++++ sys/netatalk/at_var.h | 2 +- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/sys/netatalk/aarp.c b/sys/netatalk/aarp.c index bdff6afc977d..7e0c96a0bbec 100644 --- a/sys/netatalk/aarp.c +++ b/sys/netatalk/aarp.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Robert N. M. Watson + * Copyright (c) 2004-2005 Robert N. M. Watson * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -82,14 +82,9 @@ static void at_aarpinput(struct ifnet *ifp, struct mbuf *m); #define AARPTAB_SIZE (AARPTAB_BSIZ * AARPTAB_NB) static struct aarptab aarptab[AARPTAB_SIZE]; -static struct mtx aarptab_mtx; +struct mtx aarptab_mtx; MTX_SYSINIT(aarptab_mtx, &aarptab_mtx, "aarptab_mtx", MTX_DEF); -#define AARPTAB_LOCK() mtx_lock(&aarptab_mtx) -#define AARPTAB_UNLOCK() mtx_unlock(&aarptab_mtx) -#define AARPTAB_LOCK_ASSERT() mtx_assert(&aarptab_mtx, MA_OWNED) -#define AARPTAB_UNLOCK_ASSERT() mtx_assert(&aarptab_mtx, MA_NOTOWNED) - #define AARPTAB_HASH(a) \ ((((a).s_net << 8) + (a).s_node) % AARPTAB_NB) @@ -418,7 +413,7 @@ at_aarpinput(struct ifnet *ifp, struct mbuf *m) * probed for the same address we'd like to use. Change the * address we're probing for. */ - untimeout(aarpprobe, ifp, aa->aa_ch); + callout_stop(&aa->aa_callout); wakeup(aa); m_freem(m); return; @@ -593,6 +588,7 @@ aarpprobe(void *arg) * interface with the same address as we're looking for. If the * net is phase 2, generate an 802.2 and SNAP header. */ + AARPTAB_LOCK(); for (aa = (struct at_ifaddr *)TAILQ_FIRST(&ifp->if_addrhead); aa; aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) { if (AA_SAT(aa)->sat_family == AF_APPLETALK && @@ -601,6 +597,7 @@ aarpprobe(void *arg) } } if (aa == NULL) { /* serious error XXX */ + AARPTAB_UNLOCK(); printf("aarpprobe why did this happen?!\n"); return; } @@ -608,10 +605,12 @@ aarpprobe(void *arg) if (aa->aa_probcnt <= 0) { aa->aa_flags &= ~AFA_PROBING; wakeup(aa); + AARPTAB_UNLOCK(); return; } else { - aa->aa_ch = timeout(aarpprobe, (caddr_t)ifp, hz / 5); + callout_reset(&aa->aa_callout, hz / 5, aarpprobe, ifp); } + AARPTAB_UNLOCK(); if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) { return; diff --git a/sys/netatalk/at_control.c b/sys/netatalk/at_control.c index d24edc43e434..4dc0a716a80f 100644 --- a/sys/netatalk/at_control.c +++ b/sys/netatalk/at_control.c @@ -158,6 +158,7 @@ at_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, if (aa == NULL) { aa0 = malloc(sizeof(struct at_ifaddr), M_IFADDR, M_WAITOK | M_ZERO); + callout_init(&aa0->aa_callout, CALLOUT_MPSAFE); if ((aa = at_ifaddr_list) != NULL) { /* * Don't let the loopback be first, since the @@ -517,10 +518,12 @@ at_ifinit(struct ifnet *ifp, struct at_ifaddr *aa, struct sockaddr_at *sat) * start off the probes as an asynchronous * activity. though why wait 200mSec? */ - aa->aa_ch = timeout(aarpprobe, (caddr_t)ifp, - hz / 5); - if (tsleep(aa, PPAUSE|PCATCH, "at_ifinit", - 0)) { + AARPTAB_LOCK(); + callout_reset(&aa->aa_callout, hz / 5, + aarpprobe, ifp); + if (msleep(aa, &aarptab_mtx, PPAUSE|PCATCH, + "at_ifinit", 0)) { + AARPTAB_UNLOCK(); /* * theoretically we shouldn't time * out here so if we returned with an @@ -533,6 +536,7 @@ at_ifinit(struct ifnet *ifp, struct at_ifaddr *aa, struct sockaddr_at *sat) aa->aa_lastnet = onr.nr_lastnet; return (EINTR); } + AARPTAB_UNLOCK(); /* * The async activity should have woken us diff --git a/sys/netatalk/at_extern.h b/sys/netatalk/at_extern.h index c2daf263f075..58ceb8d6e814 100644 --- a/sys/netatalk/at_extern.h +++ b/sys/netatalk/at_extern.h @@ -35,6 +35,13 @@ extern int aarpresolve (struct ifnet *, struct sockaddr_at *, u_char *); extern int at_broadcast (struct sockaddr_at *); + +extern struct mtx aarptab_mtx; + +#define AARPTAB_LOCK() mtx_lock(&aarptab_mtx) +#define AARPTAB_UNLOCK() mtx_unlock(&aarptab_mtx) +#define AARPTAB_LOCK_ASSERT() mtx_assert(&aarptab_mtx, MA_OWNED) +#define AARPTAB_UNLOCK_ASSERT() mtx_assert(&aarptab_mtx, MA_NOTOWNED) #endif #ifdef _NETATALK_AARP_H_ diff --git a/sys/netatalk/at_var.h b/sys/netatalk/at_var.h index e0eb0eddab8a..fa4e69d81efa 100644 --- a/sys/netatalk/at_var.h +++ b/sys/netatalk/at_var.h @@ -39,7 +39,7 @@ struct at_ifaddr { int aa_flags; u_short aa_firstnet, aa_lastnet; int aa_probcnt; - struct callout_handle aa_ch; + struct callout aa_callout; struct at_ifaddr *aa_next; };