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:
mlaier 2006-04-10 18:27:00 +00:00
parent 7e163b6986
commit 4157cdd5a3
2 changed files with 17 additions and 3 deletions

View File

@ -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);

View File

@ -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)