Hello,
On Tue, 15 Aug 2017, Eric Dumazet wrote:
> Please try this :
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index
> 16a1a4c4eb57fa1147f230916e2e62e18ef89562..95e0d7702029b583de8229e3c3eb923f6395b072
> 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -991,14 +991,18 @@ static void neigh_timer_handler(unsigned long arg)
>
> int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
> {
> - int rc;
> bool immediate_probe = false;
> + int rc;
> +
> + /* We _should_ test this under write_lock_bh(&neigh->lock),
> + * but this is too costly.
> + */
> + if (READ_ONCE(neigh->nud_state) & (NUD_CONNECTED | NUD_DELAY |
> NUD_PROBE))
> + return 0;
The same fast check is already done in the only caller,
neigh_event_send. Now we risk to enter the
'if (!(neigh->nud_state & (NUD_STALE | NUD_INCOMPLETE))) {' block...
> write_lock_bh(&neigh->lock);
>
> rc = 0;
> - if (neigh->nud_state & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE))
> - goto out_unlock_bh;
> if (neigh->dead)
> goto out_dead;
Regards
--
Julian Anastasov <[email protected]>