diff options
author | rwatson <rwatson@FreeBSD.org> | 2005-08-03 00:18:35 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2005-08-03 00:18:35 +0000 |
commit | 9918d13b80941400bfab87834b1e2f1eea58c7c7 (patch) | |
tree | 9a4e586ffbcd1450917ee5e388a4e1eb38254e32 /sys/pci | |
parent | efa13b9da9fc80838e2c73140ae27393b3660da4 (diff) | |
download | FreeBSD-src-9918d13b80941400bfab87834b1e2f1eea58c7c7.zip FreeBSD-src-9918d13b80941400bfab87834b1e2f1eea58c7c7.tar.gz |
Modify device drivers supporting multicast addresses to lock if_addr_mtx
over iteration of their multicast address lists when synchronizing the
hardware address filter with the network stack-maintained list.
Problem reported by: Ed Maste (emaste at phaedrus dot sandvine dot ca>
MFC after: 1 week
Diffstat (limited to 'sys/pci')
-rw-r--r-- | sys/pci/if_dc.c | 8 | ||||
-rw-r--r-- | sys/pci/if_de.c | 2 | ||||
-rw-r--r-- | sys/pci/if_pcn.c | 2 | ||||
-rw-r--r-- | sys/pci/if_rl.c | 2 | ||||
-rw-r--r-- | sys/pci/if_sf.c | 2 | ||||
-rw-r--r-- | sys/pci/if_sis.c | 4 | ||||
-rw-r--r-- | sys/pci/if_sk.c | 2 | ||||
-rw-r--r-- | sys/pci/if_ste.c | 2 | ||||
-rw-r--r-- | sys/pci/if_ti.c | 2 | ||||
-rw-r--r-- | sys/pci/if_tl.c | 2 | ||||
-rw-r--r-- | sys/pci/if_vr.c | 2 | ||||
-rw-r--r-- | sys/pci/if_wb.c | 2 | ||||
-rw-r--r-- | sys/pci/if_xl.c | 4 |
13 files changed, 36 insertions, 0 deletions
diff --git a/sys/pci/if_dc.c b/sys/pci/if_dc.c index f86d4e4..7fd9568 100644 --- a/sys/pci/if_dc.c +++ b/sys/pci/if_dc.c @@ -1110,6 +1110,7 @@ dc_setfilt_21143(struct dc_softc *sc) else DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI); + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1117,6 +1118,7 @@ dc_setfilt_21143(struct dc_softc *sc) LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); sp[h >> 4] |= htole32(1 << (h & 0xF)); } + IF_ADDR_UNLOCK(ifp); if (ifp->if_flags & IFF_BROADCAST) { h = dc_mchash_le(sc, ifp->if_broadcastaddr); @@ -1179,6 +1181,7 @@ dc_setfilt_admtek(struct dc_softc *sc) return; /* Now program new ones. */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1193,6 +1196,7 @@ dc_setfilt_admtek(struct dc_softc *sc) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); CSR_WRITE_4(sc, DC_AL_MAR0, hashes[0]); CSR_WRITE_4(sc, DC_AL_MAR1, hashes[1]); @@ -1250,6 +1254,7 @@ dc_setfilt_asix(struct dc_softc *sc) return; /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1259,6 +1264,7 @@ dc_setfilt_asix(struct dc_softc *sc) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_MAR0); CSR_WRITE_4(sc, DC_AX_FILTDATA, hashes[0]); @@ -1302,6 +1308,7 @@ dc_setfilt_xircom(struct dc_softc *sc) else DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI); + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1309,6 +1316,7 @@ dc_setfilt_xircom(struct dc_softc *sc) LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); sp[h >> 4] |= htole32(1 << (h & 0xF)); } + IF_ADDR_UNLOCK(ifp); if (ifp->if_flags & IFF_BROADCAST) { h = dc_mchash_le(sc, ifp->if_broadcastaddr); diff --git a/sys/pci/if_de.c b/sys/pci/if_de.c index 5fdff82..421d1aa 100644 --- a/sys/pci/if_de.c +++ b/sys/pci/if_de.c @@ -3026,6 +3026,7 @@ tulip_addr_filter( #endif multicnt = 0; + IF_ADDR_LOCK(sc->tulip_ifp); TAILQ_FOREACH(ifma, &sc->tulip_ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family == AF_LINK) @@ -3147,6 +3148,7 @@ tulip_addr_filter( #endif } } + IF_ADDR_UNLOCK(sc->tulip_ifp); #if defined(IFF_ALLMULTI) if (sc->tulip_flags & TULIP_ALLMULTI) sc->tulip_ifp->if_flags |= IFF_ALLMULTI; diff --git a/sys/pci/if_pcn.c b/sys/pci/if_pcn.c index 7dec359..f316146 100644 --- a/sys/pci/if_pcn.c +++ b/sys/pci/if_pcn.c @@ -351,6 +351,7 @@ pcn_setmulti(sc) pcn_csr_write(sc, PCN_CSR_MAR0 + i, 0); /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -358,6 +359,7 @@ pcn_setmulti(sc) ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; hashes[h >> 4] |= 1 << (h & 0xF); } + IF_ADDR_UNLOCK(ifp); for (i = 0; i < 4; i++) pcn_csr_write(sc, PCN_CSR_MAR0 + i, hashes[i]); diff --git a/sys/pci/if_rl.c b/sys/pci/if_rl.c index bc01dbc..8d27fb3 100644 --- a/sys/pci/if_rl.c +++ b/sys/pci/if_rl.c @@ -685,6 +685,7 @@ rl_setmulti(struct rl_softc *sc) CSR_WRITE_4(sc, RL_MAR4, 0); /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -696,6 +697,7 @@ rl_setmulti(struct rl_softc *sc) hashes[1] |= (1 << (h - 32)); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt) rxfilt |= RL_RXCFG_RX_MULTI; diff --git a/sys/pci/if_sf.c b/sys/pci/if_sf.c index a64379f..5485fb7 100644 --- a/sys/pci/if_sf.c +++ b/sys/pci/if_sf.c @@ -431,6 +431,7 @@ sf_setmulti(sc) SF_SETBIT(sc, SF_RXFILT, SF_RXFILT_ALLMULTI); } else { i = 1; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH_REVERSE(ifma, &ifp->if_multiaddrs, ifmultihead, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -449,6 +450,7 @@ sf_setmulti(sc) sf_sethash(sc, LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 0); } + IF_ADDR_UNLOCK(ifp); } } diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c index b455b83..48a6132 100644 --- a/sys/pci/if_sis.c +++ b/sys/pci/if_sis.c @@ -763,6 +763,7 @@ sis_setmulti_ns(struct sis_softc *sc) CSR_WRITE_4(sc, SIS_RXFILT_DATA, 0); } + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -775,6 +776,7 @@ sis_setmulti_ns(struct sis_softc *sc) bit -= 0x10; SIS_SETBIT(sc, SIS_RXFILT_DATA, (1 << bit)); } + IF_ADDR_UNLOCK(ifp); CSR_WRITE_4(sc, SIS_RXFILT_CTL, filtsave); @@ -813,6 +815,7 @@ sis_setmulti_sis(struct sis_softc *sc) for (i = 0; i < n; i++) hashes[i] = 0; i = 0; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -821,6 +824,7 @@ sis_setmulti_sis(struct sis_softc *sc) hashes[h >> 4] |= 1 << (h & 0xf); i++; } + IF_ADDR_UNLOCK(ifp); if (i > n) { ctl |= SIS_RXFILTCTL_ALLMULTI; for (i = 0; i < n; i++) diff --git a/sys/pci/if_sk.c b/sys/pci/if_sk.c index bcc4b03..0daf42e 100644 --- a/sys/pci/if_sk.c +++ b/sys/pci/if_sk.c @@ -823,6 +823,7 @@ sk_setmulti(sc_if) hashes[1] = 0xFFFFFFFF; } else { i = 1; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH_REVERSE(ifma, &ifp->if_multiaddrs, ifmultihead, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -855,6 +856,7 @@ sk_setmulti(sc_if) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); } switch(sc->sk_type) { diff --git a/sys/pci/if_ste.c b/sys/pci/if_ste.c index 27d5399..8e73f65 100644 --- a/sys/pci/if_ste.c +++ b/sys/pci/if_ste.c @@ -579,6 +579,7 @@ ste_setmulti(sc) CSR_WRITE_2(sc, STE_MAR3, 0); /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -589,6 +590,7 @@ ste_setmulti(sc) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); CSR_WRITE_2(sc, STE_MAR0, hashes[0] & 0xFFFF); CSR_WRITE_2(sc, STE_MAR1, (hashes[0] >> 16) & 0xFFFF); diff --git a/sys/pci/if_ti.c b/sys/pci/if_ti.c index 1bbfe38..5ce58c5 100644 --- a/sys/pci/if_ti.c +++ b/sys/pci/if_ti.c @@ -1621,6 +1621,7 @@ ti_setmulti(sc) } /* Now program new ones. */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1634,6 +1635,7 @@ ti_setmulti(sc) SLIST_INSERT_HEAD(&sc->ti_mc_listhead, mc, mc_entries); ti_add_mcast(sc, &mc->mc_addr); } + IF_ADDR_UNLOCK(ifp); /* Re-enable interrupts. */ CSR_WRITE_4(sc, TI_MB_HOSTINTR, intrs); diff --git a/sys/pci/if_tl.c b/sys/pci/if_tl.c index 3dde56a..f9d9815 100644 --- a/sys/pci/if_tl.c +++ b/sys/pci/if_tl.c @@ -960,6 +960,7 @@ tl_setmulti(sc) hashes[1] = 0xFFFFFFFF; } else { i = 1; + IF_ADDR_LOCK(ifp); TAILQ_FOREACH_REVERSE(ifma, &ifp->if_multiaddrs, ifmultihead, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -982,6 +983,7 @@ tl_setmulti(sc) else hashes[1] |= (1 << (h - 32)); } + IF_ADDR_UNLOCK(ifp); } tl_dio_write32(sc, TL_HASH1, hashes[0]); diff --git a/sys/pci/if_vr.c b/sys/pci/if_vr.c index 23194f7..654de6f 100644 --- a/sys/pci/if_vr.c +++ b/sys/pci/if_vr.c @@ -533,6 +533,7 @@ vr_setmulti(struct vr_softc *sc) CSR_WRITE_4(sc, VR_MAR1, 0); /* Now program new ones. */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -544,6 +545,7 @@ vr_setmulti(struct vr_softc *sc) hashes[1] |= (1 << (h - 32)); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt) rxfilt |= VR_RXCFG_RX_MULTI; diff --git a/sys/pci/if_wb.c b/sys/pci/if_wb.c index 0677fca..9c44e2e 100644 --- a/sys/pci/if_wb.c +++ b/sys/pci/if_wb.c @@ -614,6 +614,7 @@ wb_setmulti(sc) CSR_WRITE_4(sc, WB_MAR1, 0); /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -625,6 +626,7 @@ wb_setmulti(sc) hashes[1] |= (1 << (h - 32)); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt) rxfilt |= WB_NETCFG_RX_MULTI; diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c index cca9d4e..72c8ce0 100644 --- a/sys/pci/if_xl.c +++ b/sys/pci/if_xl.c @@ -777,8 +777,10 @@ xl_setmulti(struct xl_softc *sc) return; } + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) mcnt++; + IF_ADDR_UNLOCK(ifp); if (mcnt) rxfilt |= XL_RXFILTER_ALLMULTI; @@ -817,6 +819,7 @@ xl_setmulti_hash(struct xl_softc *sc) CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_HASH|i); /* now program new ones */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -838,6 +841,7 @@ xl_setmulti_hash(struct xl_softc *sc) h | XL_CMD_RX_SET_HASH | XL_HASH_SET); mcnt++; } + IF_ADDR_UNLOCK(ifp); if (mcnt) rxfilt |= XL_RXFILTER_MULTIHASH; |