svn commit: r254703 - in head: share/man/man9 sys/sys
John Baldwin
jhb at freebsd.org
Thu Sep 19 18:17:07 UTC 2013
On Wednesday, September 18, 2013 11:06:33 am Davide Italiano wrote:
> On Thu, Sep 12, 2013 at 4:08 PM, John Baldwin <jhb at freebsd.org> wrote:
> > Hmm, I think I had envisioned something a bit simpler. Namely, I would
> > change lc_lock/lc_unlock to return a uintptr_t instead of an int, and
> > I would then change lc_unlock for an rm lock to return a pointer to the
> > current thread's tracker as the 'how' and 0 for a write lock. Note
> > that you have to use the existing tracker to make this work correctly
> > for the sleep case where you unlock/lock.
> >
>
> Well, your solution is indeed a lot simpler :)
> Here's a patch that implements it:
> http://people.freebsd.org/~davide/review/rmshared.diff
>
> Some (more or less relevant) observations:
> -> I realized that before this change lc_unlock() for rmlocks, i.e.
> unlock_rm(), returned 1 for exclusive lock and panic'ed otherwise,
> while all the other primitives returned 0 for exclusive lock. Not sure
> if this was intentional or just an oversight, but I changed it to
> return what other primitive did mostly (0 for excl,
> (uintptr_t)rm_tracker for shared).
That's fine.
> -> In order to get the rm_priotracker structure for curthread (which I
> think is unique as long as we assert curthread is not recursively
> acquiring this lock) I just traversed the pc->pc_rm_queue. Maybe it's
> not the most efficient solution here, but I think is correct.
Yes, it should be similar to rm_trackers_present().
> -> I think that only lc_unlock() return type need to be changed from
> 'int' to 'uintptr_t'. lc_lock() type can stay void as it is right now.
> But I think you were talking about "how" argument of lc_lock() and not
> return type, probably.
Yes, I meant the 'how' arg to lc_lock().
The patch looks good, just one minor nit:
- 'rval' in _cv_wait_sig() in kern_condvar.c should stay an 'int'
> > However, if you make my suggested change to make the 'how' a uintptr_t
> > that passes the tracker you can actually do this in the callout case:
> >
> > struct rm_priotracker tracker;
> > uintptr_t how;
> >
> > how = 0;
> > if (flags & CALLOUT_SHAREDLOCK)
> > how = 1;
> > else if (flags & CALLOUT_SHAREDRM)
> > how = (uintptr_t)&tracker;
> > ...
> >
> > class->lc_lock(lock, how);
> >
> > Now, it would be even nicer to make prevent footshooting perhaps by
> > checking the lock class directly:
> >
> > how = 0;
> > if (flags & CALLOUT_SHAREDLOCK) {
> > if (class == &lock_class_rm || class == &lock_class_rm_sleepable)
> > how = (uintptr_t)&tracker;
> > else
> > how = 1;
> > }
> >
> > --
> > John Baldwin
>
> This other patch just puts your code into kern_timeout.c
> I also removed the check for lock_class_rm_sleepable as callout_init()
> should catch this earlier.
> http://people.freebsd.org/~davide/review/callout_sharedrm.diff
This looks good. My only suggestion would be to rename 'sharedlock' to
'how' or maybe 'lock_state'.
--
John Baldwin
More information about the svn-src-head
mailing list