From owner-svn-src-all@FreeBSD.ORG Fri Sep 20 23:06:24 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 2D928A15; Fri, 20 Sep 2013 23:06:24 +0000 (UTC) (envelope-from davide@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 19A57284C; Fri, 20 Sep 2013 23:06:24 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r8KN6NwF002610; Fri, 20 Sep 2013 23:06:23 GMT (envelope-from davide@svn.freebsd.org) Received: (from davide@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r8KN6Mo3002597; Fri, 20 Sep 2013 23:06:22 GMT (envelope-from davide@svn.freebsd.org) Message-Id: <201309202306.r8KN6Mo3002597@svn.freebsd.org> From: Davide Italiano Date: Fri, 20 Sep 2013 23:06:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r255745 - in head/sys: dev/hwpmc kern sys X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Sep 2013 23:06:24 -0000 Author: davide Date: Fri Sep 20 23:06:21 2013 New Revision: 255745 URL: http://svnweb.freebsd.org/changeset/base/255745 Log: Fix lc_lock/lc_unlock() support for rmlocks held in shared mode. With current lock classes KPI it was really difficult because there was no way to pass an rmtracker object to the lock/unlock routines. In order to accomplish the task, modify the aforementioned functions so that they can return (or pass as argument) an uinptr_t, which is in the rm case used to hold a pointer to struct rm_priotracker for current thread. As an added bonus, this fixes rm_sleep() in the rm shared case, which right now can communicate priotracker structure between lc_unlock()/lc_lock(). Suggested by: jhb Reviewed by: jhb Approved by: re (delphij) Modified: head/sys/dev/hwpmc/hwpmc_mod.c head/sys/kern/kern_condvar.c head/sys/kern/kern_lock.c head/sys/kern/kern_mutex.c head/sys/kern/kern_rmlock.c head/sys/kern/kern_rwlock.c head/sys/kern/kern_sx.c head/sys/kern/kern_synch.c head/sys/sys/lock.h Modified: head/sys/dev/hwpmc/hwpmc_mod.c ============================================================================== --- head/sys/dev/hwpmc/hwpmc_mod.c Fri Sep 20 22:59:22 2013 (r255744) +++ head/sys/dev/hwpmc/hwpmc_mod.c Fri Sep 20 23:06:21 2013 (r255745) @@ -2027,6 +2027,7 @@ pmc_allocate_owner_descriptor(struct pro /* allocate space for N pointers and one descriptor struct */ po = malloc(sizeof(struct pmc_owner), M_PMC, M_WAITOK|M_ZERO); po->po_owner = p; + LIST_INIT(&po->po_pmcs); LIST_INSERT_HEAD(poh, po, po_next); /* insert into hash table */ TAILQ_INIT(&po->po_logbuffers); @@ -2152,6 +2153,7 @@ pmc_allocate_pmc_descriptor(void) struct pmc *pmc; pmc = malloc(sizeof(struct pmc), M_PMC, M_WAITOK|M_ZERO); + LIST_INIT(&pmc->pm_targets); PMCDBG(PMC,ALL,1, "allocate-pmc -> pmc=%p", pmc); Modified: head/sys/kern/kern_condvar.c ============================================================================== --- head/sys/kern/kern_condvar.c Fri Sep 20 22:59:22 2013 (r255744) +++ head/sys/kern/kern_condvar.c Fri Sep 20 23:06:21 2013 (r255745) @@ -97,7 +97,7 @@ _cv_wait(struct cv *cvp, struct lock_obj WITNESS_SAVE_DECL(lock_witness); struct lock_class *class; struct thread *td; - int lock_state; + uintptr_t lock_state; td = curthread; lock_state = 0; @@ -214,7 +214,8 @@ _cv_wait_sig(struct cv *cvp, struct lock WITNESS_SAVE_DECL(lock_witness); struct lock_class *class; struct thread *td; - int lock_state, rval; + uintptr_t lock_state; + int rval; td = curthread; lock_state = 0; Modified: head/sys/kern/kern_lock.c ============================================================================== --- head/sys/kern/kern_lock.c Fri Sep 20 22:59:22 2013 (r255744) +++ head/sys/kern/kern_lock.c Fri Sep 20 23:06:21 2013 (r255745) @@ -142,12 +142,12 @@ static void assert_lockmgr(const struct #ifdef DDB static void db_show_lockmgr(const struct lock_object *lock); #endif -static void lock_lockmgr(struct lock_object *lock, int how); +static void lock_lockmgr(struct lock_object *lock, uintptr_t how); #ifdef KDTRACE_HOOKS static int owner_lockmgr(const struct lock_object *lock, struct thread **owner); #endif -static int unlock_lockmgr(struct lock_object *lock); +static uintptr_t unlock_lockmgr(struct lock_object *lock); struct lock_class lock_class_lockmgr = { .lc_name = "lockmgr", @@ -350,13 +350,13 @@ assert_lockmgr(const struct lock_object } static void -lock_lockmgr(struct lock_object *lock, int how) +lock_lockmgr(struct lock_object *lock, uintptr_t how) { panic("lockmgr locks do not support sleep interlocking"); } -static int +static uintptr_t unlock_lockmgr(struct lock_object *lock) { Modified: head/sys/kern/kern_mutex.c ============================================================================== --- head/sys/kern/kern_mutex.c Fri Sep 20 22:59:22 2013 (r255744) +++ head/sys/kern/kern_mutex.c Fri Sep 20 23:06:21 2013 (r255745) @@ -101,14 +101,14 @@ static void assert_mtx(const struct lock #ifdef DDB static void db_show_mtx(const struct lock_object *lock); #endif -static void lock_mtx(struct lock_object *lock, int how); -static void lock_spin(struct lock_object *lock, int how); +static void lock_mtx(struct lock_object *lock, uintptr_t how); +static void lock_spin(struct lock_object *lock, uintptr_t how); #ifdef KDTRACE_HOOKS static int owner_mtx(const struct lock_object *lock, struct thread **owner); #endif -static int unlock_mtx(struct lock_object *lock); -static int unlock_spin(struct lock_object *lock); +static uintptr_t unlock_mtx(struct lock_object *lock); +static uintptr_t unlock_spin(struct lock_object *lock); /* * Lock classes for sleep and spin mutexes. @@ -154,20 +154,20 @@ assert_mtx(const struct lock_object *loc } void -lock_mtx(struct lock_object *lock, int how) +lock_mtx(struct lock_object *lock, uintptr_t how) { mtx_lock((struct mtx *)lock); } void -lock_spin(struct lock_object *lock, int how) +lock_spin(struct lock_object *lock, uintptr_t how) { panic("spin locks can only use msleep_spin"); } -int +uintptr_t unlock_mtx(struct lock_object *lock) { struct mtx *m; @@ -178,7 +178,7 @@ unlock_mtx(struct lock_object *lock) return (0); } -int +uintptr_t unlock_spin(struct lock_object *lock) { Modified: head/sys/kern/kern_rmlock.c ============================================================================== --- head/sys/kern/kern_rmlock.c Fri Sep 20 22:59:22 2013 (r255744) +++ head/sys/kern/kern_rmlock.c Fri Sep 20 23:06:21 2013 (r255745) @@ -77,11 +77,11 @@ static void assert_rm(const struct lock_ #ifdef DDB static void db_show_rm(const struct lock_object *lock); #endif -static void lock_rm(struct lock_object *lock, int how); +static void lock_rm(struct lock_object *lock, uintptr_t how); #ifdef KDTRACE_HOOKS static int owner_rm(const struct lock_object *lock, struct thread **owner); #endif -static int unlock_rm(struct lock_object *lock); +static uintptr_t unlock_rm(struct lock_object *lock); struct lock_class lock_class_rm = { .lc_name = "rm", @@ -118,34 +118,61 @@ assert_rm(const struct lock_object *lock rm_assert((const struct rmlock *)lock, what); } -/* - * These do not support read locks because it would be hard to make - * the tracker work correctly with the current lock_class API as you - * would need to have the tracker pointer available when calling - * rm_rlock() in lock_rm(). - */ static void -lock_rm(struct lock_object *lock, int how) +lock_rm(struct lock_object *lock, uintptr_t how) { struct rmlock *rm; + struct rm_priotracker *tracker; rm = (struct rmlock *)lock; - if (how) + if (how == 0) rm_wlock(rm); -#ifdef INVARIANTS - else - panic("lock_rm called in read mode"); -#endif + else { + tracker = (struct rm_priotracker *)how; + rm_rlock(rm, tracker); + } } -static int +static uintptr_t unlock_rm(struct lock_object *lock) { + struct thread *td; + struct pcpu *pc; struct rmlock *rm; + struct rm_queue *queue; + struct rm_priotracker *tracker; + uintptr_t how; rm = (struct rmlock *)lock; - rm_wunlock(rm); - return (1); + tracker = NULL; + how = 0; + rm_assert(rm, RA_LOCKED | RA_NOTRECURSED); + if (rm_wowned(rm)) + rm_wunlock(rm); + else { + /* + * Find the right rm_priotracker structure for curthread. + * The guarantee about its uniqueness is given by the fact + * we already asserted the lock wasn't recursively acquired. + */ + critical_enter(); + td = curthread; + pc = pcpu_find(curcpu); + for (queue = pc->pc_rm_queue.rmq_next; + queue != &pc->pc_rm_queue; queue = queue->rmq_next) { + tracker = (struct rm_priotracker *)queue; + if ((tracker->rmp_rmlock == rm) && + (tracker->rmp_thread == td)) { + how = (uintptr_t)tracker; + break; + } + } + KASSERT(tracker != NULL, + ("rm_priotracker is non-NULL when lock held in read mode")); + critical_exit(); + rm_runlock(rm, tracker); + } + return (how); } #ifdef KDTRACE_HOOKS Modified: head/sys/kern/kern_rwlock.c ============================================================================== --- head/sys/kern/kern_rwlock.c Fri Sep 20 22:59:22 2013 (r255744) +++ head/sys/kern/kern_rwlock.c Fri Sep 20 23:06:21 2013 (r255745) @@ -83,11 +83,11 @@ SYSCTL_INT(_debug_rwlock, OID_AUTO, loop static void db_show_rwlock(const struct lock_object *lock); #endif static void assert_rw(const struct lock_object *lock, int what); -static void lock_rw(struct lock_object *lock, int how); +static void lock_rw(struct lock_object *lock, uintptr_t how); #ifdef KDTRACE_HOOKS static int owner_rw(const struct lock_object *lock, struct thread **owner); #endif -static int unlock_rw(struct lock_object *lock); +static uintptr_t unlock_rw(struct lock_object *lock); struct lock_class lock_class_rw = { .lc_name = "rw", @@ -141,7 +141,7 @@ assert_rw(const struct lock_object *lock } void -lock_rw(struct lock_object *lock, int how) +lock_rw(struct lock_object *lock, uintptr_t how) { struct rwlock *rw; @@ -152,7 +152,7 @@ lock_rw(struct lock_object *lock, int ho rw_rlock(rw); } -int +uintptr_t unlock_rw(struct lock_object *lock) { struct rwlock *rw; Modified: head/sys/kern/kern_sx.c ============================================================================== --- head/sys/kern/kern_sx.c Fri Sep 20 22:59:22 2013 (r255744) +++ head/sys/kern/kern_sx.c Fri Sep 20 23:06:21 2013 (r255745) @@ -116,11 +116,11 @@ static void assert_sx(const struct lock_ #ifdef DDB static void db_show_sx(const struct lock_object *lock); #endif -static void lock_sx(struct lock_object *lock, int how); +static void lock_sx(struct lock_object *lock, uintptr_t how); #ifdef KDTRACE_HOOKS static int owner_sx(const struct lock_object *lock, struct thread **owner); #endif -static int unlock_sx(struct lock_object *lock); +static uintptr_t unlock_sx(struct lock_object *lock); struct lock_class lock_class_sx = { .lc_name = "sx", @@ -156,7 +156,7 @@ assert_sx(const struct lock_object *lock } void -lock_sx(struct lock_object *lock, int how) +lock_sx(struct lock_object *lock, uintptr_t how) { struct sx *sx; @@ -167,7 +167,7 @@ lock_sx(struct lock_object *lock, int ho sx_slock(sx); } -int +uintptr_t unlock_sx(struct lock_object *lock) { struct sx *sx; Modified: head/sys/kern/kern_synch.c ============================================================================== --- head/sys/kern/kern_synch.c Fri Sep 20 22:59:22 2013 (r255744) +++ head/sys/kern/kern_synch.c Fri Sep 20 23:06:21 2013 (r255745) @@ -157,7 +157,8 @@ _sleep(void *ident, struct lock_object * struct thread *td; struct proc *p; struct lock_class *class; - int catch, lock_state, pri, rval, sleepq_flags; + uintptr_t lock_state; + int catch, pri, rval, sleepq_flags; WITNESS_SAVE_DECL(lock_witness); td = curthread; Modified: head/sys/sys/lock.h ============================================================================== --- head/sys/sys/lock.h Fri Sep 20 22:59:22 2013 (r255744) +++ head/sys/sys/lock.h Fri Sep 20 23:06:21 2013 (r255745) @@ -56,13 +56,14 @@ struct thread; */ struct lock_class { - const char *lc_name; - u_int lc_flags; - void (*lc_assert)(const struct lock_object *lock, int what); - void (*lc_ddb_show)(const struct lock_object *lock); - void (*lc_lock)(struct lock_object *lock, int how); - int (*lc_owner)(const struct lock_object *lock, struct thread **owner); - int (*lc_unlock)(struct lock_object *lock); + const char *lc_name; + u_int lc_flags; + void (*lc_assert)(const struct lock_object *lock, int what); + void (*lc_ddb_show)(const struct lock_object *lock); + void (*lc_lock)(struct lock_object *lock, uintptr_t how); + int (*lc_owner)(const struct lock_object *lock, + struct thread **owner); + uintptr_t (*lc_unlock)(struct lock_object *lock); }; #define LC_SLEEPLOCK 0x00000001 /* Sleep lock. */