Skip to content

Commit

Permalink
IB/fmr: ib_flush_fmr_pool() may wait too long
Browse files Browse the repository at this point in the history
ib_flush_fmr_pool() stashes away the request generation number
properly, but then goes ahead and rereads it every time it tests
whether the flush generation number has caught up.  This means that
there is a theoretical possibility of livelock, if the request
generation number keeps getting bumped and the flush generation number
never catches up.  The fix is simple: use the request generation
number read at the beginning of the function.

Also, atomic_inc() followed by atomic_read() can be replaced with
atomic_int_return().  There's no real requirement for atomicity here
but we might as well shrink the code.

This bug was discovered using David Binderman's list of "set but never
used" warnings from icc.

Signed-off-by: Roland Dreier <rolandd@cisco.com>
  • Loading branch information
Roland Dreier committed Dec 12, 2006
1 parent e103650 commit f47e22c
Showing 1 changed file with 2 additions and 10 deletions.
12 changes: 2 additions & 10 deletions drivers/infiniband/core/fmr_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,20 +394,12 @@ EXPORT_SYMBOL(ib_destroy_fmr_pool);
*/
int ib_flush_fmr_pool(struct ib_fmr_pool *pool)
{
int serial;

atomic_inc(&pool->req_ser);
/*
* It's OK if someone else bumps req_ser again here -- we'll
* just wait a little longer.
*/
serial = atomic_read(&pool->req_ser);
int serial = atomic_inc_return(&pool->req_ser);

wake_up_process(pool->thread);

if (wait_event_interruptible(pool->force_wait,
atomic_read(&pool->flush_ser) -
atomic_read(&pool->req_ser) >= 0))
atomic_read(&pool->flush_ser) - serial >= 0))
return -EINTR;

return 0;
Expand Down

0 comments on commit f47e22c

Please sign in to comment.