Commit 8ee2267a authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

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: default avatarIdo Schimmel <idosch@mellanox.com>
Reviewed-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5855357c
...@@ -12065,7 +12065,6 @@ M: Neil Horman <nhorman@tuxdriver.com> ...@@ -12065,7 +12065,6 @@ M: Neil Horman <nhorman@tuxdriver.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
S: Maintained S: Maintained
W: https://fedorahosted.org/dropwatch/ W: https://fedorahosted.org/dropwatch/
F: include/net/drop_monitor.h
F: include/uapi/linux/net_dropmon.h F: include/uapi/linux/net_dropmon.h
F: net/core/drop_monitor.c F: net/core/drop_monitor.c
......
/* 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 ...@@ -434,7 +434,6 @@ config NET_SOCK_MSG
config NET_DEVLINK config NET_DEVLINK
bool bool
default n default n
imply NET_DROP_MONITOR
config PAGE_POOL config PAGE_POOL
bool bool
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include <net/net_namespace.h> #include <net/net_namespace.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/devlink.h> #include <net/devlink.h>
#include <net/drop_monitor.h>
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/devlink.h> #include <trace/events/devlink.h>
...@@ -9261,24 +9260,6 @@ devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats, ...@@ -9261,24 +9260,6 @@ devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
u64_stats_update_end(&stats->syncp); 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 static void
devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata, devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata,
const struct devlink_trap_item *trap_item, const struct devlink_trap_item *trap_item,
...@@ -9309,7 +9290,6 @@ void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb, ...@@ -9309,7 +9290,6 @@ void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
{ {
struct devlink_trap_item *trap_item = trap_ctx; 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->stats, skb->len);
devlink_trap_stats_update(trap_item->group_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, ...@@ -9321,10 +9301,6 @@ void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
if (trap_item->trap->type == DEVLINK_TRAP_TYPE_CONTROL) if (trap_item->trap->type == DEVLINK_TRAP_TYPE_CONTROL)
return; 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()) { if (trace_devlink_trap_report_enabled()) {
struct devlink_trap_metadata metadata = {}; struct devlink_trap_metadata metadata = {};
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <net/drop_monitor.h>
#include <net/genetlink.h> #include <net/genetlink.h>
#include <net/netevent.h> #include <net/netevent.h>
#include <net/flow_offload.h> #include <net/flow_offload.h>
...@@ -34,6 +33,7 @@ ...@@ -34,6 +33,7 @@
#include <trace/events/skb.h> #include <trace/events/skb.h>
#include <trace/events/napi.h> #include <trace/events/napi.h>
#include <trace/events/devlink.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
...@@ -108,6 +108,13 @@ static enum net_dm_alert_mode net_dm_alert_mode = NET_DM_ALERT_MODE_SUMMARY; ...@@ -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_trunc_len;
static u32 net_dm_queue_len = 1000; 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 { struct net_dm_alert_ops {
void (*kfree_skb_probe)(void *ignore, struct sk_buff *skb, void (*kfree_skb_probe)(void *ignore, struct sk_buff *skb,
void *location); void *location);
...@@ -1129,25 +1136,32 @@ static const struct net_dm_alert_ops *net_dm_alert_ops_arr[] = { ...@@ -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, [NET_DM_ALERT_MODE_PACKET] = &net_dm_alert_packet_ops,
}; };
void net_dm_hw_report(struct sk_buff *skb, #if IS_ENABLED(CONFIG_NET_DEVLINK)
const struct net_dm_hw_metadata *hw_metadata) static int net_dm_hw_probe_register(const struct net_dm_alert_ops *ops)
{ {
rcu_read_lock(); return register_trace_devlink_trap_report(ops->hw_trap_probe, NULL);
}
if (!monitor_hw)
goto out;
net_dm_alert_ops_arr[net_dm_alert_mode]->hw_probe(skb, hw_metadata); 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;
}
out: static void net_dm_hw_probe_unregister(const struct net_dm_alert_ops *ops)
rcu_read_unlock(); {
} }
EXPORT_SYMBOL_GPL(net_dm_hw_report); #endif
static int net_dm_hw_monitor_start(struct netlink_ext_ack *extack) static int net_dm_hw_monitor_start(struct netlink_ext_ack *extack)
{ {
const struct net_dm_alert_ops *ops; const struct net_dm_alert_ops *ops;
int cpu; int cpu, rc;
if (monitor_hw) { if (monitor_hw) {
NL_SET_ERR_MSG_MOD(extack, "Hardware monitoring already enabled"); 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) ...@@ -1171,13 +1185,24 @@ static int net_dm_hw_monitor_start(struct netlink_ext_ack *extack)
kfree(hw_entries); 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; monitor_hw = true;
return 0; return 0;
err_module_put:
module_put(THIS_MODULE);
return rc;
} }
static void net_dm_hw_monitor_stop(struct netlink_ext_ack *extack) static void net_dm_hw_monitor_stop(struct netlink_ext_ack *extack)
{ {
const struct net_dm_alert_ops *ops;
int cpu; int cpu;
if (!monitor_hw) { if (!monitor_hw) {
...@@ -1185,12 +1210,11 @@ static void net_dm_hw_monitor_stop(struct netlink_ext_ack *extack) ...@@ -1185,12 +1210,11 @@ static void net_dm_hw_monitor_stop(struct netlink_ext_ack *extack)
return; return;
} }
ops = net_dm_alert_ops_arr[net_dm_alert_mode];
monitor_hw = false; monitor_hw = false;
/* After this call returns we are guaranteed that no CPU is processing net_dm_hw_probe_unregister(ops);
* any hardware drops.
*/
synchronize_rcu();
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
struct per_cpu_dm_data *hw_data = &per_cpu(dm_hw_cpu_data, cpu); struct per_cpu_dm_data *hw_data = &per_cpu(dm_hw_cpu_data, cpu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment