linux/include
David Howells cb65537ee1 Add wait_on_atomic_t() and wake_up_atomic_t()
Add wait_on_atomic_t() and wake_up_atomic_t() to indicate became-zero events on
atomic_t types.  This uses the bit-wake waitqueue table.  The key is set to a
value outside of the number of bits in a long so that wait_on_bit() won't be
woken up accidentally.

What I'm using this for is: in a following patch I add a counter to struct
fscache_cookie to count the number of outstanding operations that need access
to netfs data.  The way this works is:

 (1) When a cookie is allocated, the counter is initialised to 1.

 (2) When an operation wants to access netfs data, it calls atomic_inc_unless()
     to increment the counter before it does so.  If it was 0, then the counter
     isn't incremented, the operation isn't permitted to access the netfs data
     (which might by this point no longer exist) and the operation aborts in
     some appropriate manner.

 (3) When an operation finishes with the netfs data, it decrements the counter
     and if it reaches 0, calls wake_up_atomic_t() on it - the assumption being
     that it was the last blocker.

 (4) When a cookie is released, the counter is decremented and the releaser
     uses wait_on_atomic_t() to wait for the counter to become 0 - which should
     indicate no one is using the netfs data any longer.  The netfs data can
     then be destroyed.

There are some alternatives that I have thought of and that have been suggested
by Tejun Heo:

 (A) Using wait_on_bit() to wait on a bit in the counter.  This doesn't work
     because if that bit happens to be 0 then the wait won't happen - even if
     the counter is non-zero.

 (B) Using wait_on_bit() to wait on a flag elsewhere which is cleared when the
     counter reaches 0.  Such a flag would be redundant and would add
     complexity.

 (C) Adding a waitqueue to fscache_cookie - this would expand that struct by
     several words for an event that happens just once in each cookie's
     lifetime.  Further, cookies are generally per-file so there are likely to
     be a lot of them.

 (D) Similar to (C), but add a pointer to a waitqueue in the cookie instead of
     a waitqueue.  This would add single word per cookie and so would be less
     of an expansion - but still an expansion.

 (E) Adding a static waitqueue to the fscache module.  Generally this would be
     fine, but under certain circumstances many cookies will all get added at
     the same time (eg. NFS umount, cache withdrawal) thereby presenting
     scaling issues.  Note that the wait may be significant as disk I/O may be
     in progress.

So, I think reusing the wait_on_bit() waitqueue set is reasonable.  I don't
make much use of the waitqueue I need on a per-cookie basis, but sometimes I
have a huge flood of the cookies to deal with.

I also don't want to add a whole new set of global waitqueue tables
specifically for the dec-to-0 event if I can reuse the bit tables.

Signed-off-by: David Howells <dhowells@redhat.com>
Tested-By: Milosz Tanski <milosz@adfin.com>
Acked-by: Jeff Layton <jlayton@redhat.com>
2013-05-15 13:50:38 +01:00
..
acpi Merge branch 'acpi-assorted' 2013-04-28 01:54:08 +02:00
asm-generic Merge branch 'timers-nohz-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2013-05-05 13:23:27 -07:00
clocksource ARM: late Exynos multiplatform changes 2013-05-07 11:28:42 -07:00
crypto crypto: sha512 - Expose generic sha512 routine to be callable from other modules 2013-04-25 21:00:57 +08:00
drm Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux 2013-05-13 07:59:59 -07:00
dt-bindings ARM: dt: create a DT header for the GIC 2013-04-05 12:23:24 -06:00
keys
linux Add wait_on_atomic_t() and wake_up_atomic_t() 2013-05-15 13:50:38 +01:00
math-emu
media Merge branch 'topic/omap3isp' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media 2013-05-01 09:57:04 -07:00
memory
misc
net ipv6: do not clear pinet6 field 2013-05-11 16:26:38 -07:00
pcmcia
ras
rdma
rxrpc
scsi Merge branch 'postmerge' into for-linus 2013-05-10 07:54:01 -07:00
sound sound fixes for v3.10-rc1 2013-05-10 07:51:56 -07:00
target iscsi-target: Add iscsit_transport API template 2013-04-25 01:05:26 -07:00
trace Fixed regressions (two stability regressions and a performance 2013-05-14 09:30:54 -07:00
uapi Merge git://git.infradead.org/users/eparis/audit 2013-05-11 14:29:11 -07:00
video Merge branch 'late/clksrc' into late/cleanup 2013-05-06 23:43:45 +02:00
xen Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2013-05-01 14:08:52 -07:00
Kbuild UAPI: remove empty Kbuild files 2013-04-30 17:04:09 -07:00