Merge tag 'v5.15.63' into rpi-5.15.y
[platform/kernel/linux-rpi.git] / net / core / drop_monitor.c
index 49442ca..7820214 100644 (file)
@@ -110,7 +110,8 @@ static u32 net_dm_queue_len = 1000;
 
 struct net_dm_alert_ops {
        void (*kfree_skb_probe)(void *ignore, struct sk_buff *skb,
-                               void *location);
+                               void *location,
+                               enum skb_drop_reason reason);
        void (*napi_poll_probe)(void *ignore, struct napi_struct *napi,
                                int work, int budget);
        void (*work_item_func)(struct work_struct *work);
@@ -262,7 +263,9 @@ out:
        spin_unlock_irqrestore(&data->lock, flags);
 }
 
-static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb, void *location)
+static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb,
+                               void *location,
+                               enum skb_drop_reason reason)
 {
        trace_drop_common(skb, location);
 }
@@ -280,13 +283,17 @@ static void trace_napi_poll_hit(void *ignore, struct napi_struct *napi,
 
        rcu_read_lock();
        list_for_each_entry_rcu(new_stat, &hw_stats_list, list) {
+               struct net_device *dev;
+
                /*
                 * only add a note to our monitor buffer if:
                 * 1) this is the dev we received on
                 * 2) its after the last_rx delta
                 * 3) our rx_dropped count has gone up
                 */
-               if ((new_stat->dev == napi->dev)  &&
+               /* Paired with WRITE_ONCE() in dropmon_net_event() */
+               dev = READ_ONCE(new_stat->dev);
+               if ((dev == napi->dev)  &&
                    (time_after(jiffies, new_stat->last_rx + dm_hw_check_delta)) &&
                    (napi->dev->stats.rx_dropped != new_stat->last_drop_val)) {
                        trace_drop_common(NULL, NULL);
@@ -490,7 +497,8 @@ static const struct net_dm_alert_ops net_dm_alert_summary_ops = {
 
 static void net_dm_packet_trace_kfree_skb_hit(void *ignore,
                                              struct sk_buff *skb,
-                                             void *location)
+                                             void *location,
+                                             enum skb_drop_reason reason)
 {
        ktime_t tstamp = ktime_get_real();
        struct per_cpu_dm_data *data;
@@ -1572,7 +1580,10 @@ static int dropmon_net_event(struct notifier_block *ev_block,
                mutex_lock(&net_dm_mutex);
                list_for_each_entry_safe(new_stat, tmp, &hw_stats_list, list) {
                        if (new_stat->dev == dev) {
-                               new_stat->dev = NULL;
+
+                               /* Paired with READ_ONCE() in trace_napi_poll_hit() */
+                               WRITE_ONCE(new_stat->dev, NULL);
+
                                if (trace_state == TRACE_OFF) {
                                        list_del_rcu(&new_stat->list);
                                        kfree_rcu(new_stat, rcu);