Stopgap fix to avoid "mutex ipw0 recursed" panics in msleep for recursive
ioctl paths. Instead of using a recursive mutex we use conditional locking and keep track of the recursion on the stack. Reported and tested by: Ulrich Spoerlein Approved by: re (scottl)
This commit is contained in:
parent
7e163b6986
commit
4157cdd5a3
@ -220,7 +220,7 @@ ipw_attach(device_t dev)
|
||||
sc->sc_dev = dev;
|
||||
|
||||
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF | MTX_RECURSE);
|
||||
MTX_DEF);
|
||||
|
||||
if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
|
||||
device_printf(dev, "chip is in D%d power mode "
|
||||
@ -380,6 +380,7 @@ ipw_detach(device_t dev)
|
||||
struct ipw_softc *sc = device_get_softc(dev);
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ifnet *ifp = ic->ic_ifp;
|
||||
IPW_LOCK_DECL;
|
||||
|
||||
IPW_LOCK(sc);
|
||||
|
||||
@ -722,6 +723,7 @@ ipw_resume(device_t dev)
|
||||
{
|
||||
struct ipw_softc *sc = device_get_softc(dev);
|
||||
struct ifnet *ifp = sc->sc_ic.ic_ifp;
|
||||
IPW_LOCK_DECL;
|
||||
|
||||
IPW_LOCK(sc);
|
||||
|
||||
@ -743,6 +745,7 @@ ipw_media_change(struct ifnet *ifp)
|
||||
{
|
||||
struct ipw_softc *sc = ifp->if_softc;
|
||||
int error;
|
||||
IPW_LOCK_DECL;
|
||||
|
||||
IPW_LOCK(sc);
|
||||
|
||||
@ -1222,6 +1225,7 @@ ipw_intr(void *arg)
|
||||
{
|
||||
struct ipw_softc *sc = arg;
|
||||
uint32_t r;
|
||||
IPW_LOCK_DECL;
|
||||
|
||||
IPW_LOCK(sc);
|
||||
|
||||
@ -1474,6 +1478,7 @@ ipw_start(struct ifnet *ifp)
|
||||
struct mbuf *m0;
|
||||
struct ether_header *eh;
|
||||
struct ieee80211_node *ni;
|
||||
IPW_LOCK_DECL;
|
||||
|
||||
IPW_LOCK(sc);
|
||||
|
||||
@ -1557,6 +1562,7 @@ ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ifreq *ifr;
|
||||
int error = 0;
|
||||
IPW_LOCK_DECL;
|
||||
|
||||
IPW_LOCK(sc);
|
||||
|
||||
@ -1769,6 +1775,7 @@ ipw_cache_firmware(struct ipw_softc *sc, void *data)
|
||||
struct ipw_firmware_hdr hdr;
|
||||
u_char *p = data;
|
||||
int error;
|
||||
IPW_LOCK_DECL;
|
||||
|
||||
ipw_free_firmware(sc);
|
||||
|
||||
|
@ -170,5 +170,12 @@ struct ipw_softc {
|
||||
#define SIOCSLOADFW _IOW('i', 137, struct ifreq)
|
||||
#define SIOCSKILLFW _IOW('i', 138, struct ifreq)
|
||||
|
||||
#define IPW_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
|
||||
#define IPW_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
|
||||
#define IPW_LOCK_DECL int __waslocked = 0
|
||||
#define IPW_LOCK(sc) do { \
|
||||
if (!(__waslocked = mtx_owned(&(sc)->sc_mtx))) \
|
||||
mtx_lock(&(sc)->sc_mtx); \
|
||||
} while (0)
|
||||
#define IPW_UNLOCK(sc) do { \
|
||||
if (!__waslocked) \
|
||||
mtx_unlock(&(sc)->sc_mtx); \
|
||||
} while (0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user