ib_ipoib: Fixing issue with delayed work running after child is killed.
This patch addresses a common issues in the ipoib driver.
it has the following form:
Flow 1:
1) if (!test_bit(IPOIB_STOP_NEIGH_GC, &priv->flags))
2) queue_delayed_work(ipoib_workqueue, &priv->neigh_reap_task,
arp_tbl.gc_interval);
Flow 2:
3) set_bit(IPOIB_STOP_NEIGH_GC, &priv->flags);
4) cancel_delayed_work(&priv->neigh_reap_task);
The Linux Kernel (Unlike the ESX Kernel ) is preemptable, which
means that the this sequence of actions is feasible.
1 flow 1
3 flow 2
4 flow 2
2 flow 1
Now the effect of this sequence is that line #4 has no defacto effect.
The work will be rescheduled and will run once again and only then
will see that the bit value has changed.
In the IPoIB driver this is benign because after each
"set and cancel" sequence, flush is called which waits until the
second run ends. This is not the case with the neigh_reap_task
which does cancel without flush.
took from 1.5.3 :
b7abd8b0b071f0422b0c1018804033ee1b542eca
by Alex Markuze
Signed-off-by: Erez Shitrit <erezsh@mellanox.com>
(Ported from Mellanox OFED 2.4)
Signed-off-by: Mukesh Kacker <mukesh.kacker@oracle.com>