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
This commit is contained in:
rwatson 2005-02-22 14:20:29 +00:00
parent cd21b2e10c
commit d552b6fe48
4 changed files with 24 additions and 14 deletions

View File

@ -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;

View File

@ -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

View File

@ -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_

View File

@ -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;
};