fix LOR's in sk. Original patch from dwhite. This moves the memory

allocation earlier on in sk_attach so we don't have to lock until a bit
later.

PR:		69752
This commit is contained in:
John-Mark Gurney 2004-08-20 06:22:04 +00:00
parent d04d789463
commit c3e8b950c7
4 changed files with 112 additions and 88 deletions

View File

@ -1337,7 +1337,6 @@ sk_attach(dev)
error = 0;
sc_if = device_get_softc(dev);
sc = device_get_softc(device_get_parent(dev));
SK_LOCK(sc);
port = *(int *)device_get_ivars(dev);
free(device_get_ivars(dev), M_DEVBUF);
device_set_ivars(dev, NULL);
@ -1352,6 +1351,40 @@ sk_attach(dev)
if (port == SK_PORT_B)
sc_if->sk_tx_bmu = SK_BMU_TXS_CSR1;
/* Allocate the descriptor queues. */
sc_if->sk_rdata = contigmalloc(sizeof(struct sk_ring_data), M_DEVBUF,
M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
if (sc_if->sk_rdata == NULL) {
printf("sk%d: no memory for list buffers!\n", sc_if->sk_unit);
error = ENOMEM;
goto fail;
}
bzero(sc_if->sk_rdata, sizeof(struct sk_ring_data));
/* Try to allocate memory for jumbo buffers. */
if (sk_alloc_jumbo_mem(sc_if)) {
printf("sk%d: jumbo buffer allocation failed\n",
sc_if->sk_unit);
error = ENOMEM;
goto fail;
}
ifp = &sc_if->arpcom.ac_if;
ifp->if_softc = sc_if;
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = sk_ioctl;
ifp->if_start = sk_start;
ifp->if_watchdog = sk_watchdog;
ifp->if_init = sk_init;
ifp->if_baudrate = 1000000000;
ifp->if_snd.ifq_maxlen = SK_TX_RING_CNT - 1;
callout_handle_init(&sc_if->sk_tick_ch);
/*
* Get station address for this interface. Note that
* dual port cards actually come with three station
@ -1361,6 +1394,7 @@ sk_attach(dev)
* are operating in failover mode. Currently we don't
* use this extra address.
*/
SK_LOCK(sc);
for (i = 0; i < ETHER_ADDR_LEN; i++)
sc_if->arpcom.ac_enaddr[i] =
sk_win_read_1(sc, SK_MAC0_0 + (port * 8) + i);
@ -1414,47 +1448,17 @@ sk_attach(dev)
printf("skc%d: unsupported PHY type: %d\n",
sc->sk_unit, sc_if->sk_phytype);
error = ENODEV;
SK_UNLOCK(sc);
goto fail;
}
/* Allocate the descriptor queues. */
sc_if->sk_rdata = contigmalloc(sizeof(struct sk_ring_data), M_DEVBUF,
M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
if (sc_if->sk_rdata == NULL) {
printf("sk%d: no memory for list buffers!\n", sc_if->sk_unit);
error = ENOMEM;
goto fail;
}
bzero(sc_if->sk_rdata, sizeof(struct sk_ring_data));
/* Try to allocate memory for jumbo buffers. */
if (sk_alloc_jumbo_mem(sc_if)) {
printf("sk%d: jumbo buffer allocation failed\n",
sc_if->sk_unit);
error = ENOMEM;
goto fail;
}
ifp = &sc_if->arpcom.ac_if;
ifp->if_softc = sc_if;
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = sk_ioctl;
ifp->if_start = sk_start;
ifp->if_watchdog = sk_watchdog;
ifp->if_init = sk_init;
ifp->if_baudrate = 1000000000;
ifp->if_snd.ifq_maxlen = SK_TX_RING_CNT - 1;
callout_handle_init(&sc_if->sk_tick_ch);
/*
* Call MI attach routine.
* Call MI attach routine. Can't hold locks when calling into ether_*.
*/
SK_UNLOCK(sc);
ether_ifattach(ifp, sc_if->arpcom.ac_enaddr);
SK_LOCK(sc);
/*
* Do miibus setup.
@ -1468,6 +1472,7 @@ sk_attach(dev)
break;
}
SK_UNLOCK(sc);
if (mii_phy_probe(dev, &sc_if->sk_miibus,
sk_ifmedia_upd, sk_ifmedia_sts)) {
printf("skc%d: no PHY found!\n", sc_if->sk_unit);
@ -1477,7 +1482,6 @@ sk_attach(dev)
}
fail:
SK_UNLOCK(sc);
if (error) {
/* Access should be ok even though lock has been dropped */
sc->sk_if[port] = NULL;
@ -1629,7 +1633,7 @@ skc_attach(dev)
bus_generic_attach(dev);
/* Hook interrupt last to avoid having to lock softc */
error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET,
error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET|INTR_MPSAFE,
sk_intr, sc, &sc->sk_intrhand);
if (error) {
@ -1667,14 +1671,24 @@ sk_detach(dev)
/* These should only be active if attach_xmac succeeded */
if (device_is_attached(dev)) {
sk_stop(sc_if);
/* Can't hold locks while calling detach */
SK_IF_UNLOCK(sc_if);
ether_ifdetach(ifp);
SK_IF_LOCK(sc_if);
}
if (sc_if->sk_miibus)
/*
* We're generally called from skc_detach() which is using
* device_delete_child() to get to here. It's already trashed
* miibus for us, so don't do it here or we'll panic.
*/
/*
if (sc_if->sk_miibus != NULL)
device_delete_child(dev, sc_if->sk_miibus);
*/
bus_generic_detach(dev);
if (sc_if->sk_cdata.sk_jumbo_buf)
if (sc_if->sk_cdata.sk_jumbo_buf != NULL)
contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF);
if (sc_if->sk_rdata) {
if (sc_if->sk_rdata != NULL) {
contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data),
M_DEVBUF);
}
@ -1691,7 +1705,6 @@ skc_detach(dev)
sc = device_get_softc(dev);
KASSERT(mtx_initialized(&sc->sk_mtx), ("sk mutex not initialized"));
SK_LOCK(sc);
if (device_is_alive(dev)) {
if (sc->sk_devs[SK_PORT_A] != NULL)
@ -1708,7 +1721,6 @@ skc_detach(dev)
if (sc->sk_res)
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
SK_UNLOCK(sc);
mtx_destroy(&sc->sk_mtx);
return(0);

View File

@ -1439,8 +1439,8 @@ struct sk_softc {
#define SK_LOCK(_sc) mtx_lock(&(_sc)->sk_mtx)
#define SK_UNLOCK(_sc) mtx_unlock(&(_sc)->sk_mtx)
#define SK_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sk_mtx, MA_OWNED)
#define SK_IF_LOCK(_sc) mtx_lock(&(_sc)->sk_softc->sk_mtx)
#define SK_IF_UNLOCK(_sc) mtx_unlock(&(_sc)->sk_softc->sk_mtx)
#define SK_IF_LOCK(_sc) SK_LOCK((_sc)->sk_softc)
#define SK_IF_UNLOCK(_sc) SK_UNLOCK((_sc)->sk_softc)
/* Softc for each logical interface */
struct sk_if_softc {

View File

@ -1337,7 +1337,6 @@ sk_attach(dev)
error = 0;
sc_if = device_get_softc(dev);
sc = device_get_softc(device_get_parent(dev));
SK_LOCK(sc);
port = *(int *)device_get_ivars(dev);
free(device_get_ivars(dev), M_DEVBUF);
device_set_ivars(dev, NULL);
@ -1352,6 +1351,40 @@ sk_attach(dev)
if (port == SK_PORT_B)
sc_if->sk_tx_bmu = SK_BMU_TXS_CSR1;
/* Allocate the descriptor queues. */
sc_if->sk_rdata = contigmalloc(sizeof(struct sk_ring_data), M_DEVBUF,
M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
if (sc_if->sk_rdata == NULL) {
printf("sk%d: no memory for list buffers!\n", sc_if->sk_unit);
error = ENOMEM;
goto fail;
}
bzero(sc_if->sk_rdata, sizeof(struct sk_ring_data));
/* Try to allocate memory for jumbo buffers. */
if (sk_alloc_jumbo_mem(sc_if)) {
printf("sk%d: jumbo buffer allocation failed\n",
sc_if->sk_unit);
error = ENOMEM;
goto fail;
}
ifp = &sc_if->arpcom.ac_if;
ifp->if_softc = sc_if;
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = sk_ioctl;
ifp->if_start = sk_start;
ifp->if_watchdog = sk_watchdog;
ifp->if_init = sk_init;
ifp->if_baudrate = 1000000000;
ifp->if_snd.ifq_maxlen = SK_TX_RING_CNT - 1;
callout_handle_init(&sc_if->sk_tick_ch);
/*
* Get station address for this interface. Note that
* dual port cards actually come with three station
@ -1361,6 +1394,7 @@ sk_attach(dev)
* are operating in failover mode. Currently we don't
* use this extra address.
*/
SK_LOCK(sc);
for (i = 0; i < ETHER_ADDR_LEN; i++)
sc_if->arpcom.ac_enaddr[i] =
sk_win_read_1(sc, SK_MAC0_0 + (port * 8) + i);
@ -1414,47 +1448,17 @@ sk_attach(dev)
printf("skc%d: unsupported PHY type: %d\n",
sc->sk_unit, sc_if->sk_phytype);
error = ENODEV;
SK_UNLOCK(sc);
goto fail;
}
/* Allocate the descriptor queues. */
sc_if->sk_rdata = contigmalloc(sizeof(struct sk_ring_data), M_DEVBUF,
M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
if (sc_if->sk_rdata == NULL) {
printf("sk%d: no memory for list buffers!\n", sc_if->sk_unit);
error = ENOMEM;
goto fail;
}
bzero(sc_if->sk_rdata, sizeof(struct sk_ring_data));
/* Try to allocate memory for jumbo buffers. */
if (sk_alloc_jumbo_mem(sc_if)) {
printf("sk%d: jumbo buffer allocation failed\n",
sc_if->sk_unit);
error = ENOMEM;
goto fail;
}
ifp = &sc_if->arpcom.ac_if;
ifp->if_softc = sc_if;
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = sk_ioctl;
ifp->if_start = sk_start;
ifp->if_watchdog = sk_watchdog;
ifp->if_init = sk_init;
ifp->if_baudrate = 1000000000;
ifp->if_snd.ifq_maxlen = SK_TX_RING_CNT - 1;
callout_handle_init(&sc_if->sk_tick_ch);
/*
* Call MI attach routine.
* Call MI attach routine. Can't hold locks when calling into ether_*.
*/
SK_UNLOCK(sc);
ether_ifattach(ifp, sc_if->arpcom.ac_enaddr);
SK_LOCK(sc);
/*
* Do miibus setup.
@ -1468,6 +1472,7 @@ sk_attach(dev)
break;
}
SK_UNLOCK(sc);
if (mii_phy_probe(dev, &sc_if->sk_miibus,
sk_ifmedia_upd, sk_ifmedia_sts)) {
printf("skc%d: no PHY found!\n", sc_if->sk_unit);
@ -1477,7 +1482,6 @@ sk_attach(dev)
}
fail:
SK_UNLOCK(sc);
if (error) {
/* Access should be ok even though lock has been dropped */
sc->sk_if[port] = NULL;
@ -1629,7 +1633,7 @@ skc_attach(dev)
bus_generic_attach(dev);
/* Hook interrupt last to avoid having to lock softc */
error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET,
error = bus_setup_intr(dev, sc->sk_irq, INTR_TYPE_NET|INTR_MPSAFE,
sk_intr, sc, &sc->sk_intrhand);
if (error) {
@ -1667,14 +1671,24 @@ sk_detach(dev)
/* These should only be active if attach_xmac succeeded */
if (device_is_attached(dev)) {
sk_stop(sc_if);
/* Can't hold locks while calling detach */
SK_IF_UNLOCK(sc_if);
ether_ifdetach(ifp);
SK_IF_LOCK(sc_if);
}
if (sc_if->sk_miibus)
/*
* We're generally called from skc_detach() which is using
* device_delete_child() to get to here. It's already trashed
* miibus for us, so don't do it here or we'll panic.
*/
/*
if (sc_if->sk_miibus != NULL)
device_delete_child(dev, sc_if->sk_miibus);
*/
bus_generic_detach(dev);
if (sc_if->sk_cdata.sk_jumbo_buf)
if (sc_if->sk_cdata.sk_jumbo_buf != NULL)
contigfree(sc_if->sk_cdata.sk_jumbo_buf, SK_JMEM, M_DEVBUF);
if (sc_if->sk_rdata) {
if (sc_if->sk_rdata != NULL) {
contigfree(sc_if->sk_rdata, sizeof(struct sk_ring_data),
M_DEVBUF);
}
@ -1691,7 +1705,6 @@ skc_detach(dev)
sc = device_get_softc(dev);
KASSERT(mtx_initialized(&sc->sk_mtx), ("sk mutex not initialized"));
SK_LOCK(sc);
if (device_is_alive(dev)) {
if (sc->sk_devs[SK_PORT_A] != NULL)
@ -1708,7 +1721,6 @@ skc_detach(dev)
if (sc->sk_res)
bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res);
SK_UNLOCK(sc);
mtx_destroy(&sc->sk_mtx);
return(0);

View File

@ -1439,8 +1439,8 @@ struct sk_softc {
#define SK_LOCK(_sc) mtx_lock(&(_sc)->sk_mtx)
#define SK_UNLOCK(_sc) mtx_unlock(&(_sc)->sk_mtx)
#define SK_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sk_mtx, MA_OWNED)
#define SK_IF_LOCK(_sc) mtx_lock(&(_sc)->sk_softc->sk_mtx)
#define SK_IF_UNLOCK(_sc) mtx_unlock(&(_sc)->sk_softc->sk_mtx)
#define SK_IF_LOCK(_sc) SK_LOCK((_sc)->sk_softc)
#define SK_IF_UNLOCK(_sc) SK_UNLOCK((_sc)->sk_softc)
/* Softc for each logical interface */
struct sk_if_softc {