From 1a109c1cb0ef3176d2d32e11d8a51d48248bd2e5 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Fri, 29 May 2009 10:52:37 +0000 Subject: [PATCH] Make the rmlock(9) interface a bit more like the rwlock(9) interface: - Add rm_init_flags() and accept extended options only for that variation. - Add a flags space specifically for rm_init_flags(), rather than borrowing the lock_init() flag space. - Define flag RM_RECURSE to use instead of LO_RECURSABLE. - Define flag RM_NOWITNESS to allow an rmlock to be exempt from WITNESS checking; this wasn't possible previously as rm_init() always passed LO_WITNESS when initializing an rmlock's struct lock. - Add RM_SYSINIT_FLAGS(). - Rename embedded mutex in rmlocks to make it more obvious what it is. - Update consumers. - Update man page. --- share/man/man9/rmlock.9 | 30 ++++++++++++++++++++++++------ sys/kern/kern_osd.c | 2 +- sys/kern/kern_rmlock.c | 32 ++++++++++++++++++++++++++------ sys/net/pfil.h | 2 +- sys/security/mac/mac_framework.c | 2 +- sys/sys/rmlock.h | 30 +++++++++++++++++++++++++++--- 6 files changed, 80 insertions(+), 18 deletions(-) diff --git a/share/man/man9/rmlock.9 b/share/man/man9/rmlock.9 index 1be822be340c..e99661d9f8b6 100644 --- a/share/man/man9/rmlock.9 +++ b/share/man/man9/rmlock.9 @@ -32,6 +32,7 @@ .Sh NAME .Nm rmlock , .Nm rm_init , +.Nm rm_init_flags , .Nm rm_destroy , .Nm rm_rlock , .Nm rm_wlock , @@ -45,7 +46,9 @@ .In sys/lock.h .In sys/rmlock.h .Ft void -.Fn rm_init "struct rmlock *rm" "const char *name" "int opts" +.Fn rm_init "struct rmlock *rm" "const char *name" +.Ft void +.Fn rm_init_flags "struct rmlock *rm" "const char *name" "int opts" .Ft void .Fn rm_destroy "struct rmlock *rm" .Ft void @@ -106,18 +109,33 @@ can recurse if the lock has been initialized with the option, however exclusive locks are not allowed to recurse. .Ss Macros and Functions .Bl -tag -width indent -.It Fn rm_init "struct rmlock *rm" "const char *name" "int opts" +.It Fn rm_init "struct rmlock *rm" "const char *name" Initialize structure located at .Fa rm as mostly reader lock, described by .Fa name . -Optionally allowing readers to recurse by setting -.Dv LO_RECURSABLE -in -.Fa opts . The name description is used solely for debugging purposes. This function must be called before any other operations on the lock. +.It Fn rm_init_flags "struct rmlock *rm" "const char *name" "int opts" +Initialize the rm lock just like the +.Fn rm_init +function, but specifying a set of optional flags to alter the +behaviour of +.Fa rm , +through the +.Fa opts +argument. +It contains one or more of the following flags: +.Bl -tag -width ".Dv RM_NOWITNESS" +.It Dv RM_NOWITNESS +Instruct +.Xr witness 4 +to ignore this lock. +.It Dv RM_RECURSE +Allow threads to recursively acquire exclusive locks for +.Fa rm . +.El .It Fn rm_rlock "struct rmlock *rm" "struct rm_priotracker* tracker" Lock .Fa rm diff --git a/sys/kern/kern_osd.c b/sys/kern/kern_osd.c index 2ce6b6bc5e38..184c4f00ba08 100644 --- a/sys/kern/kern_osd.c +++ b/sys/kern/kern_osd.c @@ -394,7 +394,7 @@ osd_init(void *arg __unused) osd_nslots[i] = 0; LIST_INIT(&osd_list[i]); sx_init(&osd_module_lock[i], "osd_module"); - rm_init(&osd_object_lock[i], "osd_object", 0); + rm_init(&osd_object_lock[i], "osd_object"); mtx_init(&osd_list_lock[i], "osd_list", NULL, MTX_DEF); osd_destructors[i] = NULL; osd_methods[i] = NULL; diff --git a/sys/kern/kern_rmlock.c b/sys/kern/kern_rmlock.c index 3d0a10df2f09..6b83caf11015 100644 --- a/sys/kern/kern_rmlock.c +++ b/sys/kern/kern_rmlock.c @@ -188,14 +188,26 @@ rm_cleanIPI(void *arg) } void -rm_init(struct rmlock *rm, const char *name, int opts) +rm_init_flags(struct rmlock *rm, const char *name, int opts) { + int liflags; + liflags = 0; + if (!(opts & RM_NOWITNESS)) + liflags |= LO_WITNESS; + if (opts & RM_RECURSE) + liflags |= LO_RECURSABLE; rm->rm_noreadtoken = 1; LIST_INIT(&rm->rm_activeReaders); - mtx_init(&rm->rm_lock, name, "RM_MTX",MTX_NOWITNESS); - lock_init(&rm->lock_object, &lock_class_rm, name, NULL, - (opts & LO_RECURSABLE)| LO_WITNESS); + mtx_init(&rm->rm_lock, name, "rmlock_mtx", MTX_NOWITNESS); + lock_init(&rm->lock_object, &lock_class_rm, name, NULL, liflags); +} + +void +rm_init(struct rmlock *rm, const char *name) +{ + + rm_init_flags(rm, name, 0); } void @@ -216,9 +228,17 @@ rm_wowned(struct rmlock *rm) void rm_sysinit(void *arg) { - struct rm_args *args = arg; - rm_init(args->ra_rm, args->ra_desc, args->ra_opts); + + rm_init(args->ra_rm, args->ra_desc); +} + +void +rm_sysinit_flags(void *arg) +{ + struct rm_args_flags *args = arg; + + rm_init_flags(args->ra_rm, args->ra_desc, args->ra_opts); } static void diff --git a/sys/net/pfil.h b/sys/net/pfil.h index 5db9e55486b3..48b1db860b65 100644 --- a/sys/net/pfil.h +++ b/sys/net/pfil.h @@ -95,7 +95,7 @@ struct pfil_head *pfil_head_get(int, u_long); #define PFIL_HOOKED(p) ((p)->ph_nhooks > 0) #define PFIL_LOCK_INIT(p) \ - rm_init(&(p)->ph_lock, "PFil hook read/write mutex", LO_RECURSABLE) + rm_init_flags(&(p)->ph_lock, "PFil hook read/write mutex", RM_RECURSE) #define PFIL_LOCK_DESTROY(p) rm_destroy(&(p)->ph_lock) #define PFIL_RLOCK(p, t) rm_rlock(&(p)->ph_lock, (t)) #define PFIL_WLOCK(p) rm_wlock(&(p)->ph_lock) diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c index 6a36b6bbdd02..6f675cb4cae8 100644 --- a/sys/security/mac/mac_framework.c +++ b/sys/security/mac/mac_framework.c @@ -289,7 +289,7 @@ mac_init(void) mac_labelzone_init(); #ifndef MAC_STATIC - rm_init(&mac_policy_rm, "mac_policy_rm", 0); + rm_init(&mac_policy_rm, "mac_policy_rm"); sx_init(&mac_policy_sx, "mac_policy_sx"); #endif } diff --git a/sys/sys/rmlock.h b/sys/sys/rmlock.h index 9167a1d97888..9766f670d2ae 100644 --- a/sys/sys/rmlock.h +++ b/sys/sys/rmlock.h @@ -38,10 +38,18 @@ #ifdef _KERNEL -void rm_init(struct rmlock *rm, const char *name, int opts); +/* + * Flags passed to rm_init(9). + */ +#define RM_NOWITNESS 0x00000001 +#define RM_RECURSE 0x00000002 + +void rm_init(struct rmlock *rm, const char *name); +void rm_init_flags(struct rmlock *rm, const char *name, int opts); void rm_destroy(struct rmlock *rm); int rm_wowned(struct rmlock *rm); void rm_sysinit(void *arg); +void rm_sysinit_flags(void *arg); void _rm_wlock_debug(struct rmlock *rm, const char *file, int line); void _rm_wunlock_debug(struct rmlock *rm, const char *file, int line); @@ -79,19 +87,35 @@ void _rm_runlock(struct rmlock *rm, struct rm_priotracker *tracker); struct rm_args { struct rmlock *ra_rm; const char *ra_desc; +}; + +struct rm_args_flags { + struct rmlock *ra_rm; + const char *ra_desc; int ra_opts; }; -#define RM_SYSINIT(name, rm, desc, opts) \ +#define RM_SYSINIT(name, rm, desc) \ static struct rm_args name##_args = { \ (rm), \ (desc), \ - (opts), \ }; \ SYSINIT(name##_rm_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ rm_sysinit, &name##_args); \ SYSUNINIT(name##_rm_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ rm_destroy, (rm)) + +#define RM_SYSINIT_FLAGS(name, rm, desc, opts) \ + static struct rm_args name##_args = { \ + (rm), \ + (desc), \ + (opts), \ + }; \ + SYSINIT(name##_rm_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ + rm_sysinit_flags, &name##_args); \ + SYSUNINIT(name##_rm_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ + rm_destroy, (rm)) + #endif /* _KERNEL */ #endif /* !_SYS_RMLOCK_H_ */