summaryrefslogtreecommitdiffstats
path: root/sys/netatalk
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2005-02-22 14:20:29 +0000
committerrwatson <rwatson@FreeBSD.org>2005-02-22 14:20:29 +0000
commitd552b6fe480d4086e05aa88c4bcf23baf0c470a3 (patch)
treee491c0df9e3888bbb34db162823ab69087e3b44b /sys/netatalk
parentcd21b2e10ce05cf965e2989f557834034cf53854 (diff)
downloadFreeBSD-src-d552b6fe480d4086e05aa88c4bcf23baf0c470a3.zip
FreeBSD-src-d552b6fe480d4086e05aa88c4bcf23baf0c470a3.tar.gz
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
Diffstat (limited to 'sys/netatalk')
-rw-r--r--sys/netatalk/aarp.c17
-rw-r--r--sys/netatalk/at_control.c12
-rw-r--r--sys/netatalk/at_extern.h7
-rw-r--r--sys/netatalk/at_var.h2
4 files changed, 24 insertions, 14 deletions
diff --git a/sys/netatalk/aarp.c b/sys/netatalk/aarp.c
index bdff6af..7e0c96a 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 d24edc4..4dc0a71 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 c2daf26..58ceb8d 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 e0eb0ed..fa4e69d 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;
};
OpenPOWER on IntegriCloud