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