1 // SPDX-License-Identifier: GPL-2.0-only
3 * Monitoring code for network dropped packet alerts
5 * Copyright (C) 2009 Neil Horman <nhorman@tuxdriver.com>
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10 #include <linux/netdevice.h>
11 #include <linux/etherdevice.h>
12 #include <linux/string.h>
13 #include <linux/if_arp.h>
14 #include <linux/inetdevice.h>
15 #include <linux/inet.h>
16 #include <linux/interrupt.h>
17 #include <linux/netpoll.h>
18 #include <linux/sched.h>
19 #include <linux/delay.h>
20 #include <linux/types.h>
21 #include <linux/workqueue.h>
22 #include <linux/netlink.h>
23 #include <linux/net_dropmon.h>
24 #include <linux/percpu.h>
25 #include <linux/timer.h>
26 #include <linux/bitops.h>
27 #include <linux/slab.h>
28 #include <linux/module.h>
29 #include <net/genetlink.h>
30 #include <net/netevent.h>
31 #include <net/flow_offload.h>
32 #include <net/devlink.h>
34 #include <trace/events/skb.h>
35 #include <trace/events/napi.h>
36 #include <trace/events/devlink.h>
38 #include <asm/unaligned.h>
44 * Globals, our netlink socket pointer
45 * and the work handle that will send up
48 static int trace_state
= TRACE_OFF
;
49 static bool monitor_hw
;
53 * An overall lock guarding every operation coming from userspace.
54 * It also guards the global 'hw_stats_list' list.
56 static DEFINE_MUTEX(net_dm_mutex
);
60 struct u64_stats_sync syncp
;
63 #define NET_DM_MAX_HW_TRAP_NAME_LEN 40
65 struct net_dm_hw_entry
{
66 char trap_name
[NET_DM_MAX_HW_TRAP_NAME_LEN
];
70 struct net_dm_hw_entries
{
72 struct net_dm_hw_entry entries
[];
75 struct per_cpu_dm_data
{
76 spinlock_t lock
; /* Protects 'skb', 'hw_entries' and
81 struct net_dm_hw_entries
*hw_entries
;
83 struct sk_buff_head drop_queue
;
84 struct work_struct dm_alert_work
;
85 struct timer_list send_timer
;
86 struct net_dm_stats stats
;
89 struct dm_hw_stat_delta
{
90 struct net_device
*dev
;
91 unsigned long last_rx
;
92 struct list_head list
;
94 unsigned long last_drop_val
;
97 static struct genl_family net_drop_monitor_family
;
99 static DEFINE_PER_CPU(struct per_cpu_dm_data
, dm_cpu_data
);
100 static DEFINE_PER_CPU(struct per_cpu_dm_data
, dm_hw_cpu_data
);
102 static int dm_hit_limit
= 64;
103 static int dm_delay
= 1;
104 static unsigned long dm_hw_check_delta
= 2*HZ
;
105 static LIST_HEAD(hw_stats_list
);
107 static enum net_dm_alert_mode net_dm_alert_mode
= NET_DM_ALERT_MODE_SUMMARY
;
108 static u32 net_dm_trunc_len
;
109 static u32 net_dm_queue_len
= 1000;
111 struct net_dm_alert_ops
{
112 void (*kfree_skb_probe
)(void *ignore
, struct sk_buff
*skb
,
114 void (*napi_poll_probe
)(void *ignore
, struct napi_struct
*napi
,
115 int work
, int budget
);
116 void (*work_item_func
)(struct work_struct
*work
);
117 void (*hw_work_item_func
)(struct work_struct
*work
);
118 void (*hw_trap_probe
)(void *ignore
, const struct devlink
*devlink
,
120 const struct devlink_trap_metadata
*metadata
);
123 struct net_dm_skb_cb
{
125 struct devlink_trap_metadata
*hw_metadata
;
130 #define NET_DM_SKB_CB(__skb) ((struct net_dm_skb_cb *)&((__skb)->cb[0]))
132 static struct sk_buff
*reset_per_cpu_data(struct per_cpu_dm_data
*data
)
135 struct net_dm_alert_msg
*msg
;
141 al
= sizeof(struct net_dm_alert_msg
);
142 al
+= dm_hit_limit
* sizeof(struct net_dm_drop_point
);
143 al
+= sizeof(struct nlattr
);
145 skb
= genlmsg_new(al
, GFP_KERNEL
);
150 msg_header
= genlmsg_put(skb
, 0, 0, &net_drop_monitor_family
,
151 0, NET_DM_CMD_ALERT
);
157 nla
= nla_reserve(skb
, NLA_UNSPEC
,
158 sizeof(struct net_dm_alert_msg
));
169 mod_timer(&data
->send_timer
, jiffies
+ HZ
/ 10);
171 spin_lock_irqsave(&data
->lock
, flags
);
172 swap(data
->skb
, skb
);
173 spin_unlock_irqrestore(&data
->lock
, flags
);
176 struct nlmsghdr
*nlh
= (struct nlmsghdr
*)skb
->data
;
177 struct genlmsghdr
*gnlh
= (struct genlmsghdr
*)nlmsg_data(nlh
);
179 genlmsg_end(skb
, genlmsg_data(gnlh
));
185 static const struct genl_multicast_group dropmon_mcgrps
[] = {
186 { .name
= "events", },
189 static void send_dm_alert(struct work_struct
*work
)
192 struct per_cpu_dm_data
*data
;
194 data
= container_of(work
, struct per_cpu_dm_data
, dm_alert_work
);
196 skb
= reset_per_cpu_data(data
);
199 genlmsg_multicast(&net_drop_monitor_family
, skb
, 0,
204 * This is the timer function to delay the sending of an alert
205 * in the event that more drops will arrive during the
208 static void sched_send_work(struct timer_list
*t
)
210 struct per_cpu_dm_data
*data
= from_timer(data
, t
, send_timer
);
212 schedule_work(&data
->dm_alert_work
);
215 static void trace_drop_common(struct sk_buff
*skb
, void *location
)
217 struct net_dm_alert_msg
*msg
;
218 struct net_dm_drop_point
*point
;
219 struct nlmsghdr
*nlh
;
222 struct sk_buff
*dskb
;
223 struct per_cpu_dm_data
*data
;
226 local_irq_save(flags
);
227 data
= this_cpu_ptr(&dm_cpu_data
);
228 spin_lock(&data
->lock
);
234 nlh
= (struct nlmsghdr
*)dskb
->data
;
235 nla
= genlmsg_data(nlmsg_data(nlh
));
238 for (i
= 0; i
< msg
->entries
; i
++) {
239 if (!memcmp(&location
, &point
->pc
, sizeof(void *))) {
245 if (msg
->entries
== dm_hit_limit
)
248 * We need to create a new entry
250 __nla_reserve_nohdr(dskb
, sizeof(struct net_dm_drop_point
));
251 nla
->nla_len
+= NLA_ALIGN(sizeof(struct net_dm_drop_point
));
252 memcpy(point
->pc
, &location
, sizeof(void *));
256 if (!timer_pending(&data
->send_timer
)) {
257 data
->send_timer
.expires
= jiffies
+ dm_delay
* HZ
;
258 add_timer(&data
->send_timer
);
262 spin_unlock_irqrestore(&data
->lock
, flags
);
265 static void trace_kfree_skb_hit(void *ignore
, struct sk_buff
*skb
, void *location
)
267 trace_drop_common(skb
, location
);
270 static void trace_napi_poll_hit(void *ignore
, struct napi_struct
*napi
,
271 int work
, int budget
)
273 struct dm_hw_stat_delta
*new_stat
;
276 * Don't check napi structures with no associated device
282 list_for_each_entry_rcu(new_stat
, &hw_stats_list
, list
) {
284 * only add a note to our monitor buffer if:
285 * 1) this is the dev we received on
286 * 2) its after the last_rx delta
287 * 3) our rx_dropped count has gone up
289 if ((new_stat
->dev
== napi
->dev
) &&
290 (time_after(jiffies
, new_stat
->last_rx
+ dm_hw_check_delta
)) &&
291 (napi
->dev
->stats
.rx_dropped
!= new_stat
->last_drop_val
)) {
292 trace_drop_common(NULL
, NULL
);
293 new_stat
->last_drop_val
= napi
->dev
->stats
.rx_dropped
;
294 new_stat
->last_rx
= jiffies
;
301 static struct net_dm_hw_entries
*
302 net_dm_hw_reset_per_cpu_data(struct per_cpu_dm_data
*hw_data
)
304 struct net_dm_hw_entries
*hw_entries
;
307 hw_entries
= kzalloc(struct_size(hw_entries
, entries
, dm_hit_limit
),
310 /* If the memory allocation failed, we try to perform another
311 * allocation in 1/10 second. Otherwise, the probe function
312 * will constantly bail out.
314 mod_timer(&hw_data
->send_timer
, jiffies
+ HZ
/ 10);
317 spin_lock_irqsave(&hw_data
->lock
, flags
);
318 swap(hw_data
->hw_entries
, hw_entries
);
319 spin_unlock_irqrestore(&hw_data
->lock
, flags
);
324 static int net_dm_hw_entry_put(struct sk_buff
*msg
,
325 const struct net_dm_hw_entry
*hw_entry
)
329 attr
= nla_nest_start(msg
, NET_DM_ATTR_HW_ENTRY
);
333 if (nla_put_string(msg
, NET_DM_ATTR_HW_TRAP_NAME
, hw_entry
->trap_name
))
334 goto nla_put_failure
;
336 if (nla_put_u32(msg
, NET_DM_ATTR_HW_TRAP_COUNT
, hw_entry
->count
))
337 goto nla_put_failure
;
339 nla_nest_end(msg
, attr
);
344 nla_nest_cancel(msg
, attr
);
348 static int net_dm_hw_entries_put(struct sk_buff
*msg
,
349 const struct net_dm_hw_entries
*hw_entries
)
354 attr
= nla_nest_start(msg
, NET_DM_ATTR_HW_ENTRIES
);
358 for (i
= 0; i
< hw_entries
->num_entries
; i
++) {
361 rc
= net_dm_hw_entry_put(msg
, &hw_entries
->entries
[i
]);
363 goto nla_put_failure
;
366 nla_nest_end(msg
, attr
);
371 nla_nest_cancel(msg
, attr
);
376 net_dm_hw_summary_report_fill(struct sk_buff
*msg
,
377 const struct net_dm_hw_entries
*hw_entries
)
379 struct net_dm_alert_msg anc_hdr
= { 0 };
383 hdr
= genlmsg_put(msg
, 0, 0, &net_drop_monitor_family
, 0,
388 /* We need to put the ancillary header in order not to break user
391 if (nla_put(msg
, NLA_UNSPEC
, sizeof(anc_hdr
), &anc_hdr
))
392 goto nla_put_failure
;
394 rc
= net_dm_hw_entries_put(msg
, hw_entries
);
396 goto nla_put_failure
;
398 genlmsg_end(msg
, hdr
);
403 genlmsg_cancel(msg
, hdr
);
407 static void net_dm_hw_summary_work(struct work_struct
*work
)
409 struct net_dm_hw_entries
*hw_entries
;
410 struct per_cpu_dm_data
*hw_data
;
414 hw_data
= container_of(work
, struct per_cpu_dm_data
, dm_alert_work
);
416 hw_entries
= net_dm_hw_reset_per_cpu_data(hw_data
);
420 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
424 rc
= net_dm_hw_summary_report_fill(msg
, hw_entries
);
430 genlmsg_multicast(&net_drop_monitor_family
, msg
, 0, 0, GFP_KERNEL
);
437 net_dm_hw_trap_summary_probe(void *ignore
, const struct devlink
*devlink
,
439 const struct devlink_trap_metadata
*metadata
)
441 struct net_dm_hw_entries
*hw_entries
;
442 struct net_dm_hw_entry
*hw_entry
;
443 struct per_cpu_dm_data
*hw_data
;
447 if (metadata
->trap_type
== DEVLINK_TRAP_TYPE_CONTROL
)
450 hw_data
= this_cpu_ptr(&dm_hw_cpu_data
);
451 spin_lock_irqsave(&hw_data
->lock
, flags
);
452 hw_entries
= hw_data
->hw_entries
;
457 for (i
= 0; i
< hw_entries
->num_entries
; i
++) {
458 hw_entry
= &hw_entries
->entries
[i
];
459 if (!strncmp(hw_entry
->trap_name
, metadata
->trap_name
,
460 NET_DM_MAX_HW_TRAP_NAME_LEN
- 1)) {
465 if (WARN_ON_ONCE(hw_entries
->num_entries
== dm_hit_limit
))
468 hw_entry
= &hw_entries
->entries
[hw_entries
->num_entries
];
469 strlcpy(hw_entry
->trap_name
, metadata
->trap_name
,
470 NET_DM_MAX_HW_TRAP_NAME_LEN
- 1);
472 hw_entries
->num_entries
++;
474 if (!timer_pending(&hw_data
->send_timer
)) {
475 hw_data
->send_timer
.expires
= jiffies
+ dm_delay
* HZ
;
476 add_timer(&hw_data
->send_timer
);
480 spin_unlock_irqrestore(&hw_data
->lock
, flags
);
483 static const struct net_dm_alert_ops net_dm_alert_summary_ops
= {
484 .kfree_skb_probe
= trace_kfree_skb_hit
,
485 .napi_poll_probe
= trace_napi_poll_hit
,
486 .work_item_func
= send_dm_alert
,
487 .hw_work_item_func
= net_dm_hw_summary_work
,
488 .hw_trap_probe
= net_dm_hw_trap_summary_probe
,
491 static void net_dm_packet_trace_kfree_skb_hit(void *ignore
,
495 ktime_t tstamp
= ktime_get_real();
496 struct per_cpu_dm_data
*data
;
497 struct sk_buff
*nskb
;
500 if (!skb_mac_header_was_set(skb
))
503 nskb
= skb_clone(skb
, GFP_ATOMIC
);
507 NET_DM_SKB_CB(nskb
)->pc
= location
;
508 /* Override the timestamp because we care about the time when the
509 * packet was dropped.
511 nskb
->tstamp
= tstamp
;
513 data
= this_cpu_ptr(&dm_cpu_data
);
515 spin_lock_irqsave(&data
->drop_queue
.lock
, flags
);
516 if (skb_queue_len(&data
->drop_queue
) < net_dm_queue_len
)
517 __skb_queue_tail(&data
->drop_queue
, nskb
);
520 spin_unlock_irqrestore(&data
->drop_queue
.lock
, flags
);
522 schedule_work(&data
->dm_alert_work
);
527 spin_unlock_irqrestore(&data
->drop_queue
.lock
, flags
);
528 u64_stats_update_begin(&data
->stats
.syncp
);
529 data
->stats
.dropped
++;
530 u64_stats_update_end(&data
->stats
.syncp
);
534 static void net_dm_packet_trace_napi_poll_hit(void *ignore
,
535 struct napi_struct
*napi
,
536 int work
, int budget
)
540 static size_t net_dm_in_port_size(void)
542 /* NET_DM_ATTR_IN_PORT nest */
543 return nla_total_size(0) +
544 /* NET_DM_ATTR_PORT_NETDEV_IFINDEX */
545 nla_total_size(sizeof(u32
)) +
546 /* NET_DM_ATTR_PORT_NETDEV_NAME */
547 nla_total_size(IFNAMSIZ
+ 1);
550 #define NET_DM_MAX_SYMBOL_LEN 40
552 static size_t net_dm_packet_report_size(size_t payload_len
)
556 size
= nlmsg_msg_size(GENL_HDRLEN
+ net_drop_monitor_family
.hdrsize
);
558 return NLMSG_ALIGN(size
) +
559 /* NET_DM_ATTR_ORIGIN */
560 nla_total_size(sizeof(u16
)) +
562 nla_total_size(sizeof(u64
)) +
563 /* NET_DM_ATTR_SYMBOL */
564 nla_total_size(NET_DM_MAX_SYMBOL_LEN
+ 1) +
565 /* NET_DM_ATTR_IN_PORT */
566 net_dm_in_port_size() +
567 /* NET_DM_ATTR_TIMESTAMP */
568 nla_total_size(sizeof(u64
)) +
569 /* NET_DM_ATTR_ORIG_LEN */
570 nla_total_size(sizeof(u32
)) +
571 /* NET_DM_ATTR_PROTO */
572 nla_total_size(sizeof(u16
)) +
573 /* NET_DM_ATTR_PAYLOAD */
574 nla_total_size(payload_len
);
577 static int net_dm_packet_report_in_port_put(struct sk_buff
*msg
, int ifindex
,
582 attr
= nla_nest_start(msg
, NET_DM_ATTR_IN_PORT
);
587 nla_put_u32(msg
, NET_DM_ATTR_PORT_NETDEV_IFINDEX
, ifindex
))
588 goto nla_put_failure
;
590 if (name
&& nla_put_string(msg
, NET_DM_ATTR_PORT_NETDEV_NAME
, name
))
591 goto nla_put_failure
;
593 nla_nest_end(msg
, attr
);
598 nla_nest_cancel(msg
, attr
);
602 static int net_dm_packet_report_fill(struct sk_buff
*msg
, struct sk_buff
*skb
,
605 u64 pc
= (u64
)(uintptr_t) NET_DM_SKB_CB(skb
)->pc
;
606 char buf
[NET_DM_MAX_SYMBOL_LEN
];
611 hdr
= genlmsg_put(msg
, 0, 0, &net_drop_monitor_family
, 0,
612 NET_DM_CMD_PACKET_ALERT
);
616 if (nla_put_u16(msg
, NET_DM_ATTR_ORIGIN
, NET_DM_ORIGIN_SW
))
617 goto nla_put_failure
;
619 if (nla_put_u64_64bit(msg
, NET_DM_ATTR_PC
, pc
, NET_DM_ATTR_PAD
))
620 goto nla_put_failure
;
622 snprintf(buf
, sizeof(buf
), "%pS", NET_DM_SKB_CB(skb
)->pc
);
623 if (nla_put_string(msg
, NET_DM_ATTR_SYMBOL
, buf
))
624 goto nla_put_failure
;
626 rc
= net_dm_packet_report_in_port_put(msg
, skb
->skb_iif
, NULL
);
628 goto nla_put_failure
;
630 if (nla_put_u64_64bit(msg
, NET_DM_ATTR_TIMESTAMP
,
631 ktime_to_ns(skb
->tstamp
), NET_DM_ATTR_PAD
))
632 goto nla_put_failure
;
634 if (nla_put_u32(msg
, NET_DM_ATTR_ORIG_LEN
, skb
->len
))
635 goto nla_put_failure
;
640 if (nla_put_u16(msg
, NET_DM_ATTR_PROTO
, be16_to_cpu(skb
->protocol
)))
641 goto nla_put_failure
;
643 attr
= skb_put(msg
, nla_total_size(payload_len
));
644 attr
->nla_type
= NET_DM_ATTR_PAYLOAD
;
645 attr
->nla_len
= nla_attr_size(payload_len
);
646 if (skb_copy_bits(skb
, 0, nla_data(attr
), payload_len
))
647 goto nla_put_failure
;
650 genlmsg_end(msg
, hdr
);
655 genlmsg_cancel(msg
, hdr
);
659 #define NET_DM_MAX_PACKET_SIZE (0xffff - NLA_HDRLEN - NLA_ALIGNTO)
661 static void net_dm_packet_report(struct sk_buff
*skb
)
667 /* Make sure we start copying the packet from the MAC header */
668 if (skb
->data
> skb_mac_header(skb
))
669 skb_push(skb
, skb
->data
- skb_mac_header(skb
));
671 skb_pull(skb
, skb_mac_header(skb
) - skb
->data
);
673 /* Ensure packet fits inside a single netlink attribute */
674 payload_len
= min_t(size_t, skb
->len
, NET_DM_MAX_PACKET_SIZE
);
675 if (net_dm_trunc_len
)
676 payload_len
= min_t(size_t, net_dm_trunc_len
, payload_len
);
678 msg
= nlmsg_new(net_dm_packet_report_size(payload_len
), GFP_KERNEL
);
682 rc
= net_dm_packet_report_fill(msg
, skb
, payload_len
);
688 genlmsg_multicast(&net_drop_monitor_family
, msg
, 0, 0, GFP_KERNEL
);
694 static void net_dm_packet_work(struct work_struct
*work
)
696 struct per_cpu_dm_data
*data
;
697 struct sk_buff_head list
;
701 data
= container_of(work
, struct per_cpu_dm_data
, dm_alert_work
);
703 __skb_queue_head_init(&list
);
705 spin_lock_irqsave(&data
->drop_queue
.lock
, flags
);
706 skb_queue_splice_tail_init(&data
->drop_queue
, &list
);
707 spin_unlock_irqrestore(&data
->drop_queue
.lock
, flags
);
709 while ((skb
= __skb_dequeue(&list
)))
710 net_dm_packet_report(skb
);
714 net_dm_flow_action_cookie_size(const struct devlink_trap_metadata
*hw_metadata
)
716 return hw_metadata
->fa_cookie
?
717 nla_total_size(hw_metadata
->fa_cookie
->cookie_len
) : 0;
721 net_dm_hw_packet_report_size(size_t payload_len
,
722 const struct devlink_trap_metadata
*hw_metadata
)
726 size
= nlmsg_msg_size(GENL_HDRLEN
+ net_drop_monitor_family
.hdrsize
);
728 return NLMSG_ALIGN(size
) +
729 /* NET_DM_ATTR_ORIGIN */
730 nla_total_size(sizeof(u16
)) +
731 /* NET_DM_ATTR_HW_TRAP_GROUP_NAME */
732 nla_total_size(strlen(hw_metadata
->trap_group_name
) + 1) +
733 /* NET_DM_ATTR_HW_TRAP_NAME */
734 nla_total_size(strlen(hw_metadata
->trap_name
) + 1) +
735 /* NET_DM_ATTR_IN_PORT */
736 net_dm_in_port_size() +
737 /* NET_DM_ATTR_FLOW_ACTION_COOKIE */
738 net_dm_flow_action_cookie_size(hw_metadata
) +
739 /* NET_DM_ATTR_TIMESTAMP */
740 nla_total_size(sizeof(u64
)) +
741 /* NET_DM_ATTR_ORIG_LEN */
742 nla_total_size(sizeof(u32
)) +
743 /* NET_DM_ATTR_PROTO */
744 nla_total_size(sizeof(u16
)) +
745 /* NET_DM_ATTR_PAYLOAD */
746 nla_total_size(payload_len
);
749 static int net_dm_hw_packet_report_fill(struct sk_buff
*msg
,
750 struct sk_buff
*skb
, size_t payload_len
)
752 struct devlink_trap_metadata
*hw_metadata
;
756 hw_metadata
= NET_DM_SKB_CB(skb
)->hw_metadata
;
758 hdr
= genlmsg_put(msg
, 0, 0, &net_drop_monitor_family
, 0,
759 NET_DM_CMD_PACKET_ALERT
);
763 if (nla_put_u16(msg
, NET_DM_ATTR_ORIGIN
, NET_DM_ORIGIN_HW
))
764 goto nla_put_failure
;
766 if (nla_put_string(msg
, NET_DM_ATTR_HW_TRAP_GROUP_NAME
,
767 hw_metadata
->trap_group_name
))
768 goto nla_put_failure
;
770 if (nla_put_string(msg
, NET_DM_ATTR_HW_TRAP_NAME
,
771 hw_metadata
->trap_name
))
772 goto nla_put_failure
;
774 if (hw_metadata
->input_dev
) {
775 struct net_device
*dev
= hw_metadata
->input_dev
;
778 rc
= net_dm_packet_report_in_port_put(msg
, dev
->ifindex
,
781 goto nla_put_failure
;
784 if (hw_metadata
->fa_cookie
&&
785 nla_put(msg
, NET_DM_ATTR_FLOW_ACTION_COOKIE
,
786 hw_metadata
->fa_cookie
->cookie_len
,
787 hw_metadata
->fa_cookie
->cookie
))
788 goto nla_put_failure
;
790 if (nla_put_u64_64bit(msg
, NET_DM_ATTR_TIMESTAMP
,
791 ktime_to_ns(skb
->tstamp
), NET_DM_ATTR_PAD
))
792 goto nla_put_failure
;
794 if (nla_put_u32(msg
, NET_DM_ATTR_ORIG_LEN
, skb
->len
))
795 goto nla_put_failure
;
800 if (nla_put_u16(msg
, NET_DM_ATTR_PROTO
, be16_to_cpu(skb
->protocol
)))
801 goto nla_put_failure
;
803 attr
= skb_put(msg
, nla_total_size(payload_len
));
804 attr
->nla_type
= NET_DM_ATTR_PAYLOAD
;
805 attr
->nla_len
= nla_attr_size(payload_len
);
806 if (skb_copy_bits(skb
, 0, nla_data(attr
), payload_len
))
807 goto nla_put_failure
;
810 genlmsg_end(msg
, hdr
);
815 genlmsg_cancel(msg
, hdr
);
819 static struct devlink_trap_metadata
*
820 net_dm_hw_metadata_copy(const struct devlink_trap_metadata
*metadata
)
822 const struct flow_action_cookie
*fa_cookie
;
823 struct devlink_trap_metadata
*hw_metadata
;
824 const char *trap_group_name
;
825 const char *trap_name
;
827 hw_metadata
= kzalloc(sizeof(*hw_metadata
), GFP_ATOMIC
);
831 trap_group_name
= kstrdup(metadata
->trap_group_name
, GFP_ATOMIC
);
832 if (!trap_group_name
)
833 goto free_hw_metadata
;
834 hw_metadata
->trap_group_name
= trap_group_name
;
836 trap_name
= kstrdup(metadata
->trap_name
, GFP_ATOMIC
);
838 goto free_trap_group
;
839 hw_metadata
->trap_name
= trap_name
;
841 if (metadata
->fa_cookie
) {
842 size_t cookie_size
= sizeof(*fa_cookie
) +
843 metadata
->fa_cookie
->cookie_len
;
845 fa_cookie
= kmemdup(metadata
->fa_cookie
, cookie_size
,
849 hw_metadata
->fa_cookie
= fa_cookie
;
852 hw_metadata
->input_dev
= metadata
->input_dev
;
853 if (hw_metadata
->input_dev
)
854 dev_hold(hw_metadata
->input_dev
);
861 kfree(trap_group_name
);
868 net_dm_hw_metadata_free(const struct devlink_trap_metadata
*hw_metadata
)
870 if (hw_metadata
->input_dev
)
871 dev_put(hw_metadata
->input_dev
);
872 kfree(hw_metadata
->fa_cookie
);
873 kfree(hw_metadata
->trap_name
);
874 kfree(hw_metadata
->trap_group_name
);
878 static void net_dm_hw_packet_report(struct sk_buff
*skb
)
880 struct devlink_trap_metadata
*hw_metadata
;
885 if (skb
->data
> skb_mac_header(skb
))
886 skb_push(skb
, skb
->data
- skb_mac_header(skb
));
888 skb_pull(skb
, skb_mac_header(skb
) - skb
->data
);
890 payload_len
= min_t(size_t, skb
->len
, NET_DM_MAX_PACKET_SIZE
);
891 if (net_dm_trunc_len
)
892 payload_len
= min_t(size_t, net_dm_trunc_len
, payload_len
);
894 hw_metadata
= NET_DM_SKB_CB(skb
)->hw_metadata
;
895 msg
= nlmsg_new(net_dm_hw_packet_report_size(payload_len
, hw_metadata
),
900 rc
= net_dm_hw_packet_report_fill(msg
, skb
, payload_len
);
906 genlmsg_multicast(&net_drop_monitor_family
, msg
, 0, 0, GFP_KERNEL
);
909 net_dm_hw_metadata_free(NET_DM_SKB_CB(skb
)->hw_metadata
);
913 static void net_dm_hw_packet_work(struct work_struct
*work
)
915 struct per_cpu_dm_data
*hw_data
;
916 struct sk_buff_head list
;
920 hw_data
= container_of(work
, struct per_cpu_dm_data
, dm_alert_work
);
922 __skb_queue_head_init(&list
);
924 spin_lock_irqsave(&hw_data
->drop_queue
.lock
, flags
);
925 skb_queue_splice_tail_init(&hw_data
->drop_queue
, &list
);
926 spin_unlock_irqrestore(&hw_data
->drop_queue
.lock
, flags
);
928 while ((skb
= __skb_dequeue(&list
)))
929 net_dm_hw_packet_report(skb
);
933 net_dm_hw_trap_packet_probe(void *ignore
, const struct devlink
*devlink
,
935 const struct devlink_trap_metadata
*metadata
)
937 struct devlink_trap_metadata
*n_hw_metadata
;
938 ktime_t tstamp
= ktime_get_real();
939 struct per_cpu_dm_data
*hw_data
;
940 struct sk_buff
*nskb
;
943 if (metadata
->trap_type
== DEVLINK_TRAP_TYPE_CONTROL
)
946 if (!skb_mac_header_was_set(skb
))
949 nskb
= skb_clone(skb
, GFP_ATOMIC
);
953 n_hw_metadata
= net_dm_hw_metadata_copy(metadata
);
957 NET_DM_SKB_CB(nskb
)->hw_metadata
= n_hw_metadata
;
958 nskb
->tstamp
= tstamp
;
960 hw_data
= this_cpu_ptr(&dm_hw_cpu_data
);
962 spin_lock_irqsave(&hw_data
->drop_queue
.lock
, flags
);
963 if (skb_queue_len(&hw_data
->drop_queue
) < net_dm_queue_len
)
964 __skb_queue_tail(&hw_data
->drop_queue
, nskb
);
967 spin_unlock_irqrestore(&hw_data
->drop_queue
.lock
, flags
);
969 schedule_work(&hw_data
->dm_alert_work
);
974 spin_unlock_irqrestore(&hw_data
->drop_queue
.lock
, flags
);
975 u64_stats_update_begin(&hw_data
->stats
.syncp
);
976 hw_data
->stats
.dropped
++;
977 u64_stats_update_end(&hw_data
->stats
.syncp
);
978 net_dm_hw_metadata_free(n_hw_metadata
);
983 static const struct net_dm_alert_ops net_dm_alert_packet_ops
= {
984 .kfree_skb_probe
= net_dm_packet_trace_kfree_skb_hit
,
985 .napi_poll_probe
= net_dm_packet_trace_napi_poll_hit
,
986 .work_item_func
= net_dm_packet_work
,
987 .hw_work_item_func
= net_dm_hw_packet_work
,
988 .hw_trap_probe
= net_dm_hw_trap_packet_probe
,
991 static const struct net_dm_alert_ops
*net_dm_alert_ops_arr
[] = {
992 [NET_DM_ALERT_MODE_SUMMARY
] = &net_dm_alert_summary_ops
,
993 [NET_DM_ALERT_MODE_PACKET
] = &net_dm_alert_packet_ops
,
996 #if IS_ENABLED(CONFIG_NET_DEVLINK)
997 static int net_dm_hw_probe_register(const struct net_dm_alert_ops
*ops
)
999 return register_trace_devlink_trap_report(ops
->hw_trap_probe
, NULL
);
1002 static void net_dm_hw_probe_unregister(const struct net_dm_alert_ops
*ops
)
1004 unregister_trace_devlink_trap_report(ops
->hw_trap_probe
, NULL
);
1005 tracepoint_synchronize_unregister();
1008 static int net_dm_hw_probe_register(const struct net_dm_alert_ops
*ops
)
1013 static void net_dm_hw_probe_unregister(const struct net_dm_alert_ops
*ops
)
1018 static int net_dm_hw_monitor_start(struct netlink_ext_ack
*extack
)
1020 const struct net_dm_alert_ops
*ops
;
1024 NL_SET_ERR_MSG_MOD(extack
, "Hardware monitoring already enabled");
1028 ops
= net_dm_alert_ops_arr
[net_dm_alert_mode
];
1030 if (!try_module_get(THIS_MODULE
)) {
1031 NL_SET_ERR_MSG_MOD(extack
, "Failed to take reference on module");
1035 for_each_possible_cpu(cpu
) {
1036 struct per_cpu_dm_data
*hw_data
= &per_cpu(dm_hw_cpu_data
, cpu
);
1037 struct net_dm_hw_entries
*hw_entries
;
1039 INIT_WORK(&hw_data
->dm_alert_work
, ops
->hw_work_item_func
);
1040 timer_setup(&hw_data
->send_timer
, sched_send_work
, 0);
1041 hw_entries
= net_dm_hw_reset_per_cpu_data(hw_data
);
1045 rc
= net_dm_hw_probe_register(ops
);
1047 NL_SET_ERR_MSG_MOD(extack
, "Failed to connect probe to devlink_trap_probe() tracepoint");
1048 goto err_module_put
;
1056 module_put(THIS_MODULE
);
1060 static void net_dm_hw_monitor_stop(struct netlink_ext_ack
*extack
)
1062 const struct net_dm_alert_ops
*ops
;
1066 NL_SET_ERR_MSG_MOD(extack
, "Hardware monitoring already disabled");
1070 ops
= net_dm_alert_ops_arr
[net_dm_alert_mode
];
1074 net_dm_hw_probe_unregister(ops
);
1076 for_each_possible_cpu(cpu
) {
1077 struct per_cpu_dm_data
*hw_data
= &per_cpu(dm_hw_cpu_data
, cpu
);
1078 struct sk_buff
*skb
;
1080 del_timer_sync(&hw_data
->send_timer
);
1081 cancel_work_sync(&hw_data
->dm_alert_work
);
1082 while ((skb
= __skb_dequeue(&hw_data
->drop_queue
))) {
1083 struct devlink_trap_metadata
*hw_metadata
;
1085 hw_metadata
= NET_DM_SKB_CB(skb
)->hw_metadata
;
1086 net_dm_hw_metadata_free(hw_metadata
);
1091 module_put(THIS_MODULE
);
1094 static int net_dm_trace_on_set(struct netlink_ext_ack
*extack
)
1096 const struct net_dm_alert_ops
*ops
;
1099 ops
= net_dm_alert_ops_arr
[net_dm_alert_mode
];
1101 if (!try_module_get(THIS_MODULE
)) {
1102 NL_SET_ERR_MSG_MOD(extack
, "Failed to take reference on module");
1106 for_each_possible_cpu(cpu
) {
1107 struct per_cpu_dm_data
*data
= &per_cpu(dm_cpu_data
, cpu
);
1108 struct sk_buff
*skb
;
1110 INIT_WORK(&data
->dm_alert_work
, ops
->work_item_func
);
1111 timer_setup(&data
->send_timer
, sched_send_work
, 0);
1112 /* Allocate a new per-CPU skb for the summary alert message and
1113 * free the old one which might contain stale data from
1116 skb
= reset_per_cpu_data(data
);
1120 rc
= register_trace_kfree_skb(ops
->kfree_skb_probe
, NULL
);
1122 NL_SET_ERR_MSG_MOD(extack
, "Failed to connect probe to kfree_skb() tracepoint");
1123 goto err_module_put
;
1126 rc
= register_trace_napi_poll(ops
->napi_poll_probe
, NULL
);
1128 NL_SET_ERR_MSG_MOD(extack
, "Failed to connect probe to napi_poll() tracepoint");
1129 goto err_unregister_trace
;
1134 err_unregister_trace
:
1135 unregister_trace_kfree_skb(ops
->kfree_skb_probe
, NULL
);
1137 module_put(THIS_MODULE
);
1141 static void net_dm_trace_off_set(void)
1143 struct dm_hw_stat_delta
*new_stat
, *temp
;
1144 const struct net_dm_alert_ops
*ops
;
1147 ops
= net_dm_alert_ops_arr
[net_dm_alert_mode
];
1149 unregister_trace_napi_poll(ops
->napi_poll_probe
, NULL
);
1150 unregister_trace_kfree_skb(ops
->kfree_skb_probe
, NULL
);
1152 tracepoint_synchronize_unregister();
1154 /* Make sure we do not send notifications to user space after request
1155 * to stop tracing returns.
1157 for_each_possible_cpu(cpu
) {
1158 struct per_cpu_dm_data
*data
= &per_cpu(dm_cpu_data
, cpu
);
1159 struct sk_buff
*skb
;
1161 del_timer_sync(&data
->send_timer
);
1162 cancel_work_sync(&data
->dm_alert_work
);
1163 while ((skb
= __skb_dequeue(&data
->drop_queue
)))
1167 list_for_each_entry_safe(new_stat
, temp
, &hw_stats_list
, list
) {
1168 if (new_stat
->dev
== NULL
) {
1169 list_del_rcu(&new_stat
->list
);
1170 kfree_rcu(new_stat
, rcu
);
1174 module_put(THIS_MODULE
);
1177 static int set_all_monitor_traces(int state
, struct netlink_ext_ack
*extack
)
1181 if (state
== trace_state
) {
1182 NL_SET_ERR_MSG_MOD(extack
, "Trace state already set to requested state");
1188 rc
= net_dm_trace_on_set(extack
);
1191 net_dm_trace_off_set();
1199 trace_state
= state
;
1206 static bool net_dm_is_monitoring(void)
1208 return trace_state
== TRACE_ON
|| monitor_hw
;
1211 static int net_dm_alert_mode_get_from_info(struct genl_info
*info
,
1212 enum net_dm_alert_mode
*p_alert_mode
)
1216 val
= nla_get_u8(info
->attrs
[NET_DM_ATTR_ALERT_MODE
]);
1219 case NET_DM_ALERT_MODE_SUMMARY
:
1220 case NET_DM_ALERT_MODE_PACKET
:
1221 *p_alert_mode
= val
;
1230 static int net_dm_alert_mode_set(struct genl_info
*info
)
1232 struct netlink_ext_ack
*extack
= info
->extack
;
1233 enum net_dm_alert_mode alert_mode
;
1236 if (!info
->attrs
[NET_DM_ATTR_ALERT_MODE
])
1239 rc
= net_dm_alert_mode_get_from_info(info
, &alert_mode
);
1241 NL_SET_ERR_MSG_MOD(extack
, "Invalid alert mode");
1245 net_dm_alert_mode
= alert_mode
;
1250 static void net_dm_trunc_len_set(struct genl_info
*info
)
1252 if (!info
->attrs
[NET_DM_ATTR_TRUNC_LEN
])
1255 net_dm_trunc_len
= nla_get_u32(info
->attrs
[NET_DM_ATTR_TRUNC_LEN
]);
1258 static void net_dm_queue_len_set(struct genl_info
*info
)
1260 if (!info
->attrs
[NET_DM_ATTR_QUEUE_LEN
])
1263 net_dm_queue_len
= nla_get_u32(info
->attrs
[NET_DM_ATTR_QUEUE_LEN
]);
1266 static int net_dm_cmd_config(struct sk_buff
*skb
,
1267 struct genl_info
*info
)
1269 struct netlink_ext_ack
*extack
= info
->extack
;
1272 if (net_dm_is_monitoring()) {
1273 NL_SET_ERR_MSG_MOD(extack
, "Cannot configure drop monitor during monitoring");
1277 rc
= net_dm_alert_mode_set(info
);
1281 net_dm_trunc_len_set(info
);
1283 net_dm_queue_len_set(info
);
1288 static int net_dm_monitor_start(bool set_sw
, bool set_hw
,
1289 struct netlink_ext_ack
*extack
)
1291 bool sw_set
= false;
1295 rc
= set_all_monitor_traces(TRACE_ON
, extack
);
1302 rc
= net_dm_hw_monitor_start(extack
);
1304 goto err_monitor_hw
;
1311 set_all_monitor_traces(TRACE_OFF
, extack
);
1315 static void net_dm_monitor_stop(bool set_sw
, bool set_hw
,
1316 struct netlink_ext_ack
*extack
)
1319 net_dm_hw_monitor_stop(extack
);
1321 set_all_monitor_traces(TRACE_OFF
, extack
);
1324 static int net_dm_cmd_trace(struct sk_buff
*skb
,
1325 struct genl_info
*info
)
1327 bool set_sw
= !!info
->attrs
[NET_DM_ATTR_SW_DROPS
];
1328 bool set_hw
= !!info
->attrs
[NET_DM_ATTR_HW_DROPS
];
1329 struct netlink_ext_ack
*extack
= info
->extack
;
1331 /* To maintain backward compatibility, we start / stop monitoring of
1332 * software drops if no flag is specified.
1334 if (!set_sw
&& !set_hw
)
1337 switch (info
->genlhdr
->cmd
) {
1338 case NET_DM_CMD_START
:
1339 return net_dm_monitor_start(set_sw
, set_hw
, extack
);
1340 case NET_DM_CMD_STOP
:
1341 net_dm_monitor_stop(set_sw
, set_hw
, extack
);
1348 static int net_dm_config_fill(struct sk_buff
*msg
, struct genl_info
*info
)
1352 hdr
= genlmsg_put(msg
, info
->snd_portid
, info
->snd_seq
,
1353 &net_drop_monitor_family
, 0, NET_DM_CMD_CONFIG_NEW
);
1357 if (nla_put_u8(msg
, NET_DM_ATTR_ALERT_MODE
, net_dm_alert_mode
))
1358 goto nla_put_failure
;
1360 if (nla_put_u32(msg
, NET_DM_ATTR_TRUNC_LEN
, net_dm_trunc_len
))
1361 goto nla_put_failure
;
1363 if (nla_put_u32(msg
, NET_DM_ATTR_QUEUE_LEN
, net_dm_queue_len
))
1364 goto nla_put_failure
;
1366 genlmsg_end(msg
, hdr
);
1371 genlmsg_cancel(msg
, hdr
);
1375 static int net_dm_cmd_config_get(struct sk_buff
*skb
, struct genl_info
*info
)
1377 struct sk_buff
*msg
;
1380 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1384 rc
= net_dm_config_fill(msg
, info
);
1388 return genlmsg_reply(msg
, info
);
1395 static void net_dm_stats_read(struct net_dm_stats
*stats
)
1399 memset(stats
, 0, sizeof(*stats
));
1400 for_each_possible_cpu(cpu
) {
1401 struct per_cpu_dm_data
*data
= &per_cpu(dm_cpu_data
, cpu
);
1402 struct net_dm_stats
*cpu_stats
= &data
->stats
;
1407 start
= u64_stats_fetch_begin_irq(&cpu_stats
->syncp
);
1408 dropped
= cpu_stats
->dropped
;
1409 } while (u64_stats_fetch_retry_irq(&cpu_stats
->syncp
, start
));
1411 stats
->dropped
+= dropped
;
1415 static int net_dm_stats_put(struct sk_buff
*msg
)
1417 struct net_dm_stats stats
;
1418 struct nlattr
*attr
;
1420 net_dm_stats_read(&stats
);
1422 attr
= nla_nest_start(msg
, NET_DM_ATTR_STATS
);
1426 if (nla_put_u64_64bit(msg
, NET_DM_ATTR_STATS_DROPPED
,
1427 stats
.dropped
, NET_DM_ATTR_PAD
))
1428 goto nla_put_failure
;
1430 nla_nest_end(msg
, attr
);
1435 nla_nest_cancel(msg
, attr
);
1439 static void net_dm_hw_stats_read(struct net_dm_stats
*stats
)
1443 memset(stats
, 0, sizeof(*stats
));
1444 for_each_possible_cpu(cpu
) {
1445 struct per_cpu_dm_data
*hw_data
= &per_cpu(dm_hw_cpu_data
, cpu
);
1446 struct net_dm_stats
*cpu_stats
= &hw_data
->stats
;
1451 start
= u64_stats_fetch_begin_irq(&cpu_stats
->syncp
);
1452 dropped
= cpu_stats
->dropped
;
1453 } while (u64_stats_fetch_retry_irq(&cpu_stats
->syncp
, start
));
1455 stats
->dropped
+= dropped
;
1459 static int net_dm_hw_stats_put(struct sk_buff
*msg
)
1461 struct net_dm_stats stats
;
1462 struct nlattr
*attr
;
1464 net_dm_hw_stats_read(&stats
);
1466 attr
= nla_nest_start(msg
, NET_DM_ATTR_HW_STATS
);
1470 if (nla_put_u64_64bit(msg
, NET_DM_ATTR_STATS_DROPPED
,
1471 stats
.dropped
, NET_DM_ATTR_PAD
))
1472 goto nla_put_failure
;
1474 nla_nest_end(msg
, attr
);
1479 nla_nest_cancel(msg
, attr
);
1483 static int net_dm_stats_fill(struct sk_buff
*msg
, struct genl_info
*info
)
1488 hdr
= genlmsg_put(msg
, info
->snd_portid
, info
->snd_seq
,
1489 &net_drop_monitor_family
, 0, NET_DM_CMD_STATS_NEW
);
1493 rc
= net_dm_stats_put(msg
);
1495 goto nla_put_failure
;
1497 rc
= net_dm_hw_stats_put(msg
);
1499 goto nla_put_failure
;
1501 genlmsg_end(msg
, hdr
);
1506 genlmsg_cancel(msg
, hdr
);
1510 static int net_dm_cmd_stats_get(struct sk_buff
*skb
, struct genl_info
*info
)
1512 struct sk_buff
*msg
;
1515 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1519 rc
= net_dm_stats_fill(msg
, info
);
1523 return genlmsg_reply(msg
, info
);
1530 static int dropmon_net_event(struct notifier_block
*ev_block
,
1531 unsigned long event
, void *ptr
)
1533 struct net_device
*dev
= netdev_notifier_info_to_dev(ptr
);
1534 struct dm_hw_stat_delta
*new_stat
= NULL
;
1535 struct dm_hw_stat_delta
*tmp
;
1538 case NETDEV_REGISTER
:
1539 new_stat
= kzalloc(sizeof(struct dm_hw_stat_delta
), GFP_KERNEL
);
1544 new_stat
->dev
= dev
;
1545 new_stat
->last_rx
= jiffies
;
1546 mutex_lock(&net_dm_mutex
);
1547 list_add_rcu(&new_stat
->list
, &hw_stats_list
);
1548 mutex_unlock(&net_dm_mutex
);
1550 case NETDEV_UNREGISTER
:
1551 mutex_lock(&net_dm_mutex
);
1552 list_for_each_entry_safe(new_stat
, tmp
, &hw_stats_list
, list
) {
1553 if (new_stat
->dev
== dev
) {
1554 new_stat
->dev
= NULL
;
1555 if (trace_state
== TRACE_OFF
) {
1556 list_del_rcu(&new_stat
->list
);
1557 kfree_rcu(new_stat
, rcu
);
1562 mutex_unlock(&net_dm_mutex
);
1569 static const struct nla_policy net_dm_nl_policy
[NET_DM_ATTR_MAX
+ 1] = {
1570 [NET_DM_ATTR_UNSPEC
] = { .strict_start_type
= NET_DM_ATTR_UNSPEC
+ 1 },
1571 [NET_DM_ATTR_ALERT_MODE
] = { .type
= NLA_U8
},
1572 [NET_DM_ATTR_TRUNC_LEN
] = { .type
= NLA_U32
},
1573 [NET_DM_ATTR_QUEUE_LEN
] = { .type
= NLA_U32
},
1574 [NET_DM_ATTR_SW_DROPS
] = {. type
= NLA_FLAG
},
1575 [NET_DM_ATTR_HW_DROPS
] = {. type
= NLA_FLAG
},
1578 static const struct genl_small_ops dropmon_ops
[] = {
1580 .cmd
= NET_DM_CMD_CONFIG
,
1581 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1582 .doit
= net_dm_cmd_config
,
1583 .flags
= GENL_ADMIN_PERM
,
1586 .cmd
= NET_DM_CMD_START
,
1587 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1588 .doit
= net_dm_cmd_trace
,
1591 .cmd
= NET_DM_CMD_STOP
,
1592 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
1593 .doit
= net_dm_cmd_trace
,
1596 .cmd
= NET_DM_CMD_CONFIG_GET
,
1597 .doit
= net_dm_cmd_config_get
,
1600 .cmd
= NET_DM_CMD_STATS_GET
,
1601 .doit
= net_dm_cmd_stats_get
,
1605 static int net_dm_nl_pre_doit(const struct genl_ops
*ops
,
1606 struct sk_buff
*skb
, struct genl_info
*info
)
1608 mutex_lock(&net_dm_mutex
);
1613 static void net_dm_nl_post_doit(const struct genl_ops
*ops
,
1614 struct sk_buff
*skb
, struct genl_info
*info
)
1616 mutex_unlock(&net_dm_mutex
);
1619 static struct genl_family net_drop_monitor_family __ro_after_init
= {
1623 .maxattr
= NET_DM_ATTR_MAX
,
1624 .policy
= net_dm_nl_policy
,
1625 .pre_doit
= net_dm_nl_pre_doit
,
1626 .post_doit
= net_dm_nl_post_doit
,
1627 .module
= THIS_MODULE
,
1628 .small_ops
= dropmon_ops
,
1629 .n_small_ops
= ARRAY_SIZE(dropmon_ops
),
1630 .mcgrps
= dropmon_mcgrps
,
1631 .n_mcgrps
= ARRAY_SIZE(dropmon_mcgrps
),
1634 static struct notifier_block dropmon_net_notifier
= {
1635 .notifier_call
= dropmon_net_event
1638 static void __net_dm_cpu_data_init(struct per_cpu_dm_data
*data
)
1640 spin_lock_init(&data
->lock
);
1641 skb_queue_head_init(&data
->drop_queue
);
1642 u64_stats_init(&data
->stats
.syncp
);
1645 static void __net_dm_cpu_data_fini(struct per_cpu_dm_data
*data
)
1647 WARN_ON(!skb_queue_empty(&data
->drop_queue
));
1650 static void net_dm_cpu_data_init(int cpu
)
1652 struct per_cpu_dm_data
*data
;
1654 data
= &per_cpu(dm_cpu_data
, cpu
);
1655 __net_dm_cpu_data_init(data
);
1658 static void net_dm_cpu_data_fini(int cpu
)
1660 struct per_cpu_dm_data
*data
;
1662 data
= &per_cpu(dm_cpu_data
, cpu
);
1663 /* At this point, we should have exclusive access
1664 * to this struct and can free the skb inside it.
1666 consume_skb(data
->skb
);
1667 __net_dm_cpu_data_fini(data
);
1670 static void net_dm_hw_cpu_data_init(int cpu
)
1672 struct per_cpu_dm_data
*hw_data
;
1674 hw_data
= &per_cpu(dm_hw_cpu_data
, cpu
);
1675 __net_dm_cpu_data_init(hw_data
);
1678 static void net_dm_hw_cpu_data_fini(int cpu
)
1680 struct per_cpu_dm_data
*hw_data
;
1682 hw_data
= &per_cpu(dm_hw_cpu_data
, cpu
);
1683 kfree(hw_data
->hw_entries
);
1684 __net_dm_cpu_data_fini(hw_data
);
1687 static int __init
init_net_drop_monitor(void)
1691 pr_info("Initializing network drop monitor service\n");
1693 if (sizeof(void *) > 8) {
1694 pr_err("Unable to store program counters on this arch, Drop monitor failed\n");
1698 rc
= genl_register_family(&net_drop_monitor_family
);
1700 pr_err("Could not create drop monitor netlink family\n");
1703 WARN_ON(net_drop_monitor_family
.mcgrp_offset
!= NET_DM_GRP_ALERT
);
1705 rc
= register_netdevice_notifier(&dropmon_net_notifier
);
1707 pr_crit("Failed to register netdevice notifier\n");
1713 for_each_possible_cpu(cpu
) {
1714 net_dm_cpu_data_init(cpu
);
1715 net_dm_hw_cpu_data_init(cpu
);
1721 genl_unregister_family(&net_drop_monitor_family
);
1726 static void exit_net_drop_monitor(void)
1730 BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier
));
1733 * Because of the module_get/put we do in the trace state change path
1734 * we are guarnateed not to have any current users when we get here
1737 for_each_possible_cpu(cpu
) {
1738 net_dm_hw_cpu_data_fini(cpu
);
1739 net_dm_cpu_data_fini(cpu
);
1742 BUG_ON(genl_unregister_family(&net_drop_monitor_family
));
1745 module_init(init_net_drop_monitor
);
1746 module_exit(exit_net_drop_monitor
);
1748 MODULE_LICENSE("GPL v2");
1749 MODULE_AUTHOR("Neil Horman <nhorman@tuxdriver.com>");
1750 MODULE_ALIAS_GENL_FAMILY("NET_DM");
1751 MODULE_DESCRIPTION("Monitoring code for network dropped packet alerts");