Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Apr 2011 08:31:33 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-hackers@freebsd.org
Cc:        Rick Macklem <rmacklem@uoguelph.ca>
Subject:   Re: SMP question w.r.t. reading kernel variables
Message-ID:  <201104180831.33796.jhb@freebsd.org>
In-Reply-To: <397135152.167477.1303069788579.JavaMail.root@erie.cs.uoguelph.ca>
References:  <397135152.167477.1303069788579.JavaMail.root@erie.cs.uoguelph.ca>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104180831.33796.jhb>