From owner-p4-projects@FreeBSD.ORG Wed Feb 20 04:12:11 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 1DB0216A402; Wed, 20 Feb 2008 04:12:10 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8670716A401 for ; Wed, 20 Feb 2008 04:12:10 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 79D7313C448 for ; Wed, 20 Feb 2008 04:12:10 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m1K4CAKT068941 for ; Wed, 20 Feb 2008 04:12:10 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m1K4CAYV068938 for perforce@freebsd.org; Wed, 20 Feb 2008 04:12:10 GMT (envelope-from sam@freebsd.org) Date: Wed, 20 Feb 2008 04:12:10 GMT Message-Id: <200802200412.m1K4CAYV068938@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 135771 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 Feb 2008 04:12:11 -0000 http://perforce.freebsd.org/chv.cgi?CH=135771 Change 135771 by sam@sam_ebb on 2008/02/20 04:11:48 Make a lame attempt at locking vap create/delete; we can't do this properly because there are lots of calls deep below us that do malloc(M_WAITOK). Affected files ... .. //depot/projects/vap/sys/dev/ath/if_ath.c#30 edit Differences ... ==== //depot/projects/vap/sys/dev/ath/if_ath.c#30 (text+ko) ==== @@ -741,15 +741,17 @@ uint8_t mac[IEEE80211_ADDR_LEN]; int ic_opmode, needbeacon; + avp = (struct ath_vap *) malloc(sizeof(struct ath_vap), + M_80211_VAP, M_WAITOK | M_ZERO); needbeacon = 0; IEEE80211_ADDR_COPY(mac, mac0); - /* XXX ic unlocked and race against add? */ + ATH_LOCK(sc); switch (opmode) { case IEEE80211_M_STA: if (sc->sc_nstavaps != 0) { /* XXX only 1 sta for now */ device_printf(sc->sc_dev, "only 1 sta vap supported\n"); - return NULL; + goto bad; } if (sc->sc_nvaps) { /* @@ -768,7 +770,7 @@ if (sc->sc_nvaps != 0) { /* XXX only 1 for now */ device_printf(sc->sc_dev, "only 1 ibss vap supported\n"); - return NULL; + goto bad; } ic_opmode = opmode; needbeacon = 1; @@ -789,7 +791,7 @@ if (sc->sc_nvaps && ic->ic_opmode == IEEE80211_M_STA) { device_printf(sc->sc_dev, "wds not supported in sta mode\n"); - return NULL; + goto bad; } if (opmode == IEEE80211_M_WDS) { /* @@ -803,29 +805,26 @@ break; default: device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); - return NULL; + goto bad; } /* * Check that a beacon buffer is available; the code below assumes it. */ if (needbeacon & STAILQ_EMPTY(&sc->sc_bbuf)) { device_printf(sc->sc_dev, "no beacon buffer available\n"); - return NULL; + goto bad; } - avp = (struct ath_vap *) malloc(sizeof(struct ath_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (avp == NULL) { - device_printf(sc->sc_dev, "unable to allocate memory\n"); - return NULL; - } - /* STA, AHDEMO? */ if (opmode == IEEE80211_M_HOSTAP) assign_address(sc, mac, flags & IEEE80211_CLONE_BSSID); vap = &avp->av_vap; + /* XXX can't hold mutex across if_alloc */ + ATH_UNLOCK(sc); + /* XXX check return */ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ATH_LOCK(sc); /* h/w crypto support */ vap->iv_key_alloc = ath_key_alloc; @@ -875,8 +874,6 @@ STAILQ_INIT(&avp->av_mcastq.axq_q); ATH_TXQ_LOCK_INIT(sc, &avp->av_mcastq); } - /* complete setup */ - ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status); ic->ic_opmode = ic_opmode; if (opmode != IEEE80211_M_WDS) @@ -899,14 +896,22 @@ /* XXX should not happen */ break; } - if (sc->sc_hastsfadd) { /* * Configure whether or not TSF adjust should be done. */ ath_hal_settsfadjust(sc->sc_ah, sc->sc_stagbeacons); } + ATH_UNLOCK(sc); + + /* complete setup */ + ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status); return vap; +bad: + /* XXX can leak ic->ic_ifp */ + free(avp, M_80211_VAP); + ATH_UNLOCK(sc); + return NULL; } static void @@ -930,6 +935,7 @@ } ieee80211_vap_detach(vap); + ATH_LOCK(sc); /* * Reclaim beacon state. Note this must be done before * the vap instance is reclaimed as we may have a reference @@ -965,6 +971,7 @@ } if (vap->iv_opmode != IEEE80211_M_WDS) sc->sc_nvaps--; + ATH_UNLOCK(sc); free(avp, M_80211_VAP); if (ifp->if_drv_flags & IFF_DRV_RUNNING) {