Fix callout_init_rm() in the shared case, allocating storage for 'struct
rm_priotracker' directly in the softclock thread. Now consumers can pass CALLOUT_SHAREDLOCK flag to callout initialization routine safely. The choice of the already existing flags instead of special casing shared rmlocks is done to prevent consumer footshooting. Suggested by: jhb Reviewed by: jhb Approved by: re (delphij)
This commit is contained in:
parent
cabba8f230
commit
1f96759fb1
@ -597,11 +597,13 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc,
|
||||
#endif
|
||||
int direct)
|
||||
{
|
||||
struct rm_priotracker tracker;
|
||||
void (*c_func)(void *);
|
||||
void *c_arg;
|
||||
struct lock_class *class;
|
||||
struct lock_object *c_lock;
|
||||
int c_flags, sharedlock;
|
||||
uintptr_t lock_status;
|
||||
int c_flags;
|
||||
#ifdef SMP
|
||||
struct callout_cpu *new_cc;
|
||||
void (*new_func)(void *);
|
||||
@ -620,7 +622,13 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc,
|
||||
(CALLOUT_PENDING | CALLOUT_ACTIVE),
|
||||
("softclock_call_cc: pend|act %p %x", c, c->c_flags));
|
||||
class = (c->c_lock != NULL) ? LOCK_CLASS(c->c_lock) : NULL;
|
||||
sharedlock = (c->c_flags & CALLOUT_SHAREDLOCK) ? 0 : 1;
|
||||
lock_status = 0;
|
||||
if (c->c_flags & CALLOUT_SHAREDLOCK) {
|
||||
if (class == &lock_class_rm)
|
||||
lock_status = (uintptr_t)&tracker;
|
||||
else
|
||||
lock_status = 1;
|
||||
}
|
||||
c_lock = c->c_lock;
|
||||
c_func = c->c_func;
|
||||
c_arg = c->c_arg;
|
||||
@ -633,7 +641,7 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc,
|
||||
cc->cc_exec_entity[direct].cc_cancel = false;
|
||||
CC_UNLOCK(cc);
|
||||
if (c_lock != NULL) {
|
||||
class->lc_lock(c_lock, sharedlock);
|
||||
class->lc_lock(c_lock, lock_status);
|
||||
/*
|
||||
* The callout may have been cancelled
|
||||
* while we switched locks.
|
||||
|
Loading…
Reference in New Issue
Block a user