diff options
author | harti <harti@FreeBSD.org> | 2003-10-30 16:19:50 +0000 |
---|---|---|
committer | harti <harti@FreeBSD.org> | 2003-10-30 16:19:50 +0000 |
commit | 981771fa4bea53d61d0e6c43e3588c73ef1d1253 (patch) | |
tree | f962b01832d644d7bae6920bb99bfc3226bdf9c9 /sys | |
parent | d959b1ec080147ee1d619340e77a08cf548fe501 (diff) | |
download | FreeBSD-src-981771fa4bea53d61d0e6c43e3588c73ef1d1253.zip FreeBSD-src-981771fa4bea53d61d0e6c43e3588c73ef1d1253.tar.gz |
Explain why the lock-free allocation algorithm is safe in our case
while beeing not safe in the general case. Thanks to David Schultz
<das@freebsd.org> for help.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/hatm/if_hatm_intr.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/sys/dev/hatm/if_hatm_intr.c b/sys/dev/hatm/if_hatm_intr.c index 14912ce3..bcc42d6 100644 --- a/sys/dev/hatm/if_hatm_intr.c +++ b/sys/dev/hatm/if_hatm_intr.c @@ -91,6 +91,24 @@ static void hatm_mbuf_page_alloc(struct hatm_softc *sc, u_int group); /* * Free an external mbuf to a list. We use atomic functions so that * we don't need a mutex for the list. + * + * Note that in general this algorithm is not safe when multiple readers + * and writers are present. To cite from a mail from David Schultz + * <das@freebsd.org>: + * + * It looks like this is subject to the ABA problem. For instance, + * suppose X, Y, and Z are the top things on the freelist and a + * thread attempts to make an allocation. You set buf to X and load + * buf->link (Y) into a register. Then the thread get preempted, and + * another thread allocates both X and Y, then frees X. When the + * original thread gets the CPU again, X is still on top of the + * freelist, so the atomic operation succeeds. However, the atomic + * op places Y on top of the freelist, even though Y is no longer + * free. + * + * We are, however sure that we have only one thread that ever allocates + * buffers because the only place we're call from is the interrupt handler. + * Under these circumstances the code looks safe. */ __inline void hatm_ext_free(struct mbufx_free **list, struct mbufx_free *buf) |