forked from mirrors/linux
		
	drop_monitor: Convert to using devlink tracepoint
Convert drop monitor to use the recently introduced
'devlink_trap_report' tracepoint instead of having devlink call into
drop monitor.
This is both consistent with software originated drops ('kfree_skb'
tracepoint) and also allows drop monitor to be built as a module and
still report hardware originated drops.
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									5855357cd4
								
							
						
					
					
						commit
						8ee2267ad3
					
				
					 5 changed files with 42 additions and 80 deletions
				
			
		|  | @ -12065,7 +12065,6 @@ M:	Neil Horman <nhorman@tuxdriver.com> | |||
| L:	netdev@vger.kernel.org | ||||
| S:	Maintained | ||||
| W:	https://fedorahosted.org/dropwatch/ | ||||
| F:	include/net/drop_monitor.h | ||||
| F:	include/uapi/linux/net_dropmon.h | ||||
| F:	net/core/drop_monitor.c | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,36 +0,0 @@ | |||
| /* SPDX-License-Identifier: GPL-2.0-only */ | ||||
| 
 | ||||
| #ifndef _NET_DROP_MONITOR_H_ | ||||
| #define _NET_DROP_MONITOR_H_ | ||||
| 
 | ||||
| #include <linux/ktime.h> | ||||
| #include <linux/netdevice.h> | ||||
| #include <linux/skbuff.h> | ||||
| #include <net/flow_offload.h> | ||||
| 
 | ||||
| /**
 | ||||
|  * struct net_dm_hw_metadata - Hardware-supplied packet metadata. | ||||
|  * @trap_group_name: Hardware trap group name. | ||||
|  * @trap_name: Hardware trap name. | ||||
|  * @input_dev: Input netdevice. | ||||
|  * @fa_cookie: Flow action user cookie. | ||||
|  */ | ||||
| struct net_dm_hw_metadata { | ||||
| 	const char *trap_group_name; | ||||
| 	const char *trap_name; | ||||
| 	struct net_device *input_dev; | ||||
| 	const struct flow_action_cookie *fa_cookie; | ||||
| }; | ||||
| 
 | ||||
| #if IS_REACHABLE(CONFIG_NET_DROP_MONITOR) | ||||
| void net_dm_hw_report(struct sk_buff *skb, | ||||
| 		      const struct net_dm_hw_metadata *hw_metadata); | ||||
| #else | ||||
| static inline void | ||||
| net_dm_hw_report(struct sk_buff *skb, | ||||
| 		 const struct net_dm_hw_metadata *hw_metadata) | ||||
| { | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #endif /* _NET_DROP_MONITOR_H_ */ | ||||
|  | @ -434,7 +434,6 @@ config NET_SOCK_MSG | |||
| config NET_DEVLINK | ||||
| 	bool | ||||
| 	default n | ||||
| 	imply NET_DROP_MONITOR | ||||
| 
 | ||||
| config PAGE_POOL | ||||
| 	bool | ||||
|  |  | |||
|  | @ -27,7 +27,6 @@ | |||
| #include <net/net_namespace.h> | ||||
| #include <net/sock.h> | ||||
| #include <net/devlink.h> | ||||
| #include <net/drop_monitor.h> | ||||
| #define CREATE_TRACE_POINTS | ||||
| #include <trace/events/devlink.h> | ||||
| 
 | ||||
|  | @ -9261,24 +9260,6 @@ devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats, | |||
| 	u64_stats_update_end(&stats->syncp); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| devlink_trap_report_metadata_fill(struct net_dm_hw_metadata *hw_metadata, | ||||
| 				  const struct devlink_trap_item *trap_item, | ||||
| 				  struct devlink_port *in_devlink_port, | ||||
| 				  const struct flow_action_cookie *fa_cookie) | ||||
| { | ||||
| 	struct devlink_trap_group_item *group_item = trap_item->group_item; | ||||
| 
 | ||||
| 	hw_metadata->trap_group_name = group_item->group->name; | ||||
| 	hw_metadata->trap_name = trap_item->trap->name; | ||||
| 	hw_metadata->fa_cookie = fa_cookie; | ||||
| 
 | ||||
| 	spin_lock(&in_devlink_port->type_lock); | ||||
| 	if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH) | ||||
| 		hw_metadata->input_dev = in_devlink_port->type_dev; | ||||
| 	spin_unlock(&in_devlink_port->type_lock); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata, | ||||
| 				 const struct devlink_trap_item *trap_item, | ||||
|  | @ -9309,7 +9290,6 @@ void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb, | |||
| 
 | ||||
| { | ||||
| 	struct devlink_trap_item *trap_item = trap_ctx; | ||||
| 	struct net_dm_hw_metadata hw_metadata = {}; | ||||
| 
 | ||||
| 	devlink_trap_stats_update(trap_item->stats, skb->len); | ||||
| 	devlink_trap_stats_update(trap_item->group_item->stats, skb->len); | ||||
|  | @ -9321,10 +9301,6 @@ void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb, | |||
| 	if (trap_item->trap->type == DEVLINK_TRAP_TYPE_CONTROL) | ||||
| 		return; | ||||
| 
 | ||||
| 	devlink_trap_report_metadata_fill(&hw_metadata, trap_item, | ||||
| 					  in_devlink_port, fa_cookie); | ||||
| 	net_dm_hw_report(skb, &hw_metadata); | ||||
| 
 | ||||
| 	if (trace_devlink_trap_report_enabled()) { | ||||
| 		struct devlink_trap_metadata metadata = {}; | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,7 +26,6 @@ | |||
| #include <linux/bitops.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/module.h> | ||||
| #include <net/drop_monitor.h> | ||||
| #include <net/genetlink.h> | ||||
| #include <net/netevent.h> | ||||
| #include <net/flow_offload.h> | ||||
|  | @ -34,6 +33,7 @@ | |||
| 
 | ||||
| #include <trace/events/skb.h> | ||||
| #include <trace/events/napi.h> | ||||
| #include <trace/events/devlink.h> | ||||
| 
 | ||||
| #include <asm/unaligned.h> | ||||
| 
 | ||||
|  | @ -108,6 +108,13 @@ static enum net_dm_alert_mode net_dm_alert_mode = NET_DM_ALERT_MODE_SUMMARY; | |||
| static u32 net_dm_trunc_len; | ||||
| static u32 net_dm_queue_len = 1000; | ||||
| 
 | ||||
| struct net_dm_hw_metadata { | ||||
| 	const char *trap_group_name; | ||||
| 	const char *trap_name; | ||||
| 	struct net_device *input_dev; | ||||
| 	const struct flow_action_cookie *fa_cookie; | ||||
| }; | ||||
| 
 | ||||
| struct net_dm_alert_ops { | ||||
| 	void (*kfree_skb_probe)(void *ignore, struct sk_buff *skb, | ||||
| 				void *location); | ||||
|  | @ -1129,25 +1136,32 @@ static const struct net_dm_alert_ops *net_dm_alert_ops_arr[] = { | |||
| 	[NET_DM_ALERT_MODE_PACKET]	= &net_dm_alert_packet_ops, | ||||
| }; | ||||
| 
 | ||||
| void net_dm_hw_report(struct sk_buff *skb, | ||||
| 		      const struct net_dm_hw_metadata *hw_metadata) | ||||
| #if IS_ENABLED(CONFIG_NET_DEVLINK) | ||||
| static int net_dm_hw_probe_register(const struct net_dm_alert_ops *ops) | ||||
| { | ||||
| 	rcu_read_lock(); | ||||
| 
 | ||||
| 	if (!monitor_hw) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	net_dm_alert_ops_arr[net_dm_alert_mode]->hw_probe(skb, hw_metadata); | ||||
| 
 | ||||
| out: | ||||
| 	rcu_read_unlock(); | ||||
| 	return register_trace_devlink_trap_report(ops->hw_trap_probe, NULL); | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(net_dm_hw_report); | ||||
| 
 | ||||
| static void net_dm_hw_probe_unregister(const struct net_dm_alert_ops *ops) | ||||
| { | ||||
| 	unregister_trace_devlink_trap_report(ops->hw_trap_probe, NULL); | ||||
| 	tracepoint_synchronize_unregister(); | ||||
| } | ||||
| #else | ||||
| static int net_dm_hw_probe_register(const struct net_dm_alert_ops *ops) | ||||
| { | ||||
| 	return -EOPNOTSUPP; | ||||
| } | ||||
| 
 | ||||
| static void net_dm_hw_probe_unregister(const struct net_dm_alert_ops *ops) | ||||
| { | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static int net_dm_hw_monitor_start(struct netlink_ext_ack *extack) | ||||
| { | ||||
| 	const struct net_dm_alert_ops *ops; | ||||
| 	int cpu; | ||||
| 	int cpu, rc; | ||||
| 
 | ||||
| 	if (monitor_hw) { | ||||
| 		NL_SET_ERR_MSG_MOD(extack, "Hardware monitoring already enabled"); | ||||
|  | @ -1171,13 +1185,24 @@ static int net_dm_hw_monitor_start(struct netlink_ext_ack *extack) | |||
| 		kfree(hw_entries); | ||||
| 	} | ||||
| 
 | ||||
| 	rc = net_dm_hw_probe_register(ops); | ||||
| 	if (rc) { | ||||
| 		NL_SET_ERR_MSG_MOD(extack, "Failed to connect probe to devlink_trap_probe() tracepoint"); | ||||
| 		goto err_module_put; | ||||
| 	} | ||||
| 
 | ||||
| 	monitor_hw = true; | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| err_module_put: | ||||
| 	module_put(THIS_MODULE); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| static void net_dm_hw_monitor_stop(struct netlink_ext_ack *extack) | ||||
| { | ||||
| 	const struct net_dm_alert_ops *ops; | ||||
| 	int cpu; | ||||
| 
 | ||||
| 	if (!monitor_hw) { | ||||
|  | @ -1185,12 +1210,11 @@ static void net_dm_hw_monitor_stop(struct netlink_ext_ack *extack) | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	ops = net_dm_alert_ops_arr[net_dm_alert_mode]; | ||||
| 
 | ||||
| 	monitor_hw = false; | ||||
| 
 | ||||
| 	/* After this call returns we are guaranteed that no CPU is processing
 | ||||
| 	 * any hardware drops. | ||||
| 	 */ | ||||
| 	synchronize_rcu(); | ||||
| 	net_dm_hw_probe_unregister(ops); | ||||
| 
 | ||||
| 	for_each_possible_cpu(cpu) { | ||||
| 		struct per_cpu_dm_data *hw_data = &per_cpu(dm_hw_cpu_data, cpu); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Ido Schimmel
						Ido Schimmel