hold the lock for struct ixl_softc during read or write to sc->sc_media_*
OKed by knakahara@n.o
This commit is contained in:
parent
ad58ea6187
commit
46c80a8520
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: if_ixl.c,v 1.61 2020/03/12 09:34:41 yamaguchi Exp $ */
|
/* $NetBSD: if_ixl.c,v 1.62 2020/03/12 09:38:10 yamaguchi Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2015, Intel Corporation
|
* Copyright (c) 2013-2015, Intel Corporation
|
||||||
@ -74,7 +74,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: if_ixl.c,v 1.61 2020/03/12 09:34:41 yamaguchi Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: if_ixl.c,v 1.62 2020/03/12 09:38:10 yamaguchi Exp $");
|
||||||
|
|
||||||
#ifdef _KERNEL_OPT
|
#ifdef _KERNEL_OPT
|
||||||
#include "opt_net_mpsafe.h"
|
#include "opt_net_mpsafe.h"
|
||||||
@ -800,7 +800,7 @@ static void ixl_get_link_status(void *);
|
|||||||
static int ixl_get_link_status_poll(struct ixl_softc *, int *);
|
static int ixl_get_link_status_poll(struct ixl_softc *, int *);
|
||||||
static void ixl_get_link_status_done(struct ixl_softc *,
|
static void ixl_get_link_status_done(struct ixl_softc *,
|
||||||
const struct ixl_aq_desc *);
|
const struct ixl_aq_desc *);
|
||||||
static int ixl_set_link_status(struct ixl_softc *,
|
static int ixl_set_link_status_locked(struct ixl_softc *,
|
||||||
const struct ixl_aq_desc *);
|
const struct ixl_aq_desc *);
|
||||||
static uint64_t ixl_search_link_speed(uint8_t);
|
static uint64_t ixl_search_link_speed(uint8_t);
|
||||||
static uint8_t ixl_search_baudrate(uint64_t);
|
static uint8_t ixl_search_baudrate(uint64_t);
|
||||||
@ -1686,8 +1686,10 @@ ixl_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
|
|||||||
{
|
{
|
||||||
struct ixl_softc *sc = ifp->if_softc;
|
struct ixl_softc *sc = ifp->if_softc;
|
||||||
|
|
||||||
|
mutex_enter(&sc->sc_cfg_lock);
|
||||||
ifmr->ifm_status = sc->sc_media_status;
|
ifmr->ifm_status = sc->sc_media_status;
|
||||||
ifmr->ifm_active = sc->sc_media_active;
|
ifmr->ifm_active = sc->sc_media_active;
|
||||||
|
mutex_exit(&sc->sc_cfg_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -3645,8 +3647,17 @@ static void
|
|||||||
ixl_get_link_status_done(struct ixl_softc *sc,
|
ixl_get_link_status_done(struct ixl_softc *sc,
|
||||||
const struct ixl_aq_desc *iaq)
|
const struct ixl_aq_desc *iaq)
|
||||||
{
|
{
|
||||||
|
struct ixl_aq_desc iaq_buf;
|
||||||
|
|
||||||
ixl_link_state_update(sc, iaq);
|
memcpy(&iaq_buf, iaq, sizeof(iaq_buf));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The lock can be released here
|
||||||
|
* because there is no post processing about ATQ
|
||||||
|
*/
|
||||||
|
mutex_exit(&sc->sc_atq_lock);
|
||||||
|
ixl_link_state_update(sc, &iaq_buf);
|
||||||
|
mutex_enter(&sc->sc_atq_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -3666,11 +3677,12 @@ ixl_get_link_status(void *xsc)
|
|||||||
param->notify = IXL_AQ_LINK_NOTIFY;
|
param->notify = IXL_AQ_LINK_NOTIFY;
|
||||||
|
|
||||||
error = ixl_atq_exec_locked(sc, &sc->sc_link_state_atq);
|
error = ixl_atq_exec_locked(sc, &sc->sc_link_state_atq);
|
||||||
|
ixl_atq_set(&sc->sc_link_state_atq, ixl_get_link_status_done);
|
||||||
|
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
ixl_get_link_status_done(sc, iaq);
|
ixl_get_link_status_done(sc, iaq);
|
||||||
}
|
}
|
||||||
|
|
||||||
ixl_atq_set(&sc->sc_link_state_atq, ixl_get_link_status_done);
|
|
||||||
|
|
||||||
mutex_exit(&sc->sc_atq_lock);
|
mutex_exit(&sc->sc_atq_lock);
|
||||||
}
|
}
|
||||||
@ -3681,15 +3693,17 @@ ixl_link_state_update(struct ixl_softc *sc, const struct ixl_aq_desc *iaq)
|
|||||||
struct ifnet *ifp = &sc->sc_ec.ec_if;
|
struct ifnet *ifp = &sc->sc_ec.ec_if;
|
||||||
int link_state;
|
int link_state;
|
||||||
|
|
||||||
KASSERT(kpreempt_disabled());
|
mutex_enter(&sc->sc_cfg_lock);
|
||||||
|
link_state = ixl_set_link_status_locked(sc, iaq);
|
||||||
link_state = ixl_set_link_status(sc, iaq);
|
mutex_exit(&sc->sc_cfg_lock);
|
||||||
|
|
||||||
if (ifp->if_link_state != link_state)
|
if (ifp->if_link_state != link_state)
|
||||||
if_link_state_change(ifp, link_state);
|
if_link_state_change(ifp, link_state);
|
||||||
|
|
||||||
if (link_state != LINK_STATE_DOWN) {
|
if (link_state != LINK_STATE_DOWN) {
|
||||||
|
kpreempt_disable();
|
||||||
if_schedule_deferred_start(ifp);
|
if_schedule_deferred_start(ifp);
|
||||||
|
kpreempt_enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3751,9 +3765,7 @@ ixl_arq(void *xsc)
|
|||||||
|
|
||||||
switch (iaq->iaq_opcode) {
|
switch (iaq->iaq_opcode) {
|
||||||
case htole16(IXL_AQ_OP_PHY_LINK_STATUS):
|
case htole16(IXL_AQ_OP_PHY_LINK_STATUS):
|
||||||
kpreempt_disable();
|
|
||||||
ixl_link_state_update(sc, iaq);
|
ixl_link_state_update(sc, iaq);
|
||||||
kpreempt_enable();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4500,7 +4512,8 @@ ixl_get_link_status_poll(struct ixl_softc *sc, int *l)
|
|||||||
return EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
link = ixl_set_link_status(sc, &iaq);
|
/* It is unneccessary to hold lock */
|
||||||
|
link = ixl_set_link_status_locked(sc, &iaq);
|
||||||
|
|
||||||
if (l != NULL)
|
if (l != NULL)
|
||||||
*l = link;
|
*l = link;
|
||||||
@ -5690,7 +5703,7 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ixl_set_link_status(struct ixl_softc *sc, const struct ixl_aq_desc *iaq)
|
ixl_set_link_status_locked(struct ixl_softc *sc, const struct ixl_aq_desc *iaq)
|
||||||
{
|
{
|
||||||
const struct ixl_aq_link_status *status;
|
const struct ixl_aq_link_status *status;
|
||||||
const struct ixl_phy_type *itype;
|
const struct ixl_phy_type *itype;
|
||||||
@ -5722,6 +5735,7 @@ ixl_set_link_status(struct ixl_softc *sc, const struct ixl_aq_desc *iaq)
|
|||||||
baudrate = ixl_search_link_speed(status->link_speed);
|
baudrate = ixl_search_link_speed(status->link_speed);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
/* sc->sc_cfg_lock held expect during attach */
|
||||||
sc->sc_media_active = ifm_active;
|
sc->sc_media_active = ifm_active;
|
||||||
sc->sc_media_status = ifm_status;
|
sc->sc_media_status = ifm_status;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user