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 _______________________________________________ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"