From owner-svn-src-stable-7@FreeBSD.ORG Mon Sep 7 08:52:15 2009 Return-Path: Delivered-To: svn-src-stable-7@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DEFC01065679; Mon, 7 Sep 2009 08:52:15 +0000 (UTC) (envelope-from attilio@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C31F98FC13; Mon, 7 Sep 2009 08:52:15 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n878qFLJ008671; Mon, 7 Sep 2009 08:52:15 GMT (envelope-from attilio@svn.freebsd.org) Received: (from attilio@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n878qFds008667; Mon, 7 Sep 2009 08:52:15 GMT (envelope-from attilio@svn.freebsd.org) Message-Id: <200909070852.n878qFds008667@svn.freebsd.org> From: Attilio Rao Date: Mon, 7 Sep 2009 08:52:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r196915 - in stable/7/sys: dev/hwpmc kern X-BeenThere: svn-src-stable-7@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 7-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Sep 2009 08:52:16 -0000 Author: attilio Date: Mon Sep 7 08:52:15 2009 New Revision: 196915 URL: http://svn.freebsd.org/changeset/base/196915 Log: MFC r195159 and r195005: * Don't assume a fixed number of preloaded KLDs but calculate at runtime. This avoind ending up into an endless loop. * Fix a LOR between pmc_sx and allproc/proctree locks Sponsored by: Sandvine Incorporated Modified: stable/7/sys/dev/hwpmc/hwpmc_logging.c stable/7/sys/dev/hwpmc/hwpmc_mod.c stable/7/sys/kern/kern_linker.c Modified: stable/7/sys/dev/hwpmc/hwpmc_logging.c ============================================================================== --- stable/7/sys/dev/hwpmc/hwpmc_logging.c Mon Sep 7 08:46:26 2009 (r196914) +++ stable/7/sys/dev/hwpmc/hwpmc_logging.c Mon Sep 7 08:52:15 2009 (r196915) @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -552,6 +553,12 @@ pmclog_configure_log(struct pmc_mdep *md int error; struct proc *p; + /* + * As long as it is possible to get a LOR between pmc_sx lock and + * proctree/allproc sx locks used for adding a new process, assure + * the former is not held here. + */ + sx_assert(&pmc_sx, SA_UNLOCKED); PMCDBG(LOG,CFG,1, "config po=%p logfd=%d", po, logfd); p = po->po_owner; Modified: stable/7/sys/dev/hwpmc/hwpmc_mod.c ============================================================================== --- stable/7/sys/dev/hwpmc/hwpmc_mod.c Mon Sep 7 08:46:26 2009 (r196914) +++ stable/7/sys/dev/hwpmc/hwpmc_mod.c Mon Sep 7 08:52:15 2009 (r196915) @@ -2666,7 +2666,7 @@ static const char *pmc_op_to_name[] = { static int pmc_syscall_handler(struct thread *td, void *syscall_args) { - int error, is_sx_downgraded, op; + int error, is_sx_downgraded, is_sx_locked, op; struct pmc_syscall_args *c; void *arg; @@ -2675,6 +2675,7 @@ pmc_syscall_handler(struct thread *td, v DROP_GIANT(); is_sx_downgraded = 0; + is_sx_locked = 1; c = (struct pmc_syscall_args *) syscall_args; @@ -2723,9 +2724,11 @@ pmc_syscall_handler(struct thread *td, v * a log file configured, flush its buffers and * de-configure it. */ - if (cl.pm_logfd >= 0) + if (cl.pm_logfd >= 0) { + sx_xunlock(&pmc_sx); + is_sx_locked = 0; error = pmclog_configure_log(md, po, cl.pm_logfd); - else if (po->po_flags & PMC_PO_OWNS_LOGFILE) { + } else if (po->po_flags & PMC_PO_OWNS_LOGFILE) { pmclog_process_closelog(po); error = pmclog_flush(po); if (error == 0) { @@ -3776,10 +3779,12 @@ pmc_syscall_handler(struct thread *td, v break; } - if (is_sx_downgraded) - sx_sunlock(&pmc_sx); - else - sx_xunlock(&pmc_sx); + if (is_sx_locked != 0) { + if (is_sx_downgraded) + sx_sunlock(&pmc_sx); + else + sx_xunlock(&pmc_sx); + } if (error) atomic_add_int(&pmc_stats.pm_syscall_errors, 1); Modified: stable/7/sys/kern/kern_linker.c ============================================================================== --- stable/7/sys/kern/kern_linker.c Mon Sep 7 08:46:26 2009 (r196914) +++ stable/7/sys/kern/kern_linker.c Mon Sep 7 08:52:15 2009 (r196915) @@ -1882,62 +1882,41 @@ linker_basename(const char *path) } #ifdef HWPMC_HOOKS - -struct hwpmc_context { - int nobjects; - int nmappings; - struct pmckern_map_in *kobase; -}; - -static int -linker_hwpmc_list_object(linker_file_t lf, void *arg) -{ - struct hwpmc_context *hc; - - hc = arg; - - /* If we run out of mappings, fail. */ - if (hc->nobjects >= hc->nmappings) - return (1); - - /* Save the info for this linker file. */ - hc->kobase[hc->nobjects].pm_file = lf->filename; - hc->kobase[hc->nobjects].pm_address = (uintptr_t)lf->address; - hc->nobjects++; - return (0); -} - /* * Inform hwpmc about the set of kernel modules currently loaded. */ void * linker_hwpmc_list_objects(void) { - struct hwpmc_context hc; + linker_file_t lf; + struct pmckern_map_in *kobase; + int i, nmappings; - hc.nmappings = 15; /* a reasonable default */ + nmappings = 0; + KLD_LOCK(); + TAILQ_FOREACH(lf, &linker_files, link) + nmappings++; - retry: - /* allocate nmappings+1 entries */ - MALLOC(hc.kobase, struct pmckern_map_in *, - (hc.nmappings + 1) * sizeof(struct pmckern_map_in), M_LINKER, - M_WAITOK | M_ZERO); - - hc.nobjects = 0; - if (linker_file_foreach(linker_hwpmc_list_object, &hc) != 0) { - hc.nmappings = hc.nobjects; - FREE(hc.kobase, M_LINKER); - goto retry; + /* Allocate nmappings + 1 entries. */ + kobase = malloc((nmappings + 1) * sizeof(struct pmckern_map_in), + M_LINKER, M_WAITOK | M_ZERO); + i = 0; + TAILQ_FOREACH(lf, &linker_files, link) { + + /* Save the info for this linker file. */ + kobase[i].pm_file = lf->filename; + kobase[i].pm_address = (uintptr_t)lf->address; + i++; } + KLD_UNLOCK(); - KASSERT(hc.nobjects > 0, ("linker_hpwmc_list_objects: no kernel " - "objects?")); + KASSERT(i > 0, ("linker_hwpmc_list_objects: no kernel objects?")); /* The last entry of the malloced area comprises of all zeros. */ - KASSERT(hc.kobase[hc.nobjects].pm_file == NULL, + KASSERT(kobase[i].pm_file == NULL, ("linker_hwpmc_list_objects: last object not NULL")); - return ((void *)hc.kobase); + return ((void *)kobase); } #endif