Commit bbda0f0d authored by David S. Miller's avatar David S. Miller

Merge branch 'dsa-trace-events'

Vladimir Oltean says:

====================
DSA trace events

This series introduces the "dsa" trace event class, with the following
events:

$ trace-cmd list | grep dsa
dsa
dsa:dsa_fdb_add_hw
dsa:dsa_mdb_add_hw
dsa:dsa_fdb_del_hw
dsa:dsa_mdb_del_hw
dsa:dsa_fdb_add_bump
dsa:dsa_mdb_add_bump
dsa:dsa_fdb_del_drop
dsa:dsa_mdb_del_drop
dsa:dsa_fdb_del_not_found
dsa:dsa_mdb_del_not_found
dsa:dsa_lag_fdb_add_hw
dsa:dsa_lag_fdb_add_bump
dsa:dsa_lag_fdb_del_hw
dsa:dsa_lag_fdb_del_drop
dsa:dsa_lag_fdb_del_not_found
dsa:dsa_vlan_add_hw
dsa:dsa_vlan_del_hw
dsa:dsa_vlan_add_bump
dsa:dsa_vlan_del_drop
dsa:dsa_vlan_del_not_found

These are useful to debug refcounting issues on CPU and DSA ports, where
entries may remain lingering, or may be removed too soon, depending on
bugs in higher layers of the network stack.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 18bb56ab 02020bd7
......@@ -16,7 +16,8 @@ dsa_core-y += \
slave.o \
switch.o \
tag.o \
tag_8021q.o
tag_8021q.o \
trace.o
# tagging formats
obj-$(CONFIG_NET_DSA_TAG_AR9331) += tag_ar9331.o
......@@ -37,3 +38,6 @@ obj-$(CONFIG_NET_DSA_TAG_RZN1_A5PSW) += tag_rzn1_a5psw.o
obj-$(CONFIG_NET_DSA_TAG_SJA1105) += tag_sja1105.o
obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o
obj-$(CONFIG_NET_DSA_TAG_XRS700X) += tag_xrs700x.o
# for tracing framework to find trace.h
CFLAGS_trace.o := -I$(src)
......@@ -18,6 +18,7 @@
#include "slave.h"
#include "switch.h"
#include "tag_8021q.h"
#include "trace.h"
static unsigned int dsa_switch_fastest_ageing_time(struct dsa_switch *ds,
unsigned int ageing_time)
......@@ -164,14 +165,20 @@ static int dsa_port_do_mdb_add(struct dsa_port *dp,
int err = 0;
/* No need to bother with refcounting for user ports */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
return ds->ops->port_mdb_add(ds, port, mdb, db);
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp))) {
err = ds->ops->port_mdb_add(ds, port, mdb, db);
trace_dsa_mdb_add_hw(dp, mdb->addr, mdb->vid, &db, err);
return err;
}
mutex_lock(&dp->addr_lists_lock);
a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid, db);
if (a) {
refcount_inc(&a->refcount);
trace_dsa_mdb_add_bump(dp, mdb->addr, mdb->vid, &db,
&a->refcount);
goto out;
}
......@@ -182,6 +189,7 @@ static int dsa_port_do_mdb_add(struct dsa_port *dp,
}
err = ds->ops->port_mdb_add(ds, port, mdb, db);
trace_dsa_mdb_add_hw(dp, mdb->addr, mdb->vid, &db, err);
if (err) {
kfree(a);
goto out;
......@@ -209,21 +217,30 @@ static int dsa_port_do_mdb_del(struct dsa_port *dp,
int err = 0;
/* No need to bother with refcounting for user ports */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
return ds->ops->port_mdb_del(ds, port, mdb, db);
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp))) {
err = ds->ops->port_mdb_del(ds, port, mdb, db);
trace_dsa_mdb_del_hw(dp, mdb->addr, mdb->vid, &db, err);
return err;
}
mutex_lock(&dp->addr_lists_lock);
a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid, db);
if (!a) {
trace_dsa_mdb_del_not_found(dp, mdb->addr, mdb->vid, &db);
err = -ENOENT;
goto out;
}
if (!refcount_dec_and_test(&a->refcount))
if (!refcount_dec_and_test(&a->refcount)) {
trace_dsa_mdb_del_drop(dp, mdb->addr, mdb->vid, &db,
&a->refcount);
goto out;
}
err = ds->ops->port_mdb_del(ds, port, mdb, db);
trace_dsa_mdb_del_hw(dp, mdb->addr, mdb->vid, &db, err);
if (err) {
refcount_set(&a->refcount, 1);
goto out;
......@@ -247,14 +264,19 @@ static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
int err = 0;
/* No need to bother with refcounting for user ports */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
return ds->ops->port_fdb_add(ds, port, addr, vid, db);
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp))) {
err = ds->ops->port_fdb_add(ds, port, addr, vid, db);
trace_dsa_fdb_add_hw(dp, addr, vid, &db, err);
return err;
}
mutex_lock(&dp->addr_lists_lock);
a = dsa_mac_addr_find(&dp->fdbs, addr, vid, db);
if (a) {
refcount_inc(&a->refcount);
trace_dsa_fdb_add_bump(dp, addr, vid, &db, &a->refcount);
goto out;
}
......@@ -265,6 +287,7 @@ static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
}
err = ds->ops->port_fdb_add(ds, port, addr, vid, db);
trace_dsa_fdb_add_hw(dp, addr, vid, &db, err);
if (err) {
kfree(a);
goto out;
......@@ -291,21 +314,29 @@ static int dsa_port_do_fdb_del(struct dsa_port *dp, const unsigned char *addr,
int err = 0;
/* No need to bother with refcounting for user ports */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
return ds->ops->port_fdb_del(ds, port, addr, vid, db);
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp))) {
err = ds->ops->port_fdb_del(ds, port, addr, vid, db);
trace_dsa_fdb_del_hw(dp, addr, vid, &db, err);
return err;
}
mutex_lock(&dp->addr_lists_lock);
a = dsa_mac_addr_find(&dp->fdbs, addr, vid, db);
if (!a) {
trace_dsa_fdb_del_not_found(dp, addr, vid, &db);
err = -ENOENT;
goto out;
}
if (!refcount_dec_and_test(&a->refcount))
if (!refcount_dec_and_test(&a->refcount)) {
trace_dsa_fdb_del_drop(dp, addr, vid, &db, &a->refcount);
goto out;
}
err = ds->ops->port_fdb_del(ds, port, addr, vid, db);
trace_dsa_fdb_del_hw(dp, addr, vid, &db, err);
if (err) {
refcount_set(&a->refcount, 1);
goto out;
......@@ -332,6 +363,8 @@ static int dsa_switch_do_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag *lag,
a = dsa_mac_addr_find(&lag->fdbs, addr, vid, db);
if (a) {
refcount_inc(&a->refcount);
trace_dsa_lag_fdb_add_bump(lag->dev, addr, vid, &db,
&a->refcount);
goto out;
}
......@@ -342,6 +375,7 @@ static int dsa_switch_do_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag *lag,
}
err = ds->ops->lag_fdb_add(ds, *lag, addr, vid, db);
trace_dsa_lag_fdb_add_hw(lag->dev, addr, vid, &db, err);
if (err) {
kfree(a);
goto out;
......@@ -370,14 +404,19 @@ static int dsa_switch_do_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag *lag,
a = dsa_mac_addr_find(&lag->fdbs, addr, vid, db);
if (!a) {
trace_dsa_lag_fdb_del_not_found(lag->dev, addr, vid, &db);
err = -ENOENT;
goto out;
}
if (!refcount_dec_and_test(&a->refcount))
if (!refcount_dec_and_test(&a->refcount)) {
trace_dsa_lag_fdb_del_drop(lag->dev, addr, vid, &db,
&a->refcount);
goto out;
}
err = ds->ops->lag_fdb_del(ds, *lag, addr, vid, db);
trace_dsa_lag_fdb_del_hw(lag->dev, addr, vid, &db, err);
if (err) {
refcount_set(&a->refcount, 1);
goto out;
......@@ -656,8 +695,12 @@ static int dsa_port_do_vlan_add(struct dsa_port *dp,
int err = 0;
/* No need to bother with refcounting for user ports. */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
return ds->ops->port_vlan_add(ds, port, vlan, extack);
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp))) {
err = ds->ops->port_vlan_add(ds, port, vlan, extack);
trace_dsa_vlan_add_hw(dp, vlan, err);
return err;
}
/* No need to propagate on shared ports the existing VLANs that were
* re-notified after just the flags have changed. This would cause a
......@@ -672,6 +715,7 @@ static int dsa_port_do_vlan_add(struct dsa_port *dp,
v = dsa_vlan_find(&dp->vlans, vlan);
if (v) {
refcount_inc(&v->refcount);
trace_dsa_vlan_add_bump(dp, vlan, &v->refcount);
goto out;
}
......@@ -682,6 +726,7 @@ static int dsa_port_do_vlan_add(struct dsa_port *dp,
}
err = ds->ops->port_vlan_add(ds, port, vlan, extack);
trace_dsa_vlan_add_hw(dp, vlan, err);
if (err) {
kfree(v);
goto out;
......@@ -706,21 +751,29 @@ static int dsa_port_do_vlan_del(struct dsa_port *dp,
int err = 0;
/* No need to bother with refcounting for user ports */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
return ds->ops->port_vlan_del(ds, port, vlan);
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp))) {
err = ds->ops->port_vlan_del(ds, port, vlan);
trace_dsa_vlan_del_hw(dp, vlan, err);
return err;
}
mutex_lock(&dp->vlans_lock);
v = dsa_vlan_find(&dp->vlans, vlan);
if (!v) {
trace_dsa_vlan_del_not_found(dp, vlan);
err = -ENOENT;
goto out;
}
if (!refcount_dec_and_test(&v->refcount))
if (!refcount_dec_and_test(&v->refcount)) {
trace_dsa_vlan_del_drop(dp, vlan, &v->refcount);
goto out;
}
err = ds->ops->port_vlan_del(ds, port, vlan);
trace_dsa_vlan_del_hw(dp, vlan, err);
if (err) {
refcount_set(&v->refcount, 1);
goto out;
......
// SPDX-License-Identifier: GPL-2.0-or-later
/* Copyright 2022-2023 NXP
*/
#define CREATE_TRACE_POINTS
#include "trace.h"
void dsa_db_print(const struct dsa_db *db, char buf[DSA_DB_BUFSIZ])
{
switch (db->type) {
case DSA_DB_PORT:
sprintf(buf, "port %s", db->dp->name);
break;
case DSA_DB_LAG:
sprintf(buf, "lag %s id %d", db->lag.dev->name, db->lag.id);
break;
case DSA_DB_BRIDGE:
sprintf(buf, "bridge %s num %d", db->bridge.dev->name,
db->bridge.num);
break;
default:
sprintf(buf, "unknown");
break;
}
}
const char *dsa_port_kind(const struct dsa_port *dp)
{
switch (dp->type) {
case DSA_PORT_TYPE_USER:
return "user";
case DSA_PORT_TYPE_CPU:
return "cpu";
case DSA_PORT_TYPE_DSA:
return "dsa";
default:
return "unused";
}
}
/* SPDX-License-Identifier: GPL-2.0
* Copyright 2022-2023 NXP
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM dsa
#if !defined(_NET_DSA_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
#define _NET_DSA_TRACE_H
#include <net/dsa.h>
#include <net/switchdev.h>
#include <linux/etherdevice.h>
#include <linux/if_bridge.h>
#include <linux/refcount.h>
#include <linux/tracepoint.h>
/* Enough to fit "bridge %s num %d" where num has 3 digits */
#define DSA_DB_BUFSIZ (IFNAMSIZ + 16)
void dsa_db_print(const struct dsa_db *db, char buf[DSA_DB_BUFSIZ]);
const char *dsa_port_kind(const struct dsa_port *dp);
DECLARE_EVENT_CLASS(dsa_port_addr_op_hw,
TP_PROTO(const struct dsa_port *dp, const unsigned char *addr, u16 vid,
const struct dsa_db *db, int err),
TP_ARGS(dp, addr, vid, db, err),
TP_STRUCT__entry(
__string(dev, dev_name(dp->ds->dev))
__string(kind, dsa_port_kind(dp))
__field(int, port)
__array(unsigned char, addr, ETH_ALEN)
__field(u16, vid)
__array(char, db_buf, DSA_DB_BUFSIZ)
__field(int, err)
),
TP_fast_assign(
__assign_str(dev, dev_name(dp->ds->dev));
__assign_str(kind, dsa_port_kind(dp));
__entry->port = dp->index;
ether_addr_copy(__entry->addr, addr);
__entry->vid = vid;
dsa_db_print(db, __entry->db_buf);
__entry->err = err;
),
TP_printk("%s %s port %d addr %pM vid %u db \"%s\" err %d",
__get_str(dev), __get_str(kind), __entry->port, __entry->addr,
__entry->vid, __entry->db_buf, __entry->err)
);
/* Add unicast/multicast address to hardware, either on user ports
* (where no refcounting is kept), or on shared ports when the entry
* is first seen and its refcount is 1.
*/
DEFINE_EVENT(dsa_port_addr_op_hw, dsa_fdb_add_hw,
TP_PROTO(const struct dsa_port *dp, const unsigned char *addr,
u16 vid, const struct dsa_db *db, int err),
TP_ARGS(dp, addr, vid, db, err));
DEFINE_EVENT(dsa_port_addr_op_hw, dsa_mdb_add_hw,
TP_PROTO(const struct dsa_port *dp, const unsigned char *addr,
u16 vid, const struct dsa_db *db, int err),
TP_ARGS(dp, addr, vid, db, err));
/* Delete unicast/multicast address from hardware, either on user ports or
* when the refcount on shared ports reaches 0
*/
DEFINE_EVENT(dsa_port_addr_op_hw, dsa_fdb_del_hw,
TP_PROTO(const struct dsa_port *dp, const unsigned char *addr,
u16 vid, const struct dsa_db *db, int err),
TP_ARGS(dp, addr, vid, db, err));
DEFINE_EVENT(dsa_port_addr_op_hw, dsa_mdb_del_hw,
TP_PROTO(const struct dsa_port *dp, const unsigned char *addr,
u16 vid, const struct dsa_db *db, int err),
TP_ARGS(dp, addr, vid, db, err));
DECLARE_EVENT_CLASS(dsa_port_addr_op_refcount,
TP_PROTO(const struct dsa_port *dp, const unsigned char *addr, u16 vid,
const struct dsa_db *db, const refcount_t *refcount),
TP_ARGS(dp, addr, vid, db, refcount),
TP_STRUCT__entry(
__string(dev, dev_name(dp->ds->dev))
__string(kind, dsa_port_kind(dp))
__field(int, port)
__array(unsigned char, addr, ETH_ALEN)
__field(u16, vid)
__array(char, db_buf, DSA_DB_BUFSIZ)
__field(unsigned int, refcount)
),
TP_fast_assign(
__assign_str(dev, dev_name(dp->ds->dev));
__assign_str(kind, dsa_port_kind(dp));
__entry->port = dp->index;
ether_addr_copy(__entry->addr, addr);
__entry->vid = vid;
dsa_db_print(db, __entry->db_buf);
__entry->refcount = refcount_read(refcount);
),
TP_printk("%s %s port %d addr %pM vid %u db \"%s\" refcount %u",
__get_str(dev), __get_str(kind), __entry->port, __entry->addr,
__entry->vid, __entry->db_buf, __entry->refcount)
);
/* Bump the refcount of an existing unicast/multicast address on shared ports */
DEFINE_EVENT(dsa_port_addr_op_refcount, dsa_fdb_add_bump,
TP_PROTO(const struct dsa_port *dp, const unsigned char *addr,
u16 vid, const struct dsa_db *db,
const refcount_t *refcount),
TP_ARGS(dp, addr, vid, db, refcount));
DEFINE_EVENT(dsa_port_addr_op_refcount, dsa_mdb_add_bump,
TP_PROTO(const struct dsa_port *dp, const unsigned char *addr,
u16 vid, const struct dsa_db *db,
const refcount_t *refcount),
TP_ARGS(dp, addr, vid, db, refcount));
/* Drop the refcount of a multicast address that we still keep on
* shared ports
*/
DEFINE_EVENT(dsa_port_addr_op_refcount, dsa_fdb_del_drop,
TP_PROTO(const struct dsa_port *dp, const unsigned char *addr,
u16 vid, const struct dsa_db *db,
const refcount_t *refcount),
TP_ARGS(dp, addr, vid, db, refcount));
DEFINE_EVENT(dsa_port_addr_op_refcount, dsa_mdb_del_drop,
TP_PROTO(const struct dsa_port *dp, const unsigned char *addr,
u16 vid, const struct dsa_db *db,
const refcount_t *refcount),
TP_ARGS(dp, addr, vid, db, refcount));
DECLARE_EVENT_CLASS(dsa_port_addr_del_not_found,
TP_PROTO(const struct dsa_port *dp, const unsigned char *addr, u16 vid,
const struct dsa_db *db),
TP_ARGS(dp, addr, vid, db),
TP_STRUCT__entry(
__string(dev, dev_name(dp->ds->dev))
__string(kind, dsa_port_kind(dp))
__field(int, port)
__array(unsigned char, addr, ETH_ALEN)
__field(u16, vid)
__array(char, db_buf, DSA_DB_BUFSIZ)
),
TP_fast_assign(
__assign_str(dev, dev_name(dp->ds->dev));
__assign_str(kind, dsa_port_kind(dp));
__entry->port = dp->index;
ether_addr_copy(__entry->addr, addr);
__entry->vid = vid;
dsa_db_print(db, __entry->db_buf);
),
TP_printk("%s %s port %d addr %pM vid %u db \"%s\"",
__get_str(dev), __get_str(kind), __entry->port,
__entry->addr, __entry->vid, __entry->db_buf)
);
/* Attempt to delete a unicast/multicast address on shared ports for which
* the delete operation was called more times than the addition
*/
DEFINE_EVENT(dsa_port_addr_del_not_found, dsa_fdb_del_not_found,
TP_PROTO(const struct dsa_port *dp, const unsigned char *addr,
u16 vid, const struct dsa_db *db),
TP_ARGS(dp, addr, vid, db));
DEFINE_EVENT(dsa_port_addr_del_not_found, dsa_mdb_del_not_found,
TP_PROTO(const struct dsa_port *dp, const unsigned char *addr,
u16 vid, const struct dsa_db *db),
TP_ARGS(dp, addr, vid, db));
TRACE_EVENT(dsa_lag_fdb_add_hw,
TP_PROTO(const struct net_device *lag_dev, const unsigned char *addr,
u16 vid, const struct dsa_db *db, int err),
TP_ARGS(lag_dev, addr, vid, db, err),
TP_STRUCT__entry(
__string(dev, lag_dev->name)
__array(unsigned char, addr, ETH_ALEN)
__field(u16, vid)
__array(char, db_buf, DSA_DB_BUFSIZ)
__field(int, err)
),
TP_fast_assign(
__assign_str(dev, lag_dev->name);
ether_addr_copy(__entry->addr, addr);
__entry->vid = vid;
dsa_db_print(db, __entry->db_buf);
__entry->err = err;
),
TP_printk("%s addr %pM vid %u db \"%s\" err %d",
__get_str(dev), __entry->addr, __entry->vid,
__entry->db_buf, __entry->err)
);
TRACE_EVENT(dsa_lag_fdb_add_bump,
TP_PROTO(const struct net_device *lag_dev, const unsigned char *addr,
u16 vid, const struct dsa_db *db, const refcount_t *refcount),
TP_ARGS(lag_dev, addr, vid, db, refcount),
TP_STRUCT__entry(
__string(dev, lag_dev->name)
__array(unsigned char, addr, ETH_ALEN)
__field(u16, vid)
__array(char, db_buf, DSA_DB_BUFSIZ)
__field(unsigned int, refcount)
),
TP_fast_assign(
__assign_str(dev, lag_dev->name);
ether_addr_copy(__entry->addr, addr);
__entry->vid = vid;
dsa_db_print(db, __entry->db_buf);
__entry->refcount = refcount_read(refcount);
),
TP_printk("%s addr %pM vid %u db \"%s\" refcount %u",
__get_str(dev), __entry->addr, __entry->vid,
__entry->db_buf, __entry->refcount)
);
TRACE_EVENT(dsa_lag_fdb_del_hw,
TP_PROTO(const struct net_device *lag_dev, const unsigned char *addr,
u16 vid, const struct dsa_db *db, int err),
TP_ARGS(lag_dev, addr, vid, db, err),
TP_STRUCT__entry(
__string(dev, lag_dev->name)
__array(unsigned char, addr, ETH_ALEN)
__field(u16, vid)
__array(char, db_buf, DSA_DB_BUFSIZ)
__field(int, err)
),
TP_fast_assign(
__assign_str(dev, lag_dev->name);
ether_addr_copy(__entry->addr, addr);
__entry->vid = vid;
dsa_db_print(db, __entry->db_buf);
__entry->err = err;
),
TP_printk("%s addr %pM vid %u db \"%s\" err %d",
__get_str(dev), __entry->addr, __entry->vid,
__entry->db_buf, __entry->err)
);
TRACE_EVENT(dsa_lag_fdb_del_drop,
TP_PROTO(const struct net_device *lag_dev, const unsigned char *addr,
u16 vid, const struct dsa_db *db, const refcount_t *refcount),
TP_ARGS(lag_dev, addr, vid, db, refcount),
TP_STRUCT__entry(
__string(dev, lag_dev->name)
__array(unsigned char, addr, ETH_ALEN)
__field(u16, vid)
__array(char, db_buf, DSA_DB_BUFSIZ)
__field(unsigned int, refcount)
),
TP_fast_assign(
__assign_str(dev, lag_dev->name);
ether_addr_copy(__entry->addr, addr);
__entry->vid = vid;
dsa_db_print(db, __entry->db_buf);
__entry->refcount = refcount_read(refcount);
),
TP_printk("%s addr %pM vid %u db \"%s\" refcount %u",
__get_str(dev), __entry->addr, __entry->vid,
__entry->db_buf, __entry->refcount)
);
TRACE_EVENT(dsa_lag_fdb_del_not_found,
TP_PROTO(const struct net_device *lag_dev, const unsigned char *addr,
u16 vid, const struct dsa_db *db),
TP_ARGS(lag_dev, addr, vid, db),
TP_STRUCT__entry(
__string(dev, lag_dev->name)
__array(unsigned char, addr, ETH_ALEN)
__field(u16, vid)
__array(char, db_buf, DSA_DB_BUFSIZ)
),
TP_fast_assign(
__assign_str(dev, lag_dev->name);
ether_addr_copy(__entry->addr, addr);
__entry->vid = vid;
dsa_db_print(db, __entry->db_buf);
),
TP_printk("%s addr %pM vid %u db \"%s\"",
__get_str(dev), __entry->addr, __entry->vid, __entry->db_buf)
);
DECLARE_EVENT_CLASS(dsa_vlan_op_hw,
TP_PROTO(const struct dsa_port *dp,
const struct switchdev_obj_port_vlan *vlan, int err),
TP_ARGS(dp, vlan, err),
TP_STRUCT__entry(
__string(dev, dev_name(dp->ds->dev))
__string(kind, dsa_port_kind(dp))
__field(int, port)
__field(u16, vid)
__field(u16, flags)
__field(bool, changed)
__field(int, err)
),
TP_fast_assign(
__assign_str(dev, dev_name(dp->ds->dev));
__assign_str(kind, dsa_port_kind(dp));
__entry->port = dp->index;
__entry->vid = vlan->vid;
__entry->flags = vlan->flags;
__entry->changed = vlan->changed;
__entry->err = err;
),
TP_printk("%s %s port %d vid %u%s%s%s",
__get_str(dev), __get_str(kind), __entry->port, __entry->vid,
__entry->flags & BRIDGE_VLAN_INFO_PVID ? " pvid" : "",
__entry->flags & BRIDGE_VLAN_INFO_UNTAGGED ? " untagged" : "",
__entry->changed ? " (changed)" : "")
);
DEFINE_EVENT(dsa_vlan_op_hw, dsa_vlan_add_hw,
TP_PROTO(const struct dsa_port *dp,
const struct switchdev_obj_port_vlan *vlan, int err),
TP_ARGS(dp, vlan, err));
DEFINE_EVENT(dsa_vlan_op_hw, dsa_vlan_del_hw,
TP_PROTO(const struct dsa_port *dp,
const struct switchdev_obj_port_vlan *vlan, int err),
TP_ARGS(dp, vlan, err));
DECLARE_EVENT_CLASS(dsa_vlan_op_refcount,
TP_PROTO(const struct dsa_port *dp,
const struct switchdev_obj_port_vlan *vlan,
const refcount_t *refcount),
TP_ARGS(dp, vlan, refcount),
TP_STRUCT__entry(
__string(dev, dev_name(dp->ds->dev))
__string(kind, dsa_port_kind(dp))
__field(int, port)
__field(u16, vid)
__field(u16, flags)
__field(bool, changed)
__field(unsigned int, refcount)
),
TP_fast_assign(
__assign_str(dev, dev_name(dp->ds->dev));
__assign_str(kind, dsa_port_kind(dp));
__entry->port = dp->index;
__entry->vid = vlan->vid;
__entry->flags = vlan->flags;
__entry->changed = vlan->changed;
__entry->refcount = refcount_read(refcount);
),
TP_printk("%s %s port %d vid %u%s%s%s refcount %u",
__get_str(dev), __get_str(kind), __entry->port, __entry->vid,
__entry->flags & BRIDGE_VLAN_INFO_PVID ? " pvid" : "",
__entry->flags & BRIDGE_VLAN_INFO_UNTAGGED ? " untagged" : "",
__entry->changed ? " (changed)" : "", __entry->refcount)
);
DEFINE_EVENT(dsa_vlan_op_refcount, dsa_vlan_add_bump,
TP_PROTO(const struct dsa_port *dp,
const struct switchdev_obj_port_vlan *vlan,
const refcount_t *refcount),
TP_ARGS(dp, vlan, refcount));
DEFINE_EVENT(dsa_vlan_op_refcount, dsa_vlan_del_drop,
TP_PROTO(const struct dsa_port *dp,
const struct switchdev_obj_port_vlan *vlan,
const refcount_t *refcount),
TP_ARGS(dp, vlan, refcount));
TRACE_EVENT(dsa_vlan_del_not_found,
TP_PROTO(const struct dsa_port *dp,
const struct switchdev_obj_port_vlan *vlan),
TP_ARGS(dp, vlan),
TP_STRUCT__entry(
__string(dev, dev_name(dp->ds->dev))
__string(kind, dsa_port_kind(dp))
__field(int, port)
__field(u16, vid)
),
TP_fast_assign(
__assign_str(dev, dev_name(dp->ds->dev));
__assign_str(kind, dsa_port_kind(dp));
__entry->port = dp->index;
__entry->vid = vlan->vid;
),
TP_printk("%s %s port %d vid %u",
__get_str(dev), __get_str(kind), __entry->port, __entry->vid)
);
#endif /* _NET_DSA_TRACE_H */
/* We don't want to use include/trace/events */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE trace
/* This part must be outside protection */
#include <trace/define_trace.h>
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