From owner-p4-projects Mon Nov 11 16:43:46 2002 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3114F37B401; Mon, 11 Nov 2002 16:43:39 -0800 (PST) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 09AB437B404 for ; Mon, 11 Nov 2002 16:43:39 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id AACCC43E75 for ; Mon, 11 Nov 2002 16:43:38 -0800 (PST) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id gAC0fJmV012673 for ; Mon, 11 Nov 2002 16:41:19 -0800 (PST) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id gAC0fJAV012669 for perforce@freebsd.org; Mon, 11 Nov 2002 16:41:19 -0800 (PST) Date: Mon, 11 Nov 2002 16:41:19 -0800 (PST) Message-Id: <200211120041.gAC0fJAV012669@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson Subject: PERFORCE change 20981 for review To: Perforce Change Reviews Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG http://perforce.freebsd.org/chv.cgi?CH=20981 Change 20981 by rwatson@rwatson_tislabs on 2002/11/11 16:41:03 Introduce a condition variable to avoid returning EBUSY when the MAC policy list is busy during a load or unload attempt. We assert no locks held during the cv wait, meaning we should be fairly deadlock-safe. Because of the cv model and busy count, it's possible for a cv waiter waiting for exclusive access to the policy list to be starved by active and long-lived access control/labeling events. For now, we accept that as a necessary tradeoff. Largely extracted from: amigus_mac_userland Affected files ... .. //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c#356 edit Differences ... ==== //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c#356 (text+ko) ==== @@ -46,6 +46,7 @@ #include "opt_devfs.h" #include +#include #include #include #include @@ -233,12 +234,14 @@ * and that this is not yet done for relabel requests. */ static struct mtx mac_policy_list_lock; +static struct cv mac_policy_list_not_busy; static LIST_HEAD(, mac_policy_conf) mac_policy_list; static int mac_policy_list_busy; #define MAC_POLICY_LIST_LOCKINIT() do { \ mtx_init(&mac_policy_list_lock, "mac_policy_list_lock", NULL, \ MTX_DEF); \ + cv_init(&mac_policy_list_not_busy, "mac_policy_list_not_busy"); \ } while (0) #define MAC_POLICY_LIST_LOCK() do { \ @@ -249,6 +252,14 @@ mtx_unlock(&mac_policy_list_lock); \ } while (0) +#define MAC_POLICY_LIST_EXCLUSIVE() do { \ + WITNESS_SLEEP(1, NULL); \ + mtx_lock(&mac_policy_list_lock); \ + while (mac_policy_list_busy != 0) \ + cv_wait(&mac_policy_list_not_busy, \ + &mac_policy_list_lock); \ +} while (0) + #define MAC_POLICY_LIST_BUSY() do { \ MAC_POLICY_LIST_LOCK(); \ mac_policy_list_busy++; \ @@ -258,8 +269,9 @@ #define MAC_POLICY_LIST_UNBUSY() do { \ MAC_POLICY_LIST_LOCK(); \ mac_policy_list_busy--; \ - if (mac_policy_list_busy < 0) \ - panic("Extra mac_policy_list_busy--"); \ + KASSERT(mac_policy_list_busy >= 0, ("MAC_POLICY_LIST_LOCK")); \ + if (mac_policy_list_busy == 0) \ + cv_signal(&mac_policy_list_not_busy); \ MAC_POLICY_LIST_UNLOCK(); \ } while (0) @@ -474,11 +486,7 @@ struct mac_policy_conf *tmpc; int slot; - MAC_POLICY_LIST_LOCK(); - if (mac_policy_list_busy > 0) { - MAC_POLICY_LIST_UNLOCK(); - return (EBUSY); - } + MAC_POLICY_LIST_EXCLUSIVE(); LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { MAC_POLICY_LIST_UNLOCK(); @@ -518,7 +526,7 @@ * to see if we did the run-time registration, and if not, * silently succeed. */ - MAC_POLICY_LIST_LOCK(); + MAC_POLICY_LIST_EXCLUSIVE(); if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { MAC_POLICY_LIST_UNLOCK(); return (0); @@ -540,23 +548,14 @@ MAC_POLICY_LIST_UNLOCK(); return (EBUSY); } - /* - * Right now, we EBUSY if the list is in use. In the future, - * for reliability reasons, we might want to sleep and wakeup - * later to try again. - */ - if (mac_policy_list_busy > 0) { - MAC_POLICY_LIST_UNLOCK(); - return (EBUSY); - } if (mpc->mpc_ops->mpo_destroy != NULL) (*(mpc->mpc_ops->mpo_destroy))(mpc); LIST_REMOVE(mpc, mpc_list); + mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; + MAC_POLICY_LIST_UNLOCK(); - mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; - printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, mpc->mpc_name); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message