]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/packet/af_packet.c
Merge tag 'armsoc-dt' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux.git] / net / packet / af_packet.c
index 82a50e850245ec56d258687f8f2dcdd411603df6..53c1d41fb1c98219be5667214a6c05fb674c887d 100644 (file)
@@ -1295,15 +1295,21 @@ static void packet_sock_destruct(struct sock *sk)
 
 static bool fanout_flow_is_huge(struct packet_sock *po, struct sk_buff *skb)
 {
-       u32 rxhash;
+       u32 *history = po->rollover->history;
+       u32 victim, rxhash;
        int i, count = 0;
 
        rxhash = skb_get_hash(skb);
        for (i = 0; i < ROLLOVER_HLEN; i++)
-               if (po->rollover->history[i] == rxhash)
+               if (READ_ONCE(history[i]) == rxhash)
                        count++;
 
-       po->rollover->history[prandom_u32() % ROLLOVER_HLEN] = rxhash;
+       victim = prandom_u32() % ROLLOVER_HLEN;
+
+       /* Avoid dirtying the cache line if possible */
+       if (READ_ONCE(history[victim]) != rxhash)
+               WRITE_ONCE(history[victim], rxhash);
+
        return count > (ROLLOVER_HLEN >> 1);
 }