Skip to content

Commit 5855357

Browse files
idoschdavem330
authored andcommitted
drop_monitor: Prepare probe functions for devlink tracepoint
Drop monitor supports two alerting modes: Summary and packet. Prepare a probe function for each, so that they could be later registered on the devlink tracepoint by calling register_trace_devlink_trap_report(), based on the configured alerting mode. Signed-off-by: Ido Schimmel <[email protected]> Reviewed-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5b88823 commit 5855357

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed

net/core/drop_monitor.c

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <net/genetlink.h>
3131
#include <net/netevent.h>
3232
#include <net/flow_offload.h>
33+
#include <net/devlink.h>
3334

3435
#include <trace/events/skb.h>
3536
#include <trace/events/napi.h>
@@ -116,6 +117,9 @@ struct net_dm_alert_ops {
116117
void (*hw_work_item_func)(struct work_struct *work);
117118
void (*hw_probe)(struct sk_buff *skb,
118119
const struct net_dm_hw_metadata *hw_metadata);
120+
void (*hw_trap_probe)(void *ignore, const struct devlink *devlink,
121+
struct sk_buff *skb,
122+
const struct devlink_trap_metadata *metadata);
119123
};
120124

121125
struct net_dm_skb_cb {
@@ -474,12 +478,57 @@ net_dm_hw_summary_probe(struct sk_buff *skb,
474478
spin_unlock_irqrestore(&hw_data->lock, flags);
475479
}
476480

481+
static void
482+
net_dm_hw_trap_summary_probe(void *ignore, const struct devlink *devlink,
483+
struct sk_buff *skb,
484+
const struct devlink_trap_metadata *metadata)
485+
{
486+
struct net_dm_hw_entries *hw_entries;
487+
struct net_dm_hw_entry *hw_entry;
488+
struct per_cpu_dm_data *hw_data;
489+
unsigned long flags;
490+
int i;
491+
492+
hw_data = this_cpu_ptr(&dm_hw_cpu_data);
493+
spin_lock_irqsave(&hw_data->lock, flags);
494+
hw_entries = hw_data->hw_entries;
495+
496+
if (!hw_entries)
497+
goto out;
498+
499+
for (i = 0; i < hw_entries->num_entries; i++) {
500+
hw_entry = &hw_entries->entries[i];
501+
if (!strncmp(hw_entry->trap_name, metadata->trap_name,
502+
NET_DM_MAX_HW_TRAP_NAME_LEN - 1)) {
503+
hw_entry->count++;
504+
goto out;
505+
}
506+
}
507+
if (WARN_ON_ONCE(hw_entries->num_entries == dm_hit_limit))
508+
goto out;
509+
510+
hw_entry = &hw_entries->entries[hw_entries->num_entries];
511+
strlcpy(hw_entry->trap_name, metadata->trap_name,
512+
NET_DM_MAX_HW_TRAP_NAME_LEN - 1);
513+
hw_entry->count = 1;
514+
hw_entries->num_entries++;
515+
516+
if (!timer_pending(&hw_data->send_timer)) {
517+
hw_data->send_timer.expires = jiffies + dm_delay * HZ;
518+
add_timer(&hw_data->send_timer);
519+
}
520+
521+
out:
522+
spin_unlock_irqrestore(&hw_data->lock, flags);
523+
}
524+
477525
static const struct net_dm_alert_ops net_dm_alert_summary_ops = {
478526
.kfree_skb_probe = trace_kfree_skb_hit,
479527
.napi_poll_probe = trace_napi_poll_hit,
480528
.work_item_func = send_dm_alert,
481529
.hw_work_item_func = net_dm_hw_summary_work,
482530
.hw_probe = net_dm_hw_summary_probe,
531+
.hw_trap_probe = net_dm_hw_trap_summary_probe,
483532
};
484533

485534
static void net_dm_packet_trace_kfree_skb_hit(void *ignore,
@@ -858,6 +907,54 @@ net_dm_hw_metadata_clone(const struct net_dm_hw_metadata *hw_metadata)
858907
return NULL;
859908
}
860909

910+
static struct net_dm_hw_metadata *
911+
net_dm_hw_metadata_copy(const struct devlink_trap_metadata *metadata)
912+
{
913+
const struct flow_action_cookie *fa_cookie;
914+
struct net_dm_hw_metadata *hw_metadata;
915+
const char *trap_group_name;
916+
const char *trap_name;
917+
918+
hw_metadata = kzalloc(sizeof(*hw_metadata), GFP_ATOMIC);
919+
if (!hw_metadata)
920+
return NULL;
921+
922+
trap_group_name = kstrdup(metadata->trap_group_name, GFP_ATOMIC);
923+
if (!trap_group_name)
924+
goto free_hw_metadata;
925+
hw_metadata->trap_group_name = trap_group_name;
926+
927+
trap_name = kstrdup(metadata->trap_name, GFP_ATOMIC);
928+
if (!trap_name)
929+
goto free_trap_group;
930+
hw_metadata->trap_name = trap_name;
931+
932+
if (metadata->fa_cookie) {
933+
size_t cookie_size = sizeof(*fa_cookie) +
934+
metadata->fa_cookie->cookie_len;
935+
936+
fa_cookie = kmemdup(metadata->fa_cookie, cookie_size,
937+
GFP_ATOMIC);
938+
if (!fa_cookie)
939+
goto free_trap_name;
940+
hw_metadata->fa_cookie = fa_cookie;
941+
}
942+
943+
hw_metadata->input_dev = metadata->input_dev;
944+
if (hw_metadata->input_dev)
945+
dev_hold(hw_metadata->input_dev);
946+
947+
return hw_metadata;
948+
949+
free_trap_name:
950+
kfree(trap_name);
951+
free_trap_group:
952+
kfree(trap_group_name);
953+
free_hw_metadata:
954+
kfree(hw_metadata);
955+
return NULL;
956+
}
957+
861958
static void
862959
net_dm_hw_metadata_free(const struct net_dm_hw_metadata *hw_metadata)
863960
{
@@ -970,12 +1067,61 @@ net_dm_hw_packet_probe(struct sk_buff *skb,
9701067
consume_skb(nskb);
9711068
}
9721069

1070+
static void
1071+
net_dm_hw_trap_packet_probe(void *ignore, const struct devlink *devlink,
1072+
struct sk_buff *skb,
1073+
const struct devlink_trap_metadata *metadata)
1074+
{
1075+
struct net_dm_hw_metadata *n_hw_metadata;
1076+
ktime_t tstamp = ktime_get_real();
1077+
struct per_cpu_dm_data *hw_data;
1078+
struct sk_buff *nskb;
1079+
unsigned long flags;
1080+
1081+
if (!skb_mac_header_was_set(skb))
1082+
return;
1083+
1084+
nskb = skb_clone(skb, GFP_ATOMIC);
1085+
if (!nskb)
1086+
return;
1087+
1088+
n_hw_metadata = net_dm_hw_metadata_copy(metadata);
1089+
if (!n_hw_metadata)
1090+
goto free;
1091+
1092+
NET_DM_SKB_CB(nskb)->hw_metadata = n_hw_metadata;
1093+
nskb->tstamp = tstamp;
1094+
1095+
hw_data = this_cpu_ptr(&dm_hw_cpu_data);
1096+
1097+
spin_lock_irqsave(&hw_data->drop_queue.lock, flags);
1098+
if (skb_queue_len(&hw_data->drop_queue) < net_dm_queue_len)
1099+
__skb_queue_tail(&hw_data->drop_queue, nskb);
1100+
else
1101+
goto unlock_free;
1102+
spin_unlock_irqrestore(&hw_data->drop_queue.lock, flags);
1103+
1104+
schedule_work(&hw_data->dm_alert_work);
1105+
1106+
return;
1107+
1108+
unlock_free:
1109+
spin_unlock_irqrestore(&hw_data->drop_queue.lock, flags);
1110+
u64_stats_update_begin(&hw_data->stats.syncp);
1111+
hw_data->stats.dropped++;
1112+
u64_stats_update_end(&hw_data->stats.syncp);
1113+
net_dm_hw_metadata_free(n_hw_metadata);
1114+
free:
1115+
consume_skb(nskb);
1116+
}
1117+
9731118
static const struct net_dm_alert_ops net_dm_alert_packet_ops = {
9741119
.kfree_skb_probe = net_dm_packet_trace_kfree_skb_hit,
9751120
.napi_poll_probe = net_dm_packet_trace_napi_poll_hit,
9761121
.work_item_func = net_dm_packet_work,
9771122
.hw_work_item_func = net_dm_hw_packet_work,
9781123
.hw_probe = net_dm_hw_packet_probe,
1124+
.hw_trap_probe = net_dm_hw_trap_packet_probe,
9791125
};
9801126

9811127
static const struct net_dm_alert_ops *net_dm_alert_ops_arr[] = {

0 commit comments

Comments
 (0)