SMP question w.r.t. reading kernel variables
John Baldwin
jhb at freebsd.org
Mon Apr 18 16:56:29 UTC 2011
On Sunday, April 17, 2011 3:49:48 pm Rick Macklem wrote:
> Hi,
>
> I should know the answer to this, but... When reading a global kernel
> variable, where its modifications are protected by a mutex, is it
> necessary to get the mutex lock to just read its value?
>
> For example:
> A if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0)
> return (EPERM);
> versus
> B MNT_ILOCK(mp);
> if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
> MNT_IUNLOCK(mp);
> return (EPERM);
> }
> MNT_IUNLOCK(mp);
>
> My hunch is that B is necessary if you need an up-to-date value
> for the variable (mp->mnt_kern_flag in this case).
>
> Is that correct?
You already have good followups from Attilio and Kostik, but one thing to keep
in mind is that if a simple read is part of a larger "atomic operation" then
it may still need a lock. In this case Kostik points out that another lock
prevents updates to mnt_kern_flag so that this is safe. However, if not for
that you would need to consider the case that another thread sets the flag on
the next instruction. Even the B case above might still have that problem
since you drop the lock right after checking it and the rest of the function
is implicitly assuming the flag is never set perhaps (or it needs to handle
the case that the flag might become set in the future while MNT_ILOCK() is
dropped).
One way you can make that code handle that race is by holding MNT_ILOCK()
around the entire function, but that approach is often only suitable for a
simple routine.
--
John Baldwin
More information about the freebsd-hackers
mailing list