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.
This commit is contained in:
Robert Watson 2009-05-29 10:52:37 +00:00
parent e257fff483
commit 1a109c1cb0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=193030
6 changed files with 80 additions and 18 deletions

View File

@ -32,6 +32,7 @@
.Sh NAME .Sh NAME
.Nm rmlock , .Nm rmlock ,
.Nm rm_init , .Nm rm_init ,
.Nm rm_init_flags ,
.Nm rm_destroy , .Nm rm_destroy ,
.Nm rm_rlock , .Nm rm_rlock ,
.Nm rm_wlock , .Nm rm_wlock ,
@ -45,7 +46,9 @@
.In sys/lock.h .In sys/lock.h
.In sys/rmlock.h .In sys/rmlock.h
.Ft void .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 .Ft void
.Fn rm_destroy "struct rmlock *rm" .Fn rm_destroy "struct rmlock *rm"
.Ft void .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. option, however exclusive locks are not allowed to recurse.
.Ss Macros and Functions .Ss Macros and Functions
.Bl -tag -width indent .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 Initialize structure located at
.Fa rm .Fa rm
as mostly reader lock, described by as mostly reader lock, described by
.Fa name . .Fa name .
Optionally allowing readers to recurse by setting
.Dv LO_RECURSABLE
in
.Fa opts .
The name description is used solely for debugging purposes. The name description is used solely for debugging purposes.
This function must be called before any other operations This function must be called before any other operations
on the lock. 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" .It Fn rm_rlock "struct rmlock *rm" "struct rm_priotracker* tracker"
Lock Lock
.Fa rm .Fa rm

View File

@ -394,7 +394,7 @@ osd_init(void *arg __unused)
osd_nslots[i] = 0; osd_nslots[i] = 0;
LIST_INIT(&osd_list[i]); LIST_INIT(&osd_list[i]);
sx_init(&osd_module_lock[i], "osd_module"); 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); mtx_init(&osd_list_lock[i], "osd_list", NULL, MTX_DEF);
osd_destructors[i] = NULL; osd_destructors[i] = NULL;
osd_methods[i] = NULL; osd_methods[i] = NULL;

View File

@ -188,14 +188,26 @@ rm_cleanIPI(void *arg)
} }
void 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; rm->rm_noreadtoken = 1;
LIST_INIT(&rm->rm_activeReaders); LIST_INIT(&rm->rm_activeReaders);
mtx_init(&rm->rm_lock, name, "RM_MTX",MTX_NOWITNESS); mtx_init(&rm->rm_lock, name, "rmlock_mtx", MTX_NOWITNESS);
lock_init(&rm->lock_object, &lock_class_rm, name, NULL, lock_init(&rm->lock_object, &lock_class_rm, name, NULL, liflags);
(opts & LO_RECURSABLE)| LO_WITNESS); }
void
rm_init(struct rmlock *rm, const char *name)
{
rm_init_flags(rm, name, 0);
} }
void void
@ -216,9 +228,17 @@ rm_wowned(struct rmlock *rm)
void void
rm_sysinit(void *arg) rm_sysinit(void *arg)
{ {
struct rm_args *args = 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 static void

View File

@ -95,7 +95,7 @@ struct pfil_head *pfil_head_get(int, u_long);
#define PFIL_HOOKED(p) ((p)->ph_nhooks > 0) #define PFIL_HOOKED(p) ((p)->ph_nhooks > 0)
#define PFIL_LOCK_INIT(p) \ #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_LOCK_DESTROY(p) rm_destroy(&(p)->ph_lock)
#define PFIL_RLOCK(p, t) rm_rlock(&(p)->ph_lock, (t)) #define PFIL_RLOCK(p, t) rm_rlock(&(p)->ph_lock, (t))
#define PFIL_WLOCK(p) rm_wlock(&(p)->ph_lock) #define PFIL_WLOCK(p) rm_wlock(&(p)->ph_lock)

View File

@ -289,7 +289,7 @@ mac_init(void)
mac_labelzone_init(); mac_labelzone_init();
#ifndef MAC_STATIC #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"); sx_init(&mac_policy_sx, "mac_policy_sx");
#endif #endif
} }

View File

@ -38,10 +38,18 @@
#ifdef _KERNEL #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); void rm_destroy(struct rmlock *rm);
int rm_wowned(struct rmlock *rm); int rm_wowned(struct rmlock *rm);
void rm_sysinit(void *arg); 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_wlock_debug(struct rmlock *rm, const char *file, int line);
void _rm_wunlock_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 rm_args {
struct rmlock *ra_rm; struct rmlock *ra_rm;
const char *ra_desc; const char *ra_desc;
};
struct rm_args_flags {
struct rmlock *ra_rm;
const char *ra_desc;
int ra_opts; int ra_opts;
}; };
#define RM_SYSINIT(name, rm, desc, opts) \ #define RM_SYSINIT(name, rm, desc) \
static struct rm_args name##_args = { \ static struct rm_args name##_args = { \
(rm), \ (rm), \
(desc), \ (desc), \
(opts), \
}; \ }; \
SYSINIT(name##_rm_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ SYSINIT(name##_rm_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
rm_sysinit, &name##_args); \ rm_sysinit, &name##_args); \
SYSUNINIT(name##_rm_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ SYSUNINIT(name##_rm_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
rm_destroy, (rm)) 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 /* _KERNEL */
#endif /* !_SYS_RMLOCK_H_ */ #endif /* !_SYS_RMLOCK_H_ */