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:
Ido Schimmel 2020-09-29 11:15:52 +03:00 committed by David S. Miller
parent 5855357cd4
commit 8ee2267ad3
5 changed files with 42 additions and 80 deletions

View File

@ -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

View File

@ -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_ */

View File

@ -434,7 +434,6 @@ config NET_SOCK_MSG
config NET_DEVLINK
bool
default n
imply NET_DROP_MONITOR
config PAGE_POOL
bool

View File

@ -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 = {};

View File

@ -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);