net/mlx5: Bridge, add tracepoints

Move private bridge structures to dedicated headers that is accessible to
bridge tracepoint header. Implemented following tracepoints:

- Initialize FDB entry.
- Refresh FDB entry.
- Cleanup FDB entry.
- Create VLAN.
- Cleanup VLAN.
- Attach port to bridge.
- Detach port from bridge.

Usage example:

># cd /sys/kernel/debug/tracing
># echo mlx5:mlx5_esw_bridge_fdb_entry_init >> set_event
># cat trace
...
   kworker/u20:1-96      [001] ....   231.892503: mlx5_esw_bridge_fdb_entry_init: net_device=enp8s0f0_0 addr=e4:fd:05:08:00:02 vid=3 flags=0 lastuse=4294895695

Signed-off-by: Vlad Buslov <vladbu@nvidia.com>
Reviewed-by: Jianbo Liu <jianbol@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
This commit is contained in:
Vlad Buslov 2021-04-02 21:16:13 +03:00 коммит произвёл Saeed Mahameed
Родитель cc2987c44b
Коммит 9724fd5d9c
4 изменённых файлов: 247 добавлений и 50 удалений

Просмотреть файл

@ -600,3 +600,59 @@ tc and eswitch offloads tracepoints:
$ cat /sys/kernel/debug/tracing/trace
...
kworker/u48:7-2221 [009] ...1 1475.387435: mlx5e_rep_neigh_update: netdev: ens1f0 MAC: 24:8a:07:9a:17:9a IPv4: 1.1.1.10 IPv6: ::ffff:1.1.1.10 neigh_connected=1
Bridge offloads tracepoints:
- mlx5_esw_bridge_fdb_entry_init: trace bridge FDB entry offloaded to mlx5::
$ echo mlx5:mlx5_esw_bridge_fdb_entry_init >> set_event
$ cat /sys/kernel/debug/tracing/trace
...
kworker/u20:9-2217 [003] ...1 318.582243: mlx5_esw_bridge_fdb_entry_init: net_device=enp8s0f0_0 addr=e4:fd:05:08:00:02 vid=0 flags=0 used=0
- mlx5_esw_bridge_fdb_entry_cleanup: trace bridge FDB entry deleted from mlx5::
$ echo mlx5:mlx5_esw_bridge_fdb_entry_cleanup >> set_event
$ cat /sys/kernel/debug/tracing/trace
...
ip-2581 [005] ...1 318.629871: mlx5_esw_bridge_fdb_entry_cleanup: net_device=enp8s0f0_1 addr=e4:fd:05:08:00:03 vid=0 flags=0 used=16
- mlx5_esw_bridge_fdb_entry_refresh: trace bridge FDB entry offload refreshed in
mlx5::
$ echo mlx5:mlx5_esw_bridge_fdb_entry_refresh >> set_event
$ cat /sys/kernel/debug/tracing/trace
...
kworker/u20:8-3849 [003] ...1 466716: mlx5_esw_bridge_fdb_entry_refresh: net_device=enp8s0f0_0 addr=e4:fd:05:08:00:02 vid=3 flags=0 used=0
- mlx5_esw_bridge_vlan_create: trace bridge VLAN object add on mlx5
representor::
$ echo mlx5:mlx5_esw_bridge_vlan_create >> set_event
$ cat /sys/kernel/debug/tracing/trace
...
ip-2560 [007] ...1 318.460258: mlx5_esw_bridge_vlan_create: vid=1 flags=6
- mlx5_esw_bridge_vlan_cleanup: trace bridge VLAN object delete from mlx5
representor::
$ echo mlx5:mlx5_esw_bridge_vlan_cleanup >> set_event
$ cat /sys/kernel/debug/tracing/trace
...
bridge-2582 [007] ...1 318.653496: mlx5_esw_bridge_vlan_cleanup: vid=2 flags=8
- mlx5_esw_bridge_vport_init: trace mlx5 vport assigned with bridge upper
device::
$ echo mlx5:mlx5_esw_bridge_vport_init >> set_event
$ cat /sys/kernel/debug/tracing/trace
...
ip-2560 [007] ...1 318.458915: mlx5_esw_bridge_vport_init: vport_num=1
- mlx5_esw_bridge_vport_cleanup: trace mlx5 vport removed from bridge upper
device::
$ echo mlx5:mlx5_esw_bridge_vport_cleanup >> set_event
$ cat /sys/kernel/debug/tracing/trace
...
ip-5387 [000] ...1 573713: mlx5_esw_bridge_vport_cleanup: vport_num=1

Просмотреть файл

@ -1,17 +1,15 @@
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/* Copyright (c) 2021 Mellanox Technologies. */
#include <linux/netdevice.h>
#include <linux/list.h>
#include <linux/rhashtable.h>
#include <linux/xarray.h>
#include <linux/if_bridge.h>
#include <linux/if_vlan.h>
#include <linux/if_ether.h>
#include <linux/notifier.h>
#include <net/netevent.h>
#include <net/switchdev.h>
#include "bridge.h"
#include "eswitch.h"
#include "fs_core.h"
#include "bridge_priv.h"
#define CREATE_TRACE_POINTS
#include "diag/bridge_tracepoint.h"
#define MLX5_ESW_BRIDGE_INGRESS_TABLE_SIZE 64000
#define MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_IDX_FROM 0
@ -39,31 +37,6 @@ enum {
MLX5_ESW_BRIDGE_LEVEL_SKIP_TABLE,
};
struct mlx5_esw_bridge_fdb_key {
unsigned char addr[ETH_ALEN];
u16 vid;
};
enum {
MLX5_ESW_BRIDGE_FLAG_ADDED_BY_USER = BIT(0),
};
struct mlx5_esw_bridge_fdb_entry {
struct mlx5_esw_bridge_fdb_key key;
struct rhash_head ht_node;
struct net_device *dev;
struct list_head list;
struct list_head vlan_list;
u16 vport_num;
u16 flags;
struct mlx5_flow_handle *ingress_handle;
struct mlx5_fc *ingress_counter;
unsigned long lastuse;
struct mlx5_flow_handle *egress_handle;
struct mlx5_flow_handle *filter_handle;
};
static const struct rhashtable_params fdb_ht_params = {
.key_offset = offsetof(struct mlx5_esw_bridge_fdb_entry, key),
.key_len = sizeof(struct mlx5_esw_bridge_fdb_key),
@ -71,19 +44,6 @@ static const struct rhashtable_params fdb_ht_params = {
.automatic_shrinking = true,
};
struct mlx5_esw_bridge_vlan {
u16 vid;
u16 flags;
struct list_head fdb_list;
struct mlx5_pkt_reformat *pkt_reformat_push;
struct mlx5_pkt_reformat *pkt_reformat_pop;
};
struct mlx5_esw_bridge_port {
u16 vport_num;
struct xarray vlans;
};
enum {
MLX5_ESW_BRIDGE_VLAN_FILTERING_FLAG = BIT(0),
};
@ -697,10 +657,23 @@ static void mlx5_esw_bridge_port_erase(struct mlx5_esw_bridge_port *port,
xa_erase(&bridge->vports, port->vport_num);
}
static void mlx5_esw_bridge_fdb_entry_refresh(unsigned long lastuse,
struct mlx5_esw_bridge_fdb_entry *entry)
{
trace_mlx5_esw_bridge_fdb_entry_refresh(entry);
entry->lastuse = lastuse;
mlx5_esw_bridge_fdb_offload_notify(entry->dev, entry->key.addr,
entry->key.vid,
SWITCHDEV_FDB_ADD_TO_BRIDGE);
}
static void
mlx5_esw_bridge_fdb_entry_cleanup(struct mlx5_esw_bridge_fdb_entry *entry,
struct mlx5_esw_bridge *bridge)
{
trace_mlx5_esw_bridge_fdb_entry_cleanup(entry);
rhashtable_remove_fast(&bridge->fdb_ht, &entry->ht_node, fdb_ht_params);
mlx5_del_flow_rules(entry->egress_handle);
if (entry->filter_handle)
@ -842,6 +815,7 @@ mlx5_esw_bridge_vlan_create(u16 vid, u16 flags, struct mlx5_esw_bridge_port *por
if (err)
goto err_xa_insert;
trace_mlx5_esw_bridge_vlan_create(vlan);
return vlan;
err_xa_insert:
@ -884,6 +858,7 @@ static void mlx5_esw_bridge_vlan_cleanup(struct mlx5_esw_bridge_port *port,
struct mlx5_esw_bridge_vlan *vlan,
struct mlx5_esw_bridge *bridge)
{
trace_mlx5_esw_bridge_vlan_cleanup(vlan);
mlx5_esw_bridge_vlan_flush(vlan, bridge);
mlx5_esw_bridge_vlan_erase(port, vlan);
kvfree(vlan);
@ -1007,6 +982,8 @@ mlx5_esw_bridge_fdb_entry_init(struct net_device *dev, u16 vport_num, const unsi
else
INIT_LIST_HEAD(&entry->vlan_list);
list_add(&entry->list, &bridge->fdb_list);
trace_mlx5_esw_bridge_fdb_entry_init(entry);
return entry;
err_ht_init:
@ -1078,6 +1055,7 @@ static int mlx5_esw_bridge_vport_init(struct mlx5_esw_bridge_offloads *br_offloa
vport->vport, err);
goto err_port_insert;
}
trace_mlx5_esw_bridge_vport_init(port);
vport->bridge = bridge;
return 0;
@ -1106,6 +1084,7 @@ static int mlx5_esw_bridge_vport_cleanup(struct mlx5_esw_bridge_offloads *br_off
return -EINVAL;
}
trace_mlx5_esw_bridge_vport_cleanup(port);
mlx5_esw_bridge_port_vlans_flush(port, bridge);
mlx5_esw_bridge_port_erase(port, bridge);
kvfree(port);
@ -1266,11 +1245,7 @@ void mlx5_esw_bridge_update(struct mlx5_esw_bridge_offloads *br_offloads)
continue;
if (time_after(lastuse, entry->lastuse)) {
entry->lastuse = lastuse;
/* refresh existing bridge entry */
mlx5_esw_bridge_fdb_offload_notify(entry->dev, entry->key.addr,
entry->key.vid,
SWITCHDEV_FDB_ADD_TO_BRIDGE);
mlx5_esw_bridge_fdb_entry_refresh(lastuse, entry);
} else if (time_is_before_jiffies(entry->lastuse + bridge->ageing_time)) {
mlx5_esw_bridge_fdb_offload_notify(entry->dev, entry->key.addr,
entry->key.vid,

Просмотреть файл

@ -0,0 +1,53 @@
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2021 Mellanox Technologies. */
#ifndef _MLX5_ESW_BRIDGE_PRIVATE_
#define _MLX5_ESW_BRIDGE_PRIVATE_
#include <linux/netdevice.h>
#include <linux/if_bridge.h>
#include <linux/if_vlan.h>
#include <linux/if_ether.h>
#include <linux/rhashtable.h>
#include <linux/xarray.h>
#include "fs_core.h"
struct mlx5_esw_bridge_fdb_key {
unsigned char addr[ETH_ALEN];
u16 vid;
};
enum {
MLX5_ESW_BRIDGE_FLAG_ADDED_BY_USER = BIT(0),
};
struct mlx5_esw_bridge_fdb_entry {
struct mlx5_esw_bridge_fdb_key key;
struct rhash_head ht_node;
struct net_device *dev;
struct list_head list;
struct list_head vlan_list;
u16 vport_num;
u16 flags;
struct mlx5_flow_handle *ingress_handle;
struct mlx5_fc *ingress_counter;
unsigned long lastuse;
struct mlx5_flow_handle *egress_handle;
struct mlx5_flow_handle *filter_handle;
};
struct mlx5_esw_bridge_vlan {
u16 vid;
u16 flags;
struct list_head fdb_list;
struct mlx5_pkt_reformat *pkt_reformat_push;
struct mlx5_pkt_reformat *pkt_reformat_pop;
};
struct mlx5_esw_bridge_port {
u16 vport_num;
struct xarray vlans;
};
#endif /* _MLX5_ESW_BRIDGE_PRIVATE_ */

Просмотреть файл

@ -0,0 +1,113 @@
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2021 Mellanox Technologies. */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM mlx5
#if !defined(_MLX5_ESW_BRIDGE_TRACEPOINT_) || defined(TRACE_HEADER_MULTI_READ)
#define _MLX5_ESW_BRIDGE_TRACEPOINT_
#include <linux/tracepoint.h>
#include "../bridge_priv.h"
DECLARE_EVENT_CLASS(mlx5_esw_bridge_fdb_template,
TP_PROTO(const struct mlx5_esw_bridge_fdb_entry *fdb),
TP_ARGS(fdb),
TP_STRUCT__entry(
__array(char, dev_name, IFNAMSIZ)
__array(unsigned char, addr, ETH_ALEN)
__field(u16, vid)
__field(u16, flags)
__field(unsigned int, used)
),
TP_fast_assign(
strncpy(__entry->dev_name,
netdev_name(fdb->dev),
IFNAMSIZ);
memcpy(__entry->addr, fdb->key.addr, ETH_ALEN);
__entry->vid = fdb->key.vid;
__entry->flags = fdb->flags;
__entry->used = jiffies_to_msecs(jiffies - fdb->lastuse)
),
TP_printk("net_device=%s addr=%pM vid=%hu flags=%hx used=%u",
__entry->dev_name,
__entry->addr,
__entry->vid,
__entry->flags,
__entry->used / 1000)
);
DEFINE_EVENT(mlx5_esw_bridge_fdb_template,
mlx5_esw_bridge_fdb_entry_init,
TP_PROTO(const struct mlx5_esw_bridge_fdb_entry *fdb),
TP_ARGS(fdb)
);
DEFINE_EVENT(mlx5_esw_bridge_fdb_template,
mlx5_esw_bridge_fdb_entry_refresh,
TP_PROTO(const struct mlx5_esw_bridge_fdb_entry *fdb),
TP_ARGS(fdb)
);
DEFINE_EVENT(mlx5_esw_bridge_fdb_template,
mlx5_esw_bridge_fdb_entry_cleanup,
TP_PROTO(const struct mlx5_esw_bridge_fdb_entry *fdb),
TP_ARGS(fdb)
);
DECLARE_EVENT_CLASS(mlx5_esw_bridge_vlan_template,
TP_PROTO(const struct mlx5_esw_bridge_vlan *vlan),
TP_ARGS(vlan),
TP_STRUCT__entry(
__field(u16, vid)
__field(u16, flags)
),
TP_fast_assign(
__entry->vid = vlan->vid;
__entry->flags = vlan->flags;
),
TP_printk("vid=%hu flags=%hx",
__entry->vid,
__entry->flags)
);
DEFINE_EVENT(mlx5_esw_bridge_vlan_template,
mlx5_esw_bridge_vlan_create,
TP_PROTO(const struct mlx5_esw_bridge_vlan *vlan),
TP_ARGS(vlan)
);
DEFINE_EVENT(mlx5_esw_bridge_vlan_template,
mlx5_esw_bridge_vlan_cleanup,
TP_PROTO(const struct mlx5_esw_bridge_vlan *vlan),
TP_ARGS(vlan)
);
DECLARE_EVENT_CLASS(mlx5_esw_bridge_port_template,
TP_PROTO(const struct mlx5_esw_bridge_port *port),
TP_ARGS(port),
TP_STRUCT__entry(
__field(u16, vport_num)
),
TP_fast_assign(
__entry->vport_num = port->vport_num;
),
TP_printk("vport_num=%hu", __entry->vport_num)
);
DEFINE_EVENT(mlx5_esw_bridge_port_template,
mlx5_esw_bridge_vport_init,
TP_PROTO(const struct mlx5_esw_bridge_port *port),
TP_ARGS(port)
);
DEFINE_EVENT(mlx5_esw_bridge_port_template,
mlx5_esw_bridge_vport_cleanup,
TP_PROTO(const struct mlx5_esw_bridge_port *port),
TP_ARGS(port)
);
#endif
/* This part must be outside protection */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH esw/diag
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE bridge_tracepoint
#include <trace/define_trace.h>