* [PATCH for-next 3/4] devlink: fix boolean JSON print
From: Aya Levin @ 2019-02-10 18:28 UTC (permalink / raw)
To: David Ahern, netdev, David S. Miller, Jiri Pirko
Cc: Moshe Shemesh, Aya Levin, Eran Ben Elisha, Tal Alon, Ariel Almog
In-Reply-To: <1549823329-10377-1-git-send-email-ayal@mellanox.com>
This patch removes the inverted commas from boolean values in JSON
format: true/false instead of "true"/"false".
Signed-off-by: Aya Levin <ayal@mellanox.com>
Reviewed-by: Moshe Shemesh <moshe@mellanox.com>
---
devlink/devlink.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/devlink/devlink.c b/devlink/devlink.c
index 46e2e41c5dfd..a433883f1b2b 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -1605,10 +1605,10 @@ static void pr_out_str(struct dl *dl, const char *name, const char *val)
static void pr_out_bool(struct dl *dl, const char *name, bool val)
{
- if (val)
- pr_out_str(dl, name, "true");
+ if (dl->json_output)
+ jsonw_bool_field(dl->jw, name, val);
else
- pr_out_str(dl, name, "false");
+ pr_out_str(dl, name, val ? "true" : "false");
}
static void pr_out_uint(struct dl *dl, const char *name, unsigned int val)
--
2.14.1
^ permalink raw reply related
* [PATCH for-next 2/4] devlink: fix print of uint64_t
From: Aya Levin @ 2019-02-10 18:28 UTC (permalink / raw)
To: David Ahern, netdev, David S. Miller, Jiri Pirko
Cc: Moshe Shemesh, Aya Levin, Eran Ben Elisha, Tal Alon, Ariel Almog
In-Reply-To: <1549823329-10377-1-git-send-email-ayal@mellanox.com>
This patch prints uint64_t with its corresponding format and avoid implicit
cast to uint32_t.
Signed-off-by: Aya Levin <ayal@mellanox.com>
Reviewed-by: Moshe Shemesh <moshe@mellanox.com>
Reported-by: Maria Pasechnik <mariap@mellanox.com>
---
devlink/devlink.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/devlink/devlink.c b/devlink/devlink.c
index a05755385a49..46e2e41c5dfd 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -1628,7 +1628,14 @@ static void pr_out_u64(struct dl *dl, const char *name, uint64_t val)
if (val == (uint64_t) -1)
return pr_out_str(dl, name, "unlimited");
- return pr_out_uint(dl, name, val);
+ if (dl->json_output) {
+ jsonw_u64_field(dl->jw, name, val);
+ } else {
+ if (g_indent_newline)
+ pr_out("%s %lu", name, val);
+ else
+ pr_out(" %s %lu", name, val);
+ }
}
static void pr_out_region_chunk_start(struct dl *dl, uint64_t addr)
--
2.14.1
^ permalink raw reply related
* [PATCH for-next 1/4] devlink: refactor validation of finding required arguments
From: Aya Levin @ 2019-02-10 18:28 UTC (permalink / raw)
To: David Ahern, netdev, David S. Miller, Jiri Pirko
Cc: Moshe Shemesh, Aya Levin, Eran Ben Elisha, Tal Alon, Ariel Almog
In-Reply-To: <1549823329-10377-1-git-send-email-ayal@mellanox.com>
Introducing argument's metadata structure matching a bitmap flag per
required argument and an error message if missing. Using this static
array to refactor validation of finding required arguments in devlink
command line and to ease further maintenance.
Signed-off-by: Aya Levin <ayal@mellanox.com>
Reviewed-by: Moshe Shemesh <moshe@mellanox.com>
---
devlink/devlink.c | 155 +++++++++++++++++-------------------------------------
1 file changed, 47 insertions(+), 108 deletions(-)
diff --git a/devlink/devlink.c b/devlink/devlink.c
index d823512a4030..a05755385a49 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -39,6 +39,7 @@
#define PARAM_CMODE_RUNTIME_STR "runtime"
#define PARAM_CMODE_DRIVERINIT_STR "driverinit"
#define PARAM_CMODE_PERMANENT_STR "permanent"
+#define DL_ARGS_REQUIRED_MAX_ERR_LEN 80
static int g_new_line_count;
@@ -950,6 +951,51 @@ static int param_cmode_get(const char *cmodestr,
return 0;
}
+struct dl_args_metadata {
+ uint32_t o_flag;
+ char err_msg[DL_ARGS_REQUIRED_MAX_ERR_LEN];
+};
+
+static const struct dl_args_metadata dl_args_required[] = {
+ {DL_OPT_PORT_TYPE, "Port type not set.\n"},
+ {DL_OPT_PORT_COUNT, "Port split count option expected.\n"},
+ {DL_OPT_SB_POOL, "Pool index option expected.\n"},
+ {DL_OPT_SB_SIZE, "Pool size option expected.\n"},
+ {DL_OPT_SB_TYPE, "Pool type option expected.\n"},
+ {DL_OPT_SB_THTYPE, "Pool threshold type option expected.\n"},
+ {DL_OPT_SB_TH, "Threshold option expected.\n"},
+ {DL_OPT_SB_TC, "TC index option expected.\n"},
+ {DL_OPT_ESWITCH_MODE, "E-Switch mode option expected.\n"},
+ {DL_OPT_ESWITCH_INLINE_MODE, "E-Switch inline-mode option expected.\n"},
+ {DL_OPT_DPIPE_TABLE_NAME, "Dpipe table name expected\n"},
+ {DL_OPT_DPIPE_TABLE_COUNTERS, "Dpipe table counter state expected\n"},
+ {DL_OPT_ESWITCH_ENCAP_MODE, "E-Switch encapsulation option expected.\n"},
+ {DL_OPT_PARAM_NAME, "Parameter name expected.\n"},
+ {DL_OPT_PARAM_VALUE, "Value to set expected.\n"},
+ {DL_OPT_PARAM_CMODE, "Configuration mode expected.\n"},
+ {DL_OPT_REGION_SNAPSHOT_ID, "Region snapshot id expected.\n"},
+ {DL_OPT_REGION_ADDRESS, "Region address value expected.\n"},
+ {DL_OPT_REGION_LENGTH, "Region length value expected.\n"},
+};
+
+static int validate_finding_required_dl_args(uint32_t o_required,
+ uint32_t o_found)
+{
+ uint32_t dl_args_required_size;
+ uint32_t o_flag;
+ int i;
+
+ dl_args_required_size = ARRAY_SIZE(dl_args_required);
+ for (i = 0; i < dl_args_required_size; i++) {
+ o_flag = dl_args_required[i].o_flag;
+ if ((o_required & o_flag) && !(o_found & o_flag)) {
+ pr_err("%s", dl_args_required[i].err_msg);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
static int dl_argv_parse(struct dl *dl, uint32_t o_required,
uint32_t o_optional)
{
@@ -1198,114 +1244,7 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required,
opts->present |= DL_OPT_SB;
}
- if ((o_required & DL_OPT_PORT_TYPE) && !(o_found & DL_OPT_PORT_TYPE)) {
- pr_err("Port type option expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_PORT_COUNT) &&
- !(o_found & DL_OPT_PORT_COUNT)) {
- pr_err("Port split count option expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_SB_POOL) && !(o_found & DL_OPT_SB_POOL)) {
- pr_err("Pool index option expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_SB_SIZE) && !(o_found & DL_OPT_SB_SIZE)) {
- pr_err("Pool size option expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_SB_TYPE) && !(o_found & DL_OPT_SB_TYPE)) {
- pr_err("Pool type option expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_SB_THTYPE) && !(o_found & DL_OPT_SB_THTYPE)) {
- pr_err("Pool threshold type option expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_SB_TH) && !(o_found & DL_OPT_SB_TH)) {
- pr_err("Threshold option expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_SB_TC) && !(o_found & DL_OPT_SB_TC)) {
- pr_err("TC index option expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_ESWITCH_MODE) &&
- !(o_found & DL_OPT_ESWITCH_MODE)) {
- pr_err("E-Switch mode option expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_ESWITCH_INLINE_MODE) &&
- !(o_found & DL_OPT_ESWITCH_INLINE_MODE)) {
- pr_err("E-Switch inline-mode option expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_DPIPE_TABLE_NAME) &&
- !(o_found & DL_OPT_DPIPE_TABLE_NAME)) {
- pr_err("Dpipe table name expected\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_DPIPE_TABLE_COUNTERS) &&
- !(o_found & DL_OPT_DPIPE_TABLE_COUNTERS)) {
- pr_err("Dpipe table counter state expected\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_ESWITCH_ENCAP_MODE) &&
- !(o_found & DL_OPT_ESWITCH_ENCAP_MODE)) {
- pr_err("E-Switch encapsulation option expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_PARAM_NAME) &&
- !(o_found & DL_OPT_PARAM_NAME)) {
- pr_err("Parameter name expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_PARAM_VALUE) &&
- !(o_found & DL_OPT_PARAM_VALUE)) {
- pr_err("Value to set expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_PARAM_CMODE) &&
- !(o_found & DL_OPT_PARAM_CMODE)) {
- pr_err("Configuration mode expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_REGION_SNAPSHOT_ID) &&
- !(o_found & DL_OPT_REGION_SNAPSHOT_ID)) {
- pr_err("Region snapshot id expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_REGION_ADDRESS) &&
- !(o_found & DL_OPT_REGION_ADDRESS)) {
- pr_err("Region address value expected.\n");
- return -EINVAL;
- }
-
- if ((o_required & DL_OPT_REGION_LENGTH) &&
- !(o_found & DL_OPT_REGION_LENGTH)) {
- pr_err("Region length value expected.\n");
- return -EINVAL;
- }
-
- return 0;
+ return validate_finding_required_dl_args(o_required, o_found);
}
static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
--
2.14.1
^ permalink raw reply related
* [iproute2-next, 0/4] Add support for devlink health
From: Aya Levin @ 2019-02-10 18:28 UTC (permalink / raw)
To: David Ahern, netdev, David S. Miller, Jiri Pirko
Cc: Moshe Shemesh, Aya Levin, Eran Ben Elisha, Tal Alon, Ariel Almog
In-Reply-To: <1549532202-943-1-git-send-email-eranbe@mellanox.com>
This series adds support for devlink health commands:
devlink health show [DEV reporter REPORTE_NAME]
devlink health recover DEV reporter REPORTER_NAME
devlink health diagnose DEV reporter REPORTER_NAME
devlink health dump show DEV reporter REPORTER_NAME
devlink health dump clear DEV reporter REPORTER_NAME
devlink health set DEV reporter REPORTER_NAME NAME VALUE
The first patch refactors the validation of input parameters, which
grow way too long. Patch 2 and 3 fix bugs that were discovered during
the devlink health development. Patch 4 adds the devlink health
functionality.
Aya Levin (4):
devlink: refactor validation of finding required arguments
devlink: fix print of uint64_t
devlink: fix boolean JSON print
devlink: add health command support
devlink/devlink.c | 721 ++++++++++++++++++++++++++++++++++++-------
include/uapi/linux/devlink.h | 23 ++
man/man8/devlink-health.8 | 176 +++++++++++
man/man8/devlink.8 | 7 +-
4 files changed, 813 insertions(+), 114 deletions(-)
create mode 100644 man/man8/devlink-health.8
--
2.14.1
^ permalink raw reply
* [PATCH net-next v2 00/16] net: Remove switchdev_ops
From: Florian Fainelli @ 2019-02-10 17:50 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
Hi all,
This patch series finishes by the removal of switchdev_ops. To get there
we need to do a few things:
- get rid of the one and only call to switchdev_port_attr_get() which is
used to fetch the device's bridge port flags capabilities, instead we
can just check what flags are being programmed during the prepare
phase
- once we get rid of getting switchdev port attributes we convert the
setting of such attributes using a blocking notifier
And then remove switchdev_ops completely.
Please review and let me know what you think!
Changes in v2:
- fixed bisectability issues in patch #15
- added Acked-by from Jiri where necessary
- fixed a few minor issues according to Jiri's feedback:
- rename port_attr_event -> port_attr_set_event
- moved SWITCHDEV_PORT_ATTR_SET closer to other blocking events
Florian Fainelli (16):
Documentation: networking: switchdev: Update port parent ID section
mlxsw: spectrum: Check bridge flags during prepare phase
staging: fsl-dpaa2: ethsw: Check bridge port flags during set
net: dsa: Add setter for SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS
rocker: Check bridge flags during prepare phase
net: bridge: Stop calling switchdev_port_attr_get()
net: Remove SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT
net: Get rid of switchdev_port_attr_get()
switchdev: Add SWITCHDEV_PORT_ATTR_SET
rocker: Handle SWITCHDEV_PORT_ATTR_SET
net: dsa: Handle SWITCHDEV_PORT_ATTR_SET
mlxsw: spectrum_switchdev: Handle SWITCHDEV_PORT_ATTR_SET
net: mscc: ocelot: Handle SWITCHDEV_PORT_ATTR_SET
staging: fsl-dpaa2: ethsw: Handle SWITCHDEV_PORT_ATTR_SET
net: switchdev: Replace port attr set SDO with a notification
net: Remove switchdev_ops
Documentation/networking/switchdev.txt | 15 ++-
.../net/ethernet/mellanox/mlxsw/spectrum.c | 12 ---
.../net/ethernet/mellanox/mlxsw/spectrum.h | 2 -
.../mellanox/mlxsw/spectrum_switchdev.c | 69 ++++----------
drivers/net/ethernet/mscc/ocelot.c | 21 +++-
drivers/net/ethernet/rocker/rocker_main.c | 95 ++++++++-----------
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 48 ++++------
include/linux/netdevice.h | 3 -
include/net/switchdev.h | 36 ++-----
net/bridge/br_switchdev.c | 20 +---
net/dsa/dsa_priv.h | 3 +
net/dsa/port.c | 10 ++
net/dsa/slave.c | 40 ++++----
net/switchdev/switchdev.c | 92 +++++-------------
14 files changed, 170 insertions(+), 296 deletions(-)
--
2.19.1
^ permalink raw reply
* [PATCH net-next v2 01/16] Documentation: networking: switchdev: Update port parent ID section
From: Florian Fainelli @ 2019-02-10 17:50 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
Update the section about switchdev drivers having to implement a
switchdev_port_attr_get() function to return
SWITCHDEV_ATTR_ID_PORT_PARENT_ID since that is no longer valid after
commit bccb30254a4a ("net: Get rid of
SWITCHDEV_ATTR_ID_PORT_PARENT_ID").
Fixes: bccb30254a4a ("net: Get rid of SWITCHDEV_ATTR_ID_PORT_PARENT_ID")
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Documentation/networking/switchdev.txt | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/Documentation/networking/switchdev.txt b/Documentation/networking/switchdev.txt
index f3244d87512a..ea90243340a9 100644
--- a/Documentation/networking/switchdev.txt
+++ b/Documentation/networking/switchdev.txt
@@ -92,11 +92,11 @@ device.
Switch ID
^^^^^^^^^
-The switchdev driver must implement the switchdev op switchdev_port_attr_get
-for SWITCHDEV_ATTR_ID_PORT_PARENT_ID for each port netdev, returning the same
-physical ID for each port of a switch. The ID must be unique between switches
-on the same system. The ID does not need to be unique between switches on
-different systems.
+The switchdev driver must implement the net_device operation
+ndo_get_port_parent_id for each port netdev, returning the same physical ID for
+each port of a switch. The ID must be unique between switches on the same
+system. The ID does not need to be unique between switches on different
+systems.
The switch ID is used to locate ports on a switch and to know if aggregated
ports belong to the same switch.
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 02/16] mlxsw: spectrum: Check bridge flags during prepare phase
From: Florian Fainelli @ 2019-02-10 17:50 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
In preparation for getting rid of switchdev_port_attr_get(), have mlxsw
check for the bridge flags being set through switchdev_port_attr_set()
with the SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS attribute identifier.
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 95e37de3e48f..468a6d513074 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -623,8 +623,11 @@ static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
struct mlxsw_sp_bridge_port *bridge_port;
int err;
- if (switchdev_trans_ph_prepare(trans))
+ if (switchdev_trans_ph_prepare(trans)) {
+ if (brport_flags & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD))
+ return -EOPNOTSUPP;
return 0;
+ }
bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp_port->mlxsw_sp->bridge,
orig_dev);
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 04/16] net: dsa: Add setter for SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS
From: Florian Fainelli @ 2019-02-10 17:50 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
In preparation for removing SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT,
add support for a function that processes the
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS attribute and returns not supported
for any flag set, since DSA does not currently support toggling those
bridge port attributes (yet).
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
net/dsa/dsa_priv.h | 3 +++
net/dsa/port.c | 10 ++++++++++
net/dsa/slave.c | 4 ++++
3 files changed, 17 insertions(+)
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 1f4972dab9f2..97594f0b6efb 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -150,6 +150,9 @@ int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
struct switchdev_trans *trans);
int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock,
struct switchdev_trans *trans);
+int dsa_port_bridge_port_flags_set(struct dsa_port *dp,
+ unsigned long brport_flags,
+ struct switchdev_trans *trans);
int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
u16 vid);
int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 2d7e01b23572..2ce3752203cf 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -177,6 +177,16 @@ int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock,
return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
}
+int dsa_port_bridge_port_flags_set(struct dsa_port *dp,
+ unsigned long brport_flags,
+ struct switchdev_trans *trans)
+{
+ if (brport_flags)
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+
int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
u16 vid)
{
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 2e5e7c04821b..9b499ba88aa7 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -295,6 +295,10 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
ret = dsa_port_ageing_time(dp, attr->u.ageing_time, trans);
break;
+ case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
+ ret = dsa_port_bridge_port_flags_set(dp, attr->u.brport_flags,
+ trans);
+ break;
default:
ret = -EOPNOTSUPP;
break;
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 06/16] net: bridge: Stop calling switchdev_port_attr_get()
From: Florian Fainelli @ 2019-02-10 17:50 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
Now that all switchdev drivers have been converted to checking the
bridge port flags during the prepare phase of the
switchdev_port_attr_set(), we can move straight to trying to set the
desired flag through SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS.
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
net/bridge/br_switchdev.c | 20 +++-----------------
1 file changed, 3 insertions(+), 17 deletions(-)
diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
index db9e8ab96d48..939f300522c5 100644
--- a/net/bridge/br_switchdev.c
+++ b/net/bridge/br_switchdev.c
@@ -64,29 +64,15 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
{
struct switchdev_attr attr = {
.orig_dev = p->dev,
- .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT,
+ .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
+ .flags = SWITCHDEV_F_DEFER,
+ .u.brport_flags = flags,
};
int err;
if (mask & ~BR_PORT_FLAGS_HW_OFFLOAD)
return 0;
- err = switchdev_port_attr_get(p->dev, &attr);
- if (err == -EOPNOTSUPP)
- return 0;
- if (err)
- return err;
-
- /* Check if specific bridge flag attribute offload is supported */
- if (!(attr.u.brport_flags_support & mask)) {
- br_warn(p->br, "bridge flag offload is not supported %u(%s)\n",
- (unsigned int)p->port_no, p->dev->name);
- return -EOPNOTSUPP;
- }
-
- attr.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS;
- attr.flags = SWITCHDEV_F_DEFER;
- attr.u.brport_flags = flags;
err = switchdev_port_attr_set(p->dev, &attr);
if (err) {
br_warn(p->br, "error setting offload flag on port %u(%s)\n",
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 07/16] net: Remove SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT
From: Florian Fainelli @ 2019-02-10 17:50 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
Now that we have converted the bridge code and the drivers to check for
bridge port(s) flags at the time we try to set them, there is no need
for a get() -> set() sequence anymore and
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT therefore becomes unused.
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
.../net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 4 ----
drivers/net/ethernet/rocker/rocker_main.c | 4 ----
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 3 ---
include/net/switchdev.h | 2 --
net/dsa/slave.c | 10 +---------
5 files changed, 1 insertion(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 468a6d513074..8242a373f6e7 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -455,10 +455,6 @@ static int mlxsw_sp_port_attr_get(struct net_device *dev,
mlxsw_sp_port_bridge_flags_get(mlxsw_sp->bridge, attr->orig_dev,
&attr->u.brport_flags);
break;
- case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
- attr->u.brport_flags_support = BR_LEARNING | BR_FLOOD |
- BR_MCAST_FLOOD;
- break;
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index 8657313b6f30..375c4c908bea 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2075,10 +2075,6 @@ static int rocker_port_attr_get(struct net_device *dev,
err = rocker_world_port_attr_bridge_flags_get(rocker_port,
&attr->u.brport_flags);
break;
- case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
- err = rocker_world_port_attr_bridge_flags_support_get(rocker_port,
- &attr->u.brport_flags_support);
- break;
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 6228c4375835..79635d1091df 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -651,9 +651,6 @@ static int swdev_port_attr_get(struct net_device *netdev,
(port_priv->ethsw_data->learning ? BR_LEARNING : 0) |
(port_priv->flood ? BR_FLOOD : 0);
break;
- case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
- attr->u.brport_flags_support = BR_LEARNING | BR_FLOOD;
- break;
default:
return -EOPNOTSUPP;
}
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 5e87b54c5dc5..e2083824e577 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -45,7 +45,6 @@ enum switchdev_attr_id {
SWITCHDEV_ATTR_ID_UNDEFINED,
SWITCHDEV_ATTR_ID_PORT_STP_STATE,
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
- SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT,
SWITCHDEV_ATTR_ID_PORT_MROUTER,
SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING,
@@ -62,7 +61,6 @@ struct switchdev_attr {
union {
u8 stp_state; /* PORT_STP_STATE */
unsigned long brport_flags; /* PORT_BRIDGE_FLAGS */
- unsigned long brport_flags_support; /* PORT_BRIDGE_FLAGS_SUPPORT */
bool mrouter; /* PORT_MROUTER */
clock_t ageing_time; /* BRIDGE_AGEING_TIME */
bool vlan_filtering; /* BRIDGE_VLAN_FILTERING */
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 9b499ba88aa7..7b33be6f1954 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -385,15 +385,7 @@ static int dsa_slave_get_port_parent_id(struct net_device *dev,
static int dsa_slave_port_attr_get(struct net_device *dev,
struct switchdev_attr *attr)
{
- switch (attr->id) {
- case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
- attr->u.brport_flags_support = 0;
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- return 0;
+ return -EOPNOTSUPP;
}
static inline netdev_tx_t dsa_slave_netpoll_send_skb(struct net_device *dev,
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 10/16] rocker: Handle SWITCHDEV_PORT_ATTR_SET
From: Florian Fainelli @ 2019-02-10 17:50 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare rocker to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_SET and simply translate that into the existing
rocker_port_attr_set call.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/rocker/rocker_main.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index ff3f14504f4f..b94f940dc7b5 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2811,6 +2811,20 @@ rocker_switchdev_port_obj_event(unsigned long event, struct net_device *netdev,
return notifier_from_errno(err);
}
+static int
+rocker_switchdev_port_attr_set_event(unsigned long event, struct net_device *netdev,
+ struct switchdev_notifier_port_attr_info
+ *port_attr_info)
+{
+ int err;
+
+ err = rocker_port_attr_set(netdev, port_attr_info->attr,
+ port_attr_info->trans);
+
+ port_attr_info->handled = true;
+ return notifier_from_errno(err);
+}
+
static int rocker_switchdev_blocking_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -2823,6 +2837,8 @@ static int rocker_switchdev_blocking_event(struct notifier_block *unused,
case SWITCHDEV_PORT_OBJ_ADD:
case SWITCHDEV_PORT_OBJ_DEL:
return rocker_switchdev_port_obj_event(event, dev, ptr);
+ case SWITCHDEV_PORT_ATTR_SET:
+ return rocker_switchdev_port_attr_set_event(event, dev, ptr);
}
return NOTIFY_DONE;
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 08/16] net: Get rid of switchdev_port_attr_get()
From: Florian Fainelli @ 2019-02-10 17:50 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
With the bridge no longer calling switchdev_port_attr_get() to obtain
the supported bridge port flags from a driver but instead trying to set
the bridge port flags directly and relying on driver to reject
unsupported configurations, we can effectively get rid of
switchdev_port_attr_get() entirely since this was the only place where
it was called.
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
Documentation/networking/switchdev.txt | 5 ++-
.../mellanox/mlxsw/spectrum_switchdev.c | 32 -------------------
drivers/net/ethernet/rocker/rocker_main.c | 30 -----------------
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 19 -----------
include/net/switchdev.h | 8 -----
net/dsa/slave.c | 7 ----
6 files changed, 2 insertions(+), 99 deletions(-)
diff --git a/Documentation/networking/switchdev.txt b/Documentation/networking/switchdev.txt
index ea90243340a9..327afe754230 100644
--- a/Documentation/networking/switchdev.txt
+++ b/Documentation/networking/switchdev.txt
@@ -233,9 +233,8 @@ the bridge's FDB. It's possible, but not optimal, to enable learning on the
device port and on the bridge port, and disable learning_sync.
To support learning and learning_sync port attributes, the driver implements
-switchdev op switchdev_port_attr_get/set for
-SWITCHDEV_ATTR_PORT_ID_BRIDGE_FLAGS. The driver should initialize the attributes
-to the hardware defaults.
+switchdev op switchdev_port_attr_set for SWITCHDEV_ATTR_PORT_ID_BRIDGE_FLAGS.
+The driver should initialize the attributes to the hardware defaults.
FDB Ageing
^^^^^^^^^^
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 8242a373f6e7..6b09d68671cf 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -431,37 +431,6 @@ static void mlxsw_sp_bridge_vlan_put(struct mlxsw_sp_bridge_vlan *bridge_vlan)
mlxsw_sp_bridge_vlan_destroy(bridge_vlan);
}
-static void mlxsw_sp_port_bridge_flags_get(struct mlxsw_sp_bridge *bridge,
- struct net_device *dev,
- unsigned long *brport_flags)
-{
- struct mlxsw_sp_bridge_port *bridge_port;
-
- bridge_port = mlxsw_sp_bridge_port_find(bridge, dev);
- if (WARN_ON(!bridge_port))
- return;
-
- memcpy(brport_flags, &bridge_port->flags, sizeof(*brport_flags));
-}
-
-static int mlxsw_sp_port_attr_get(struct net_device *dev,
- struct switchdev_attr *attr)
-{
- struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
- struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
-
- switch (attr->id) {
- case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
- mlxsw_sp_port_bridge_flags_get(mlxsw_sp->bridge, attr->orig_dev,
- &attr->u.brport_flags);
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
static int
mlxsw_sp_port_bridge_vlan_stp_set(struct mlxsw_sp_port *mlxsw_sp_port,
struct mlxsw_sp_bridge_vlan *bridge_vlan,
@@ -1957,7 +1926,6 @@ static struct mlxsw_sp_port *mlxsw_sp_lag_rep_port(struct mlxsw_sp *mlxsw_sp,
}
static const struct switchdev_ops mlxsw_sp_port_switchdev_ops = {
- .switchdev_port_attr_get = mlxsw_sp_port_attr_get,
.switchdev_port_attr_set = mlxsw_sp_port_attr_set,
};
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index 375c4c908bea..ff3f14504f4f 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -1606,17 +1606,6 @@ rocker_world_port_attr_bridge_flags_set(struct rocker_port *rocker_port,
trans);
}
-static int
-rocker_world_port_attr_bridge_flags_get(const struct rocker_port *rocker_port,
- unsigned long *p_brport_flags)
-{
- struct rocker_world_ops *wops = rocker_port->rocker->wops;
-
- if (!wops->port_attr_bridge_flags_get)
- return -EOPNOTSUPP;
- return wops->port_attr_bridge_flags_get(rocker_port, p_brport_flags);
-}
-
static int
rocker_world_port_attr_bridge_ageing_time_set(struct rocker_port *rocker_port,
u32 ageing_time,
@@ -2064,24 +2053,6 @@ static const struct net_device_ops rocker_port_netdev_ops = {
* swdev interface
********************/
-static int rocker_port_attr_get(struct net_device *dev,
- struct switchdev_attr *attr)
-{
- const struct rocker_port *rocker_port = netdev_priv(dev);
- int err = 0;
-
- switch (attr->id) {
- case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
- err = rocker_world_port_attr_bridge_flags_get(rocker_port,
- &attr->u.brport_flags);
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- return err;
-}
-
static int rocker_port_attr_set(struct net_device *dev,
const struct switchdev_attr *attr,
struct switchdev_trans *trans)
@@ -2154,7 +2125,6 @@ static int rocker_port_obj_del(struct net_device *dev,
}
static const struct switchdev_ops rocker_port_switchdev_ops = {
- .switchdev_port_attr_get = rocker_port_attr_get,
.switchdev_port_attr_set = rocker_port_attr_set,
};
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 79635d1091df..b195b09e0d1d 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -640,24 +640,6 @@ static void ethsw_teardown_irqs(struct fsl_mc_device *sw_dev)
fsl_mc_free_irqs(sw_dev);
}
-static int swdev_port_attr_get(struct net_device *netdev,
- struct switchdev_attr *attr)
-{
- struct ethsw_port_priv *port_priv = netdev_priv(netdev);
-
- switch (attr->id) {
- case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
- attr->u.brport_flags =
- (port_priv->ethsw_data->learning ? BR_LEARNING : 0) |
- (port_priv->flood ? BR_FLOOD : 0);
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
static int port_attr_stp_state_set(struct net_device *netdev,
struct switchdev_trans *trans,
u8 state)
@@ -933,7 +915,6 @@ static int swdev_port_obj_del(struct net_device *netdev,
}
static const struct switchdev_ops ethsw_port_switchdev_ops = {
- .switchdev_port_attr_get = swdev_port_attr_get,
.switchdev_port_attr_set = swdev_port_attr_set,
};
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index e2083824e577..96cd3e795f7f 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -178,8 +178,6 @@ switchdev_notifier_info_to_extack(const struct switchdev_notifier_info *info)
#ifdef CONFIG_NET_SWITCHDEV
void switchdev_deferred_process(void);
-int switchdev_port_attr_get(struct net_device *dev,
- struct switchdev_attr *attr);
int switchdev_port_attr_set(struct net_device *dev,
const struct switchdev_attr *attr);
int switchdev_port_obj_add(struct net_device *dev,
@@ -224,12 +222,6 @@ static inline void switchdev_deferred_process(void)
{
}
-static inline int switchdev_port_attr_get(struct net_device *dev,
- struct switchdev_attr *attr)
-{
- return -EOPNOTSUPP;
-}
-
static inline int switchdev_port_attr_set(struct net_device *dev,
const struct switchdev_attr *attr)
{
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 7b33be6f1954..d8eb33979368 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -382,12 +382,6 @@ static int dsa_slave_get_port_parent_id(struct net_device *dev,
return 0;
}
-static int dsa_slave_port_attr_get(struct net_device *dev,
- struct switchdev_attr *attr)
-{
- return -EOPNOTSUPP;
-}
-
static inline netdev_tx_t dsa_slave_netpoll_send_skb(struct net_device *dev,
struct sk_buff *skb)
{
@@ -1054,7 +1048,6 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
};
static const struct switchdev_ops dsa_slave_switchdev_ops = {
- .switchdev_port_attr_get = dsa_slave_port_attr_get,
.switchdev_port_attr_set = dsa_slave_port_attr_set,
};
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 09/16] switchdev: Add SWITCHDEV_PORT_ATTR_SET
From: Florian Fainelli @ 2019-02-10 17:50 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
In preparation for allowing switchdev enabled drivers to veto specific
attribute settings from within the context of the caller, introduce a
new switchdev notifier type for port attributes.
Suggested-by: Ido Schimmel <idosch@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
include/net/switchdev.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 96cd3e795f7f..7bc6a004d32a 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -135,6 +135,7 @@ enum switchdev_notifier_type {
SWITCHDEV_PORT_OBJ_ADD, /* Blocking. */
SWITCHDEV_PORT_OBJ_DEL, /* Blocking. */
+ SWITCHDEV_PORT_ATTR_SET, /* Blocking. */
SWITCHDEV_VXLAN_FDB_ADD_TO_BRIDGE,
SWITCHDEV_VXLAN_FDB_DEL_TO_BRIDGE,
@@ -163,6 +164,13 @@ struct switchdev_notifier_port_obj_info {
bool handled;
};
+struct switchdev_notifier_port_attr_info {
+ struct switchdev_notifier_info info; /* must be first */
+ const struct switchdev_attr *attr;
+ struct switchdev_trans *trans;
+ bool handled;
+};
+
static inline struct net_device *
switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
{
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 11/16] net: dsa: Handle SWITCHDEV_PORT_ATTR_SET
From: Florian Fainelli @ 2019-02-10 17:51 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare DSA to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_SET and simply translate that into the existing
dsa_slave_port_attr_set() call.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
net/dsa/slave.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index d8eb33979368..ee4b94c5e68e 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1547,6 +1547,20 @@ dsa_slave_switchdev_port_obj_event(unsigned long event,
return notifier_from_errno(err);
}
+static int
+dsa_slave_switchdev_port_attr_set_event(unsigned long event,
+ struct net_device *netdev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int err;
+
+ err = dsa_slave_port_attr_set(netdev, port_attr_info->attr,
+ port_attr_info->trans);
+
+ port_attr_info->handled = true;
+ return notifier_from_errno(err);
+}
+
static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -1559,6 +1573,8 @@ static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused,
case SWITCHDEV_PORT_OBJ_ADD: /* fall through */
case SWITCHDEV_PORT_OBJ_DEL:
return dsa_slave_switchdev_port_obj_event(event, dev, ptr);
+ case SWITCHDEV_PORT_ATTR_SET:
+ return dsa_slave_switchdev_port_attr_set_event(event, dev, ptr);
}
return NOTIFY_DONE;
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 13/16] net: mscc: ocelot: Handle SWITCHDEV_PORT_ATTR_SET
From: Florian Fainelli @ 2019-02-10 17:51 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare ocelot to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_SET and simply translate that into the existing
ocelot_port_attr_set() call.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/mscc/ocelot.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 195306d05bcd..1dda4dd4c073 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1582,6 +1582,20 @@ struct notifier_block ocelot_netdevice_nb __read_mostly = {
};
EXPORT_SYMBOL(ocelot_netdevice_nb);
+static int
+ocelot_switchdev_port_attr_set_event(unsigned long event,
+ struct net_device *netdev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int err;
+
+ err = ocelot_port_attr_set(netdev, port_attr_info->attr,
+ port_attr_info->trans);
+
+ port_attr_info->handled = true;
+ return notifier_from_errno(err);
+}
+
static int ocelot_switchdev_blocking_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -1600,6 +1614,8 @@ static int ocelot_switchdev_blocking_event(struct notifier_block *unused,
ocelot_netdevice_dev_check,
ocelot_port_obj_del);
return notifier_from_errno(err);
+ case SWITCHDEV_PORT_ATTR_SET:
+ return ocelot_switchdev_port_attr_set_event(event, dev, ptr);
}
return NOTIFY_DONE;
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 15/16] net: switchdev: Replace port attr set SDO with a notification
From: Florian Fainelli @ 2019-02-10 17:51 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
Drop switchdev_ops.switchdev_port_attr_set. Drop the uses of this field
from all clients, which were migrated to use switchdev notification in
the previous patches.
Add a new function switchdev_port_attr_notify() that sends the switchdev
notifications SWITCHDEV_PORT_ATTR_SET.
Drop __switchdev_port_attr_set() and update switchdev_port_attr_set()
likewise.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
net/switchdev/switchdev.c | 92 ++++++++++-----------------------------
1 file changed, 22 insertions(+), 70 deletions(-)
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 7e1357db33d7..fab96d978924 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -174,81 +174,31 @@ static int switchdev_deferred_enqueue(struct net_device *dev,
return 0;
}
-/**
- * switchdev_port_attr_get - Get port attribute
- *
- * @dev: port device
- * @attr: attribute to get
- */
-int switchdev_port_attr_get(struct net_device *dev, struct switchdev_attr *attr)
+static int switchdev_port_attr_notify(enum switchdev_notifier_type nt,
+ struct net_device *dev,
+ const struct switchdev_attr *attr,
+ struct switchdev_trans *trans)
{
- const struct switchdev_ops *ops = dev->switchdev_ops;
- struct net_device *lower_dev;
- struct list_head *iter;
- struct switchdev_attr first = {
- .id = SWITCHDEV_ATTR_ID_UNDEFINED
- };
- int err = -EOPNOTSUPP;
+ int err;
+ int rc;
- if (ops && ops->switchdev_port_attr_get)
- return ops->switchdev_port_attr_get(dev, attr);
+ struct switchdev_notifier_port_attr_info attr_info = {
+ .attr = attr,
+ .trans = trans,
+ .handled = false,
+ };
- if (attr->flags & SWITCHDEV_F_NO_RECURSE)
+ rc = call_switchdev_blocking_notifiers(nt, dev, &attr_info.info, NULL);
+ err = notifier_to_errno(rc);
+ if (err) {
+ WARN_ON(!attr_info.handled);
return err;
-
- /* Switch device port(s) may be stacked under
- * bond/team/vlan dev, so recurse down to get attr on
- * each port. Return -ENODATA if attr values don't
- * compare across ports.
- */
-
- netdev_for_each_lower_dev(dev, lower_dev, iter) {
- err = switchdev_port_attr_get(lower_dev, attr);
- if (err)
- break;
- if (first.id == SWITCHDEV_ATTR_ID_UNDEFINED)
- first = *attr;
- else if (memcmp(&first, attr, sizeof(*attr)))
- return -ENODATA;
}
- return err;
-}
-EXPORT_SYMBOL_GPL(switchdev_port_attr_get);
-
-static int __switchdev_port_attr_set(struct net_device *dev,
- const struct switchdev_attr *attr,
- struct switchdev_trans *trans)
-{
- const struct switchdev_ops *ops = dev->switchdev_ops;
- struct net_device *lower_dev;
- struct list_head *iter;
- int err = -EOPNOTSUPP;
-
- if (ops && ops->switchdev_port_attr_set) {
- err = ops->switchdev_port_attr_set(dev, attr, trans);
- goto done;
- }
-
- if (attr->flags & SWITCHDEV_F_NO_RECURSE)
- goto done;
-
- /* Switch device port(s) may be stacked under
- * bond/team/vlan dev, so recurse down to set attr on
- * each port.
- */
-
- netdev_for_each_lower_dev(dev, lower_dev, iter) {
- err = __switchdev_port_attr_set(lower_dev, attr, trans);
- if (err)
- break;
- }
-
-done:
- if (err == -EOPNOTSUPP && attr->flags & SWITCHDEV_F_SKIP_EOPNOTSUPP)
- err = 0;
+ if (!attr_info.handled)
+ return -EOPNOTSUPP;
- return err;
+ return 0;
}
static int switchdev_port_attr_set_now(struct net_device *dev,
@@ -267,7 +217,8 @@ static int switchdev_port_attr_set_now(struct net_device *dev,
*/
trans.ph_prepare = true;
- err = __switchdev_port_attr_set(dev, attr, &trans);
+ err = switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET, dev, attr,
+ &trans);
if (err) {
/* Prepare phase failed: abort the transaction. Any
* resources reserved in the prepare phase are
@@ -286,7 +237,8 @@ static int switchdev_port_attr_set_now(struct net_device *dev,
*/
trans.ph_prepare = false;
- err = __switchdev_port_attr_set(dev, attr, &trans);
+ err = switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET, dev, attr,
+ &trans);
WARN(err, "%s: Commit of attribute (id=%d) failed.\n",
dev->name, attr->id);
switchdev_trans_items_warn_destroy(dev, &trans);
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 14/16] staging: fsl-dpaa2: ethsw: Handle SWITCHDEV_PORT_ATTR_SET
From: Florian Fainelli @ 2019-02-10 17:51 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare ethsw to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_SET and simply translate that into the existing
swdev_port_attr_set() call.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index b195b09e0d1d..8baa503d9a6a 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -1092,6 +1092,20 @@ ethsw_switchdev_port_obj_event(unsigned long event, struct net_device *netdev,
return notifier_from_errno(err);
}
+static int
+ethsw_switchdev_port_attr_set_event(unsigned long event,
+ struct net_device *netdev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int err;
+
+ err = swdev_port_attr_set(netdev, port_attr_info->attr,
+ port_attr_info->trans);
+
+ port_attr_info->handled = true;
+ return notifier_from_errno(err);
+}
+
static int port_switchdev_blocking_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -1104,6 +1118,8 @@ static int port_switchdev_blocking_event(struct notifier_block *unused,
case SWITCHDEV_PORT_OBJ_ADD: /* fall through */
case SWITCHDEV_PORT_OBJ_DEL:
return ethsw_switchdev_port_obj_event(event, dev, ptr);
+ case SWITCHDEV_PORT_ATTR_SET:
+ return ethsw_switchdev_port_attr_set_event(event, dev, ptr);
}
return NOTIFY_DONE;
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 12/16] mlxsw: spectrum_switchdev: Handle SWITCHDEV_PORT_ATTR_SET
From: Florian Fainelli @ 2019-02-10 17:51 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare mlxsw to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_SET and simply translate that into the existing
mlxsw_sp_port_attr_set() call.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
.../ethernet/mellanox/mlxsw/spectrum_switchdev.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 6b09d68671cf..39a99db040bd 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -3410,6 +3410,20 @@ mlxsw_sp_switchdev_handle_vxlan_obj_del(struct net_device *vxlan_dev,
}
}
+static int
+mlxsw_sp_switchdev_port_attr_set_event(unsigned long event,
+ struct net_device *dev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int err;
+
+ err = mlxsw_sp_port_attr_set(dev, port_attr_info->attr,
+ port_attr_info->trans);
+
+ port_attr_info->handled = true;
+ return notifier_from_errno(err);
+}
+
static int mlxsw_sp_switchdev_blocking_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -3433,6 +3447,8 @@ static int mlxsw_sp_switchdev_blocking_event(struct notifier_block *unused,
mlxsw_sp_port_dev_check,
mlxsw_sp_port_obj_del);
return notifier_from_errno(err);
+ case SWITCHDEV_PORT_ATTR_SET:
+ return mlxsw_sp_switchdev_port_attr_set_event(event, dev, ptr);
}
return NOTIFY_DONE;
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 16/16] net: Remove switchdev_ops
From: Florian Fainelli @ 2019-02-10 17:51 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
Now that we have converted all possible callers to using a switchdev
notifier for attributes we do not have a need for implementing
switchdev_ops anymore, and this can be removed from all drivers the
net_device structure.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 12 ------------
drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 2 --
.../mellanox/mlxsw/spectrum_switchdev.c | 12 ------------
drivers/net/ethernet/mscc/ocelot.c | 5 -----
drivers/net/ethernet/rocker/rocker_main.c | 5 -----
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 5 -----
include/linux/netdevice.h | 3 ---
include/net/switchdev.h | 18 ------------------
net/dsa/slave.c | 5 -----
9 files changed, 67 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 7c9745cecbbd..619965abab43 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3220,7 +3220,6 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
}
mlxsw_sp_port->default_vlan = mlxsw_sp_port_vlan;
- mlxsw_sp_port_switchdev_init(mlxsw_sp_port);
mlxsw_sp->ports[local_port] = mlxsw_sp_port;
err = register_netdev(dev);
if (err) {
@@ -3237,7 +3236,6 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
err_register_netdev:
mlxsw_sp->ports[local_port] = NULL;
- mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
mlxsw_sp_port_vlan_destroy(mlxsw_sp_port_vlan);
err_port_vlan_create:
err_port_pvid_set:
@@ -3280,7 +3278,6 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
mlxsw_core_port_clear(mlxsw_sp->core, local_port, mlxsw_sp);
unregister_netdev(mlxsw_sp_port->dev); /* This calls ndo_stop */
mlxsw_sp->ports[local_port] = NULL;
- mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
mlxsw_sp_port_vlan_flush(mlxsw_sp_port, true);
mlxsw_sp_port_nve_fini(mlxsw_sp_port);
mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port);
@@ -4001,12 +3998,6 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
goto err_span_init;
}
- err = mlxsw_sp_switchdev_init(mlxsw_sp);
- if (err) {
- dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize switchdev\n");
- goto err_switchdev_init;
- }
-
err = mlxsw_sp_counter_pool_init(mlxsw_sp);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to init counter pool\n");
@@ -4077,8 +4068,6 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
err_afa_init:
mlxsw_sp_counter_pool_fini(mlxsw_sp);
err_counter_pool_init:
- mlxsw_sp_switchdev_fini(mlxsw_sp);
-err_switchdev_init:
mlxsw_sp_span_fini(mlxsw_sp);
err_span_init:
mlxsw_sp_lag_fini(mlxsw_sp);
@@ -4141,7 +4130,6 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
mlxsw_sp_nve_fini(mlxsw_sp);
mlxsw_sp_afa_fini(mlxsw_sp);
mlxsw_sp_counter_pool_fini(mlxsw_sp);
- mlxsw_sp_switchdev_fini(mlxsw_sp);
mlxsw_sp_span_fini(mlxsw_sp);
mlxsw_sp_lag_fini(mlxsw_sp);
mlxsw_sp_buffers_fini(mlxsw_sp);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index ceebc91f4f1d..82e3e6dc81a1 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -375,8 +375,6 @@ u32 mlxsw_sp_bytes_cells(const struct mlxsw_sp *mlxsw_sp, u32 bytes);
/* spectrum_switchdev.c */
int mlxsw_sp_switchdev_init(struct mlxsw_sp *mlxsw_sp);
void mlxsw_sp_switchdev_fini(struct mlxsw_sp *mlxsw_sp);
-void mlxsw_sp_port_switchdev_init(struct mlxsw_sp_port *mlxsw_sp_port);
-void mlxsw_sp_port_switchdev_fini(struct mlxsw_sp_port *mlxsw_sp_port);
int mlxsw_sp_rif_fdb_op(struct mlxsw_sp *mlxsw_sp, const char *mac, u16 fid,
bool adding);
void
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 39a99db040bd..a3a3c14c7886 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -1925,10 +1925,6 @@ static struct mlxsw_sp_port *mlxsw_sp_lag_rep_port(struct mlxsw_sp *mlxsw_sp,
return NULL;
}
-static const struct switchdev_ops mlxsw_sp_port_switchdev_ops = {
- .switchdev_port_attr_set = mlxsw_sp_port_attr_set,
-};
-
static int
mlxsw_sp_bridge_8021q_port_join(struct mlxsw_sp_bridge_device *bridge_device,
struct mlxsw_sp_bridge_port *bridge_port,
@@ -3536,11 +3532,3 @@ void mlxsw_sp_switchdev_fini(struct mlxsw_sp *mlxsw_sp)
kfree(mlxsw_sp->bridge);
}
-void mlxsw_sp_port_switchdev_init(struct mlxsw_sp_port *mlxsw_sp_port)
-{
- mlxsw_sp_port->dev->switchdev_ops = &mlxsw_sp_port_switchdev_ops;
-}
-
-void mlxsw_sp_port_switchdev_fini(struct mlxsw_sp_port *mlxsw_sp_port)
-{
-}
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 1dda4dd4c073..c98d2df08968 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1324,10 +1324,6 @@ static int ocelot_port_obj_del(struct net_device *dev,
return ret;
}
-static const struct switchdev_ops ocelot_port_switchdev_ops = {
- .switchdev_port_attr_set = ocelot_port_attr_set,
-};
-
static int ocelot_port_bridge_join(struct ocelot_port *ocelot_port,
struct net_device *bridge)
{
@@ -1649,7 +1645,6 @@ int ocelot_probe_port(struct ocelot *ocelot, u8 port,
dev->netdev_ops = &ocelot_port_netdev_ops;
dev->ethtool_ops = &ocelot_ethtool_ops;
- dev->switchdev_ops = &ocelot_port_switchdev_ops;
dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXFCS;
dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index b94f940dc7b5..262f6dd173f6 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2124,10 +2124,6 @@ static int rocker_port_obj_del(struct net_device *dev,
return err;
}
-static const struct switchdev_ops rocker_port_switchdev_ops = {
- .switchdev_port_attr_set = rocker_port_attr_set,
-};
-
struct rocker_fib_event_work {
struct work_struct work;
union {
@@ -2581,7 +2577,6 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
rocker_port_dev_addr_init(rocker_port);
dev->netdev_ops = &rocker_port_netdev_ops;
dev->ethtool_ops = &rocker_port_ethtool_ops;
- dev->switchdev_ops = &rocker_port_switchdev_ops;
netif_tx_napi_add(dev, &rocker_port->napi_tx, rocker_port_poll_tx,
NAPI_POLL_WEIGHT);
netif_napi_add(dev, &rocker_port->napi_rx, rocker_port_poll_rx,
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 8baa503d9a6a..fe7d7617e800 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -914,10 +914,6 @@ static int swdev_port_obj_del(struct net_device *netdev,
return err;
}
-static const struct switchdev_ops ethsw_port_switchdev_ops = {
- .switchdev_port_attr_set = swdev_port_attr_set,
-};
-
/* For the moment, only flood setting needs to be updated */
static int port_bridge_join(struct net_device *netdev,
struct net_device *upper_dev)
@@ -1439,7 +1435,6 @@ static int ethsw_probe_port(struct ethsw_core *ethsw, u16 port_idx)
SET_NETDEV_DEV(port_netdev, dev);
port_netdev->netdev_ops = ðsw_port_ops;
port_netdev->ethtool_ops = ðsw_port_ethtool_ops;
- port_netdev->switchdev_ops = ðsw_port_switchdev_ops;
/* Set MTU limits */
port_netdev->min_mtu = ETH_MIN_MTU;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 1fb733f38a47..a747456b9d23 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1836,9 +1836,6 @@ struct net_device {
#endif
const struct net_device_ops *netdev_ops;
const struct ethtool_ops *ethtool_ops;
-#ifdef CONFIG_NET_SWITCHDEV
- const struct switchdev_ops *switchdev_ops;
-#endif
#ifdef CONFIG_NET_L3_MASTER_DEV
const struct l3mdev_ops *l3mdev_ops;
#endif
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 7bc6a004d32a..e66a6c30eee6 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -111,21 +111,6 @@ void *switchdev_trans_item_dequeue(struct switchdev_trans *trans);
typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj);
-/**
- * struct switchdev_ops - switchdev operations
- *
- * @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
- *
- * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
- */
-struct switchdev_ops {
- int (*switchdev_port_attr_get)(struct net_device *dev,
- struct switchdev_attr *attr);
- int (*switchdev_port_attr_set)(struct net_device *dev,
- const struct switchdev_attr *attr,
- struct switchdev_trans *trans);
-};
-
enum switchdev_notifier_type {
SWITCHDEV_FDB_ADD_TO_BRIDGE = 1,
SWITCHDEV_FDB_DEL_TO_BRIDGE,
@@ -223,7 +208,6 @@ int switchdev_handle_port_obj_del(struct net_device *dev,
int (*del_cb)(struct net_device *dev,
const struct switchdev_obj *obj));
-#define SWITCHDEV_SET_OPS(netdev, ops) ((netdev)->switchdev_ops = (ops))
#else
static inline void switchdev_deferred_process(void)
@@ -310,8 +294,6 @@ switchdev_handle_port_obj_del(struct net_device *dev,
return 0;
}
-#define SWITCHDEV_SET_OPS(netdev, ops) do {} while (0)
-
#endif
#endif /* _LINUX_SWITCHDEV_H_ */
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index ee4b94c5e68e..871ab04d5f05 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1047,10 +1047,6 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
.ndo_get_port_parent_id = dsa_slave_get_port_parent_id,
};
-static const struct switchdev_ops dsa_slave_switchdev_ops = {
- .switchdev_port_attr_set = dsa_slave_port_attr_set,
-};
-
static struct device_type dsa_type = {
.name = "dsa",
};
@@ -1310,7 +1306,6 @@ int dsa_slave_create(struct dsa_port *port)
eth_hw_addr_inherit(slave_dev, master);
slave_dev->priv_flags |= IFF_NO_QUEUE;
slave_dev->netdev_ops = &dsa_slave_netdev_ops;
- slave_dev->switchdev_ops = &dsa_slave_switchdev_ops;
slave_dev->min_mtu = 0;
slave_dev->max_mtu = ETH_MAX_MTU;
SET_NETDEV_DEVTYPE(slave_dev, &dsa_type);
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 05/16] rocker: Check bridge flags during prepare phase
From: Florian Fainelli @ 2019-02-10 17:50 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
In preparation for getting rid of switchdev_port_attr_get(), have rocker
check for the bridge flags being set through switchdev_port_attr_set()
with the SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS attribute identifier.
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/rocker/rocker_main.c | 40 ++++++++++++++---------
1 file changed, 25 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index 66f72f8c46e5..8657313b6f30 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -1565,18 +1565,42 @@ static int rocker_world_port_attr_stp_state_set(struct rocker_port *rocker_port,
return wops->port_attr_stp_state_set(rocker_port, state);
}
+static int
+rocker_world_port_attr_bridge_flags_support_get(const struct rocker_port *
+ rocker_port,
+ unsigned long *
+ p_brport_flags_support)
+{
+ struct rocker_world_ops *wops = rocker_port->rocker->wops;
+
+ if (!wops->port_attr_bridge_flags_support_get)
+ return -EOPNOTSUPP;
+ return wops->port_attr_bridge_flags_support_get(rocker_port,
+ p_brport_flags_support);
+}
+
static int
rocker_world_port_attr_bridge_flags_set(struct rocker_port *rocker_port,
unsigned long brport_flags,
struct switchdev_trans *trans)
{
struct rocker_world_ops *wops = rocker_port->rocker->wops;
+ unsigned long brport_flags_s;
+ int err;
if (!wops->port_attr_bridge_flags_set)
return -EOPNOTSUPP;
- if (switchdev_trans_ph_prepare(trans))
+ if (switchdev_trans_ph_prepare(trans)) {
+ err = rocker_world_port_attr_bridge_flags_support_get(rocker_port,
+ &brport_flags_s);
+ if (err)
+ return err;
+
+ if (brport_flags & ~brport_flags_s)
+ return -EOPNOTSUPP;
return 0;
+ }
return wops->port_attr_bridge_flags_set(rocker_port, brport_flags,
trans);
@@ -1593,20 +1617,6 @@ rocker_world_port_attr_bridge_flags_get(const struct rocker_port *rocker_port,
return wops->port_attr_bridge_flags_get(rocker_port, p_brport_flags);
}
-static int
-rocker_world_port_attr_bridge_flags_support_get(const struct rocker_port *
- rocker_port,
- unsigned long *
- p_brport_flags_support)
-{
- struct rocker_world_ops *wops = rocker_port->rocker->wops;
-
- if (!wops->port_attr_bridge_flags_support_get)
- return -EOPNOTSUPP;
- return wops->port_attr_bridge_flags_support_get(rocker_port,
- p_brport_flags_support);
-}
-
static int
rocker_world_port_attr_bridge_ageing_time_set(struct rocker_port *rocker_port,
u32 ageing_time,
--
2.19.1
^ permalink raw reply related
* [PATCH net-next v2 03/16] staging: fsl-dpaa2: ethsw: Check bridge port flags during set
From: Florian Fainelli @ 2019-02-10 17:50 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, idosch, linux-kernel, devel, bridge, jiri,
andrew, vivien.didelot
In-Reply-To: <20190210175105.31629-1-f.fainelli@gmail.com>
In preparation for removing SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT,
have ethsw check that the bridge port flags that are being set are
supported.
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index e559f4c25cf7..6228c4375835 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -680,8 +680,11 @@ static int port_attr_br_flags_set(struct net_device *netdev,
struct ethsw_port_priv *port_priv = netdev_priv(netdev);
int err = 0;
- if (switchdev_trans_ph_prepare(trans))
+ if (switchdev_trans_ph_prepare(trans)) {
+ if (flags & ~(BR_LEARNING | BR_FLOOD))
+ return -EOPNOTSUPP;
return 0;
+ }
/* Learning is enabled per switch */
err = ethsw_set_learning(port_priv->ethsw_data, flags & BR_LEARNING);
--
2.19.1
^ permalink raw reply related
* Re: [PATCH v1 net-next 0/2] Change tc action identifiers to be more consistent
From: David Miller @ 2019-02-10 17:29 UTC (permalink / raw)
To: eli; +Cc: jhs, xiyou.wangcong, jiri, netdev, simon.horman
In-Reply-To: <20190210122500.13614-1-eli@mellanox.com>
From: Eli Cohen <eli@mellanox.com>
Date: Sun, 10 Feb 2019 14:24:58 +0200
> This two patch series modifies TC actions identifiers to be more consistent and
> also puts them in one place so new identifiers numbers can be chosen more
> easily.
>
> Eli Cohen (2):
> net: Move all TC actions identifiers to one place
> net: Change TCA_ACT_* to TCA_ID_* to match that of TCA_ID_POLICE
>
> Changelog:
> v0 -> v1:
> Remove definition of TCA_ACT_SIMP from net/sched/act_simple.c to avoid two
> identical definitions.
Series applied, thanks.
^ permalink raw reply
* Re: tc qdisc kernel crash
From: Ben Hutchings @ 2019-02-10 15:51 UTC (permalink / raw)
To: netdev; +Cc: 921542, Adrian
In-Reply-To: <154947154317.4485.11268926035712969198.reportbug@Telenet-PC>
[-- Attachment #1: Type: text/plain, Size: 4491 bytes --]
Control: tag -1 confirmed upstream
Control: found -1 4.20-1~exp1
Adrian (cc'd) reported (https://bugs.debian.org/921542) that a script
using tc could trigger a kernel crash. I've simplified the script he
provided down to:
--- BEGIN ---
#!/bin/sh -ex
modprobe ifb
while true; do
tc qdisc add dev ifb0 root handle 2:0 prio bands 5
tc qdisc add dev ifb0 parent 2:5 sfq
tc filter add dev ifb0 parent 2:0 protocol ip prio 5 handle 0 tcindex mask 0 classid 2:5 pass_on
tc qdisc del dev ifb0 root || true
done
--- END ---
The crash is still reproducible in 4.20 and 5.0-rc5. KASan shows a
use-after-free:
+ modprobe ifb
+ true
+ tc qdisc add dev ifb0 root handle 2:0 prio bands 5
+ tc qdisc add dev ifb0 parent 2:5 sfq
+ tc filter add dev ifb0 parent 2:0 protocol ip prio 5 handle 0 tcindex mask 0 classid 2:5 pass_on
+ tc qdisc del dev ifb0 root
+ true
+ tc qdisc add dev ifb0 root handle 2:0 prio bands 5
[ 63.926983] ==================================================================
[ 63.929429] BUG: KASAN: use-after-free in worker_thread+0x327/0x5b0
[ 63.931489] Read of size 8 at addr ffff88804fd22130 by task kworker/u8:1/32
[ 63.933766]
[ 63.934397] CPU: 0 PID: 32 Comm: kworker/u8:1 Not tainted 5.0.0-rc5 #3
[ 63.936629] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
[ 63.939537] Workqueue: (null) (events_unbound)
[ 63.942039] Call Trace:
[ 63.943187] dump_stack+0x71/0xa0
[ 63.944386] ? worker_thread+0x327/0x5b0
[ 63.945881] print_address_description+0x65/0x22e
[ 63.947980] ? worker_thread+0x327/0x5b0
[ 63.949588] ? worker_thread+0x327/0x5b0
[ 63.951254] kasan_report.cold.3+0x1a/0x40
[ 63.953036] ? worker_thread+0x327/0x5b0
[ 63.954692] worker_thread+0x327/0x5b0
[ 63.956236] ? flush_rcu_work+0x40/0x40
[ 63.957722] kthread+0x1ae/0x1d0
[ 63.959067] ? __kthread_parkme+0x90/0x90
[ 63.960451] ret_from_fork+0x35/0x40
[ 63.962020]
[ 63.962817] Allocated by task 757:
[ 63.964465] __kasan_kmalloc.constprop.13+0xc1/0xd0
[ 63.966670] tcindex_alloc_perfect_hash+0x37/0x150 [cls_tcindex]
[ 63.969287] tcindex_set_parms+0xb38/0xd30 [cls_tcindex]
[ 63.972539] tcindex_change+0x13d/0x1c2 [cls_tcindex]
[ 63.974796] tc_new_tfilter+0x7ec/0xaf0
[ 63.976546] rtnetlink_rcv_msg+0x35c/0x490
[ 63.978302] netlink_rcv_skb+0xc6/0x1f0
[ 63.980050] netlink_unicast+0x309/0x3d0
[ 63.981990] netlink_sendmsg+0x37d/0x5e0
[ 63.983849] sock_sendmsg+0x6d/0x80
[ 63.985538] ___sys_sendmsg+0x46a/0x4e0
[ 63.987328] __sys_sendmsg+0xd3/0x160
[ 63.988974] do_syscall_64+0x73/0x140
[ 63.990616] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 63.992538]
[ 63.993430] Freed by task 9:
[ 63.994660] __kasan_slab_free+0x125/0x170
[ 63.996239] kfree+0x90/0x1d0
[ 63.997496] __tcindex_destroy+0x1f/0x40 [cls_tcindex]
[ 63.999316] rcu_process_callbacks+0x3cb/0x650
[ 64.000889] __do_softirq+0x115/0x3b4
[ 64.003254]
[ 64.004138] The buggy address belongs to the object at ffff88804fd22100
[ 64.004138] which belongs to the cache kmalloc-8k of size 8192
[ 64.009001] The buggy address is located 48 bytes inside of
[ 64.009001] 8192-byte region [ffff88804fd22100, ffff88804fd24100)
[ 64.013752] The buggy address belongs to the page:
[ 64.015906] page:ffffea00013f4800 count:1 mapcount:0 mapping:ffff888051002700 index:0x0 compound_mapcount: 0
[ 64.020237] flags: 0xffffc000010200(slab|head)
[ 64.022176] raw: 00ffffc000010200 dead000000000100 dead000000000200 ffff888051002700
[ 64.025247] raw: 0000000000000000 0000000080030003 00000001ffffffff 0000000000000000
[ 64.028847] page dumped because: kasan: bad access detected
[ 64.031367]
[ 64.033285] Memory state around the buggy address:
[ 64.035276] ffff88804fd22000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 64.037741] ffff88804fd22080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 64.040138] >ffff88804fd22100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 64.042717] ^
[ 64.044794] ffff88804fd22180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 64.047431] ffff88804fd22200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 64.049993] ==================================================================
Ben.
--
Ben Hutchings
The world is coming to an end. Please log off.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: Linux 5.0 regression: rtl8169 / kernel BUG at lib/dynamic_queue_limits.c:27!
From: Sander Eikelenboom @ 2019-02-10 15:50 UTC (permalink / raw)
To: Heiner Kallweit, Eric Dumazet, Realtek linux nic maintainers,
Eric Dumazet
Cc: Linus Torvalds, linux-kernel, netdev
In-Reply-To: <6307e338-c2b6-ea87-ce56-2eb9606d3bfa@gmail.com>
On 10/02/2019 12:44, Heiner Kallweit wrote:
> On 10.02.2019 10:16, Sander Eikelenboom wrote:
>> On 09/02/2019 12:50, Heiner Kallweit wrote:
>>> On 09.02.2019 11:07, Sander Eikelenboom wrote:
>>>> On 09/02/2019 10:59, Heiner Kallweit wrote:
>>>>> On 09.02.2019 10:34, Sander Eikelenboom wrote:
>>>>>> On 09/02/2019 10:02, Heiner Kallweit wrote:
>>>>>>> On 09.02.2019 00:09, Eric Dumazet wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 02/08/2019 01:50 PM, Heiner Kallweit wrote:
>>>>>>>>> On 08.02.2019 22:45, Sander Eikelenboom wrote:
>>>>>>>>>> On 08/02/2019 22:22, Heiner Kallweit wrote:
>>>>>>>>>>> On 08.02.2019 21:55, Sander Eikelenboom wrote:
>>>>>>>>>>>> On 08/02/2019 19:52, Heiner Kallweit wrote:
>>>>>>>>>>>>> On 08.02.2019 19:29, Sander Eikelenboom wrote:
>>>>>>>>>>>>>> L.S.,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> While testing a linux 5.0-rc5 kernel (with some patches on top but they don't seem related) under Xen i the nasty splat below,
>>>>>>>>>>>>>> that I haven encountered with Linux 4.20.x.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Unfortunately I haven't got a clear reproducer for this and bisecting could be nasty due to another (networking related) kernel bug.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> If you need more info, want me to run a debug patch etc., please feel free to ask.
>>>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks for the report. However I see no change in the r8169 driver between
>>>>>>>>>>>>> 4.20 and 5.0 with regard to BQL code. Having said that the root cause could
>>>>>>>>>>>>> be somewhere else. Therefore I'm afraid a bisect will be needed.
>>>>>>>>>>>>
>>>>>>>>>>>> Hmm i did some diging and i think:
>>>>>>>>>>>> bd7153bd83b806bfcc2e79b7a6f43aa653d06ef3 r8169: remove unneeded mmiowb barriers
>>>>>>>>>>>> 2e6eedb4813e34d8d84ac0eb3afb668966f3f356 r8169: make use of xmit_more and __netdev_sent_queue
>>>>>>>>>>>> 620344c43edfa020bbadfd81a144ebe5181fc94f net: core: add __netdev_sent_queue as variant of __netdev_tx_sent_queue
>>>>>>>>>>>>
>>>>>>>>>>> You're right. Thought this was added in 4.20 already.
>>>>>>>>>>> The BQL code pattern I copied from the mlx4 driver and so far I haven't heard about
>>>>>>>>>>> this issue from any user of physical hw. And due to the fact that a lot of mainboards
>>>>>>>>>>> have onboard Realtek network I have quite a few testers out there.
>>>>>>>>>>> Does the issue occur under specific circumstances like very high load?
>>>>>>>>>>
>>>>>>>>>> Yep, the box is already quite contented with the Xen VM's and if I remember correctly it occurred while kernel compiling
>>>>>>>>>> on the host.
>>>>>>>>>>
>>>>>>>>>>> If indeed the xmit_more patch causes the issue, I think we have to involve Eric Dumazet
>>>>>>>>>>> as author of the underlying changes.
>>>>>>>>>>
>>>>>>>>>> It could also be the barriers weren't that unneeded as assumed.
>>>>>>>>>
>>>>>>>>> The barriers were removed after adding xmit_more handling. Therefore it would be good to
>>>>>>>>> test also with only
>>>>>>>>> bd7153bd83b806bfcc2e79b7a6f43aa653d06ef3 r8169: remove unneeded mmiowb barriers
>>>>>>>>> removed.
>>>>>>>>>
>>>>>>>>>> Since we are almost at RC6 i took the liberty to CC Eric now.
>>>>>>>>>>
>>>>>>>>> Sure, thanks.
>>>>>>>>>
>>>>>>>>>> BTW am i correct these patches are merely optimizations ?
>>>>>>>>>
>>>>>>>>> Yes
>>>>>>>>>
>>>>>>>>>> If so and concluding they revert cleanly, perhaps it should be considered at this point in the RC's
>>>>>>>>>> to revert them for 5.0 and try again for 5.1 ?
>>>>>>>>>>
>>>>>>>>> Before removing both it would be good to test with only the barrier-removal removed.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Commit 2e6eedb4813e34d8d84ac0eb3afb668966f3f356 r8169: make use of xmit_more and __netdev_sent_queue
>>>>>>>> looks buggy to me, since the skb might have been freed already on another cpu when you call
>>>>>>>>
>>>>>>>> You could try :
>>>>>>>>
>>>>>>>> diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
>>>>>>>> index 3624e67aef72c92ed6e908e2c99ac2d381210126..f907d484165d9fd775e81bf2bfb9aa4ddedb1c93 100644
>>>>>>>> --- a/drivers/net/ethernet/realtek/r8169.c
>>>>>>>> +++ b/drivers/net/ethernet/realtek/r8169.c
>>>>>>>> @@ -6070,6 +6070,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
>>>>>>>> dma_addr_t mapping;
>>>>>>>> u32 opts[2], len;
>>>>>>>> bool stop_queue;
>>>>>>>> + bool door_bell;
>>>>>>>> int frags;
>>>>>>>>
>>>>>>>> if (unlikely(!rtl_tx_slots_avail(tp, skb_shinfo(skb)->nr_frags))) {
>>>>>>>> @@ -6116,6 +6117,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
>>>>>>>> /* Force memory writes to complete before releasing descriptor */
>>>>>>>> dma_wmb();
>>>>>>>>
>>>>>>>> + door_bell = __netdev_sent_queue(dev, skb->len, skb->xmit_more);
>>>>>>>> +
>>>>>>>> txd->opts1 = rtl8169_get_txd_opts1(opts[0], len, entry);
>>>>>>>>
>>>>>>>> /* Force all memory writes to complete before notifying device */
>>>>>>>> @@ -6127,7 +6130,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
>>>>>>>> if (unlikely(stop_queue))
>>>>>>>> netif_stop_queue(dev);
>>>>>>>>
>>>>>>>> - if (__netdev_sent_queue(dev, skb->len, skb->xmit_more)) {
>>>>>>>> + if (door_bell) {
>>>>>>>> RTL_W8(tp, TxPoll, NPQ);
>>>>>>>> mmiowb();
>>>>>>>> }
>>>>>>>>
>>>>>>> Thanks a lot for checking and for the proposed fix.
>>>>>>> Sander, can you try with this patch on top of 5.0-rc5 w/o removing two two commits?
>>>>>>
>>>>>> I have done that already during the night .. the results:
>>>>>> - I can confirm 2e6eedb4813e34d8d84ac0eb3afb668966f3f356 is the first commit which causes hitting the BUG_ON in lib/dynamic_queue_limits.c.
>>>>>> (in other word, with only reverting bd7153bd83b806bfcc2e79b7a6f43aa653d06ef3 it still blows up).
>>>>>>
>>>>>> - The Eric's patch only applies cleanly with bd7153bd83b806bfcc2e79b7a6f43aa653d06ef3 reverted, so that's what I tested.
>>>>>> The patch seems to prevent hitting the BUG_ON in lib/dynamic_queue_limits.c, it has run this night and I gave done a few kernel compiles
>>>>>> this morning. How ever during these kernel compiles i'm getting a transmit queue timeout which i haven't seen with 4.20.x, although i regularly
>>>>>> compile kernels in the same way as I do now. The only thing I can't say if that is due to this change, or if it's again something else.
>>>>>> Which makes me somewhat inclined to go testing the complete revert some more and see if I can trigger the queue timeout on that or not.
>>>>>>
>>>>>> If I can, it is a separate issue.
>>>>>> If I can't it seems even with a patch it still seems as a regression in comparison with 4.20.x, for which
>>>>>> a revert would be the right thing to do (since as you indicated these are merely optimizations),
>>>>>> which would give us more time for 5.1 to try to solve things on top of the 5.0-release-to-be.
>>>>>> (especially since I seem to still have other issues which need to be sorted out and time is limited)
>>>>>>
>>>>>> The timeout in question:
>>>>>> [28336.869479] NETDEV WATCHDOG: eth1 (r8169): transmit queue 0 timed out
>>>>>> [28336.881498] WARNING: CPU: 0 PID: 6925 at net/sched/sch_generic.c:461 dev_watchdog+0x20b/0x210
>>>>>> [28336.893358] Modules linked in:
>>>>>> [28336.904106] CPU: 0 PID: 6925 Comm: cc1 Tainted: G D 5.0.0-rc5-20190208-thp-net-florian-rtl8169-eric-doflr+ #1
>>>>>> [28336.917385] Hardware name: MSI MS-7640/890FXA-GD70 (MS-7640) , BIOS V1.8B1 09/13/2010
>>>>>> [28336.928988] RIP: e030:dev_watchdog+0x20b/0x210
>>>>>> [28336.940623] Code: 00 49 63 4e e0 eb 90 4c 89 e7 c6 05 ad d8 f1 00 01 e8 a9 32 fd ff 89 d9 48 89 c2 4c 89 e6 48 c7 c7 50 59 89 82 e8 e5 92 4d ff <0f> 0b eb c0 90 48 c7 47 08 00 00 00 00 48 c7 07 00 00 00 00 0f b7
>>>>>> [28336.965265] RSP: e02b:ffff88807d403ea0 EFLAGS: 00010286
>>>>>> [28336.977465] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff82a69db8
>>>>>> [28336.991265] RDX: 0000000000000001 RSI: 0000000000000001 RDI: 0000000000000200
>>>>>> [28337.008865] RBP: ffff88807936e41c R08: 0000000000000000 R09: 0000000000000819
>>>>>> [28337.022250] R10: 0000000000000202 R11: ffffffff8247ca80 R12: ffff88807936e000
>>>>>> [28337.035204] R13: 0000000000000000 R14: ffff88807936e440 R15: 0000000000000001
>>>>>> [28337.049832] FS: 00007f53e9bf3840(0000) GS:ffff88807d400000(0000) knlGS:0000000000000000
>>>>>> [28337.062524] CS: e030 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>> [28337.075086] CR2: 00007f53e60c4000 CR3: 000000001a0be000 CR4: 0000000000000660
>>>>>> [28337.090052] Call Trace:
>>>>>> [28337.103615] <IRQ>
>>>>>> [28337.116587] ? qdisc_destroy+0x120/0x120
>>>>>> [28337.128905] call_timer_fn+0x19/0x90
>>>>>> [28337.141892] expire_timers+0x8b/0xa0
>>>>>> [28337.153354] run_timer_softirq+0x7e/0x160
>>>>>> [28337.165931] ? handle_irq_event_percpu+0x4c/0x70
>>>>>> [28337.176548] ? handle_percpu_irq+0x32/0x50
>>>>>> [28337.186734] __do_softirq+0xed/0x229
>>>>>> [28337.196404] ? hypervisor_callback+0xa/0x20
>>>>>> [28337.207822] irq_exit+0xb7/0xc0
>>>>>> [28337.218978] xen_evtchn_do_upcall+0x27/0x40
>>>>>> [28337.230763] xen_do_hypervisor_callback+0x29/0x40
>>>>>> [28337.241261] </IRQ>
>>>>>> [28337.253283] RIP: e033:0xff7e62
>>>>>> [28337.264899] Code: 35 43 0f c7 00 4c 89 ef e8 8b 6d 67 ff 0f 1f 00 44 89 e0 44 89 e2 c1 e8 06 83 e2 3f 48 8b 0c c5 40 8d c6 01 48 0f a3 d1 72 0e <48> 8b 04 c5 50 8d c6 01 48 0f a3 d0 73 0b 44 89 e6 4c 89 ef e8 b5
>>>>>> [28337.288677] RSP: e02b:00007fff0fc6a340 EFLAGS: 00000202
>>>>>> [28337.299234] RAX: 0000000000000000 RBX: 00007f53e60c3580 RCX: 0000000000000000
>>>>>> [28337.309577] RDX: 0000000000000034 RSI: 0000000001e71a98 RDI: 00007fff0fc6a538
>>>>>> [28337.320724] RBP: 00007fff0fc6a4b0 R08: 0000000000000000 R09: 0000000000000000
>>>>>> [28337.331829] R10: 0000000000000001 R11: 00000000020cb3d0 R12: 0000000000000034
>>>>>> [28337.343900] R13: 00007fff0fc6a538 R14: 0000000000000000 R15: 0000000000000001
>>>>>> [28337.353977] ---[ end trace 6ff49f09286816b7 ]---
>>>>>>
>>>>> Thanks for your efforts. As usual this tx timeout trace says basically nothing except
>>>>> "timeout" and root cause could be anything. Earlier you reported a memory allocation error,
>>>>> did that occur again?
>>>>> If we decide to revert, I'd leave removal of the memory barriers in (as it doesn't seem to
>>>>> contribute to the issue) and just submit a patch to effectively revert
>>>>> 2e6eedb4813e34d8d84ac0eb3afb668966f3f356.
>>>>
>>>> I can't say if that is correct, because i haven't tested that.
>>>>
>>>> Another thing I could test is:
>>>> - putting all the r8169 patches (and prerequisites) that went into 5.0
>>>> up to bd7153bd83b806bfcc2e79b7a6f43aa653d06ef3, onto 4.20.7 and see what that does.
>>>> If that would be feasible (not too many needed prerequisites out of r8169) and if
>>>> you could spare me some time and prep such a branch somewhere so i can pull and compile that,
>>>> that would be great.
>>>>
>>>
>>> Unfortunately there's quite a number of changes. Regarding __netdev_tx_sent_queue()
>>> and watchdog timeout I found the following comment in drivers/net/ethernet/sfc/tx.c,
>>> efx_enqueue_skb():
>>>
>>> if (__netdev_tx_sent_queue(tx_queue->core_txq, skb_len, xmit_more)) {
>>> struct efx_tx_queue *txq2 = efx_tx_queue_partner(tx_queue);
>>>
>>> /* There could be packets left on the partner queue if those
>>> * SKBs had skb->xmit_more set. If we do not push those they
>>> * could be left for a long time and cause a netdev watchdog.
>>> */
>>> if (txq2->xmit_more_available)
>>> efx_nic_push_buffers(txq2);
>>>
>>> But I'm not sure whether the situation in r8169 is comparable. The following patch
>>> implements what I mentioned earlier: It leaves all other 5.0 changes in place and
>>> effectively reverts 2e6eedb4813e34d8d84ac0eb3afb668966f3f356. Would be great if
>>> you could give it a try.
>>
>> Hi Heiner,
>>
>> It took some time to respond, because I had another issue with 5.0 which intervened with proper testing,
>> but fortunately I could pinpoint without doing a full bisect and revert that commit for further testing.
>>
>> So there is still time left and I could do a more proper run with your patch below.
>> Unfortunately i still get a splat (see below) with this, although i'm not sure it is related,
>> just that I can't tell.
>>
> I checked further and there's a handful of network drivers using __napi_alloc_skb() with __GFP_NOWARN,
> maybe to avoid such splats. Did the splat impact functionality? When checking the code in r8169 the
> affected packet would just be dropped.
Hmm a __GFP_NOWARN will merely hide it.
But i took a good look with some more testing and it seems to occur when
during kernel compile the system has to use a little bit of swap.
So it's probably not a problem with r8169 code.
--
Sander
>> Perhaps Linus as Oops-decoding-guru has an idea ?
>>
>> --
>> Sander
>>
>> [39041.689007] dpkg-deb: page allocation failure: order:0, mode:0x480020(GFP_ATOMIC), nodemask=(null),cpuset=/,mems_allowed=0
>> [39041.689016] CPU: 4 PID: 14078 Comm: dpkg-deb Not tainted 5.0.0-rc5-20190209-kallweit+ #1
>> [39041.689017] Hardware name: MSI MS-7640/890FXA-GD70 (MS-7640) , BIOS V1.8B1 09/13/2010
>> [39041.689018] Call Trace:
>> [39041.689022] <IRQ>
>> [39041.689030] dump_stack+0x5c/0x7b
>> [39041.689033] warn_alloc+0x103/0x190
>> [39041.689036] __alloc_pages_nodemask+0xe3d/0xe80
>> [39041.689039] ? ip_rcv+0x48/0xc0
>> [39041.689040] ? ip_rcv_finish_core.isra.0+0x360/0x360
>> [39041.689042] page_frag_alloc+0x117/0x150
>> [39041.689044] __napi_alloc_skb+0x83/0xd0
>> [39041.689048] rtl8169_poll+0x210/0x640
>> [39041.689051] net_rx_action+0x23d/0x370
>> [39041.689054] __do_softirq+0xed/0x229
>> [39041.689058] irq_exit+0xb7/0xc0
>> [39041.689061] xen_evtchn_do_upcall+0x27/0x40
>> [39041.689063] xen_do_hypervisor_callback+0x29/0x40
>> [39041.689064] </IRQ>
>> [39041.689066] RIP: e030:_atomic_dec_and_lock+0x2/0x40
>> [39041.689068] Code: ff 39 05 c5 c1 c9 00 89 c7 89 c6 76 0f 83 eb 01 83 fb ff 75 d9 5b 89 f8 5d 41 5c c3 0f 0b 90 90 90 90 90 90 90 90 90 90 8b 07 <83> f8 01 74 0c 8d 50 ff f0 0f b1 17 75 f2 31 c0 c3 55 53 48 89 fb
>> [39041.689069] RSP: e02b:ffffc9000705b990 EFLAGS: 00000246
>> [39041.689071] RAX: 0000000000000001 RBX: ffff888017082640 RCX: 0000000000000000
>> [39041.689071] RDX: 0000000000000000 RSI: ffff8880170826c0 RDI: ffff888017082788
>> [39041.689072] RBP: ffff8880170826c0 R08: ffffc9000705bb00 R09: ffffc9000705bb00
>> [39041.689073] R10: ffffc9000705bb58 R11: ffff88807fc17000 R12: ffff888017082788
>> [39041.689073] R13: ffff88806cc8cf58 R14: ffff888017082640 R15: ffff888009990240
>> [39041.689077] iput+0x63/0x1a0
>> [39041.689079] __dentry_kill+0xc5/0x170
>> [39041.689080] shrink_dentry_list+0x93/0x1c0
>> [39041.689082] prune_dcache_sb+0x4d/0x70
>> [39041.689084] super_cache_scan+0x104/0x190
>> [39041.689087] do_shrink_slab+0x12c/0x1e0
>> [39041.689089] shrink_slab+0xdf/0x2b0
>> [39041.689091] shrink_node+0x158/0x470
>> [39041.689093] do_try_to_free_pages+0xd1/0x380
>> [39041.689095] try_to_free_pages+0xb2/0xe0
>> [39041.689097] __alloc_pages_nodemask+0x603/0xe80
>> [39041.689099] ? __pagevec_lru_add_fn+0x1b1/0x290
>> [39041.689102] alloc_pages_vma+0x7b/0x1c0
>> [39041.689106] __handle_mm_fault+0xdb3/0x1060
>> [39041.689109] ? xen_mc_flush+0xc0/0x190
>> [39041.689110] handle_mm_fault+0xf8/0x200
>> [39041.689113] __do_page_fault+0x231/0x4a0
>> [39041.689115] ? page_fault+0x8/0x30
>> [39041.689116] page_fault+0x1e/0x30
>> [39041.689118] RIP: e033:0x7fb9851d012e
>> [39041.689119] Code: 29 c2 48 3b 15 7b a3 31 00 0f 87 af 00 00 00 0f 10 01 0f 10 49 f0 0f 10 51 e0 0f 10 59 d0 48 83 e9 40 48 83 ea 40 41 0f 29 01 <41> 0f 29 49 f0 41 0f 29 51 e0 41 0f 29 59 d0 49 83 e9 40 48 83 fa
>> [39041.689119] RSP: e02b:00007fb958b36d38 EFLAGS: 00010202
>> [39041.689120] RAX: 00007fb97a617f0e RBX: 000000000000f004 RCX: 00007fb948008be3
>> [39041.689121] RDX: 00000000000080c2 RSI: 00007fb948000b31 RDI: 00007fb97a617f0e
>> [39041.689122] RBP: 00000000000ff062 R08: 0000000000000002 R09: 00007fb97a620000
>> [39041.689123] R10: 0000000000000004 R11: 00007fb97a626f02 R12: 000000000000f005
>> [39041.689123] R13: 00007fb948000b28 R14: 0000562d76b63710 R15: 0000000000000003
>> [39041.689125] Mem-Info:
>> [39041.689130] active_anon:78775 inactive_anon:49211 isolated_anon:0
>> active_file:106409 inactive_file:107531 isolated_file:0
>> unevictable:552 dirty:175 writeback:0 unstable:0
>> slab_reclaimable:13739 slab_unreclaimable:16454
>> mapped:1605 shmem:23 pagetables:2900 bounce:0
>> free:3681 free_pcp:935 free_cma:0
>> [39041.689132] Node 0 active_anon:315100kB inactive_anon:196844kB active_file:425636kB inactive_file:430124kB unevictable:2208kB isolated(anon):0kB isolated(file):0kB mapped:6420kB dirty:700kB writeback:0kB shmem:92kB shmem_thp: 0kB shmem_pmdmapped: 0kB anon_thp: 0kB writeback_tmp:0kB unstable:0kB all_unreclaimable? no
>> [39041.689133] Node 0 DMA free:7480kB min:44kB low:56kB high:68kB active_anon:0kB inactive_anon:7832kB active_file:472kB inactive_file:4kB unevictable:0kB writepending:0kB present:15956kB managed:15872kB mlocked:0kB kernel_stack:0kB pagetables:12kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB
>> [39041.689136] lowmem_reserve[]: 0 1865 1865 1865
>> [39041.689138] Node 0 DMA32 free:7244kB min:19472kB low:21380kB high:23288kB active_anon:315360kB inactive_anon:188144kB active_file:425164kB inactive_file:430120kB unevictable:2208kB writepending:700kB present:2080768kB managed:1674968kB mlocked:2208kB kernel_stack:9632kB pagetables:11588kB bounce:0kB free_pcp:3740kB local_pcp:528kB free_cma:0kB
>> [39041.689140] lowmem_reserve[]: 0 0 0 0
>> [39041.689142] Node 0 DMA: 6*4kB (UME) 6*8kB (UE) 7*16kB (UME) 6*32kB (ME) 5*64kB (UME) 3*128kB (UE) 5*256kB (UME) 2*512kB (ME) 2*1024kB (UE) 1*2048kB (M) 0*4096kB = 7480kB
>> [39041.689148] Node 0 DMA32: 69*4kB (U) 315*8kB (UE) 138*16kB (UE) 70*32kB (UE) 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 7244kB
>> [39041.689153] 214701 total pagecache pages
>> [39041.689155] 273 pages in swap cache
>> [39041.689156] Swap cache stats: add 100978, delete 100706, find 1158/1257
>> [39041.689156] Free swap = 3790588kB
>> [39041.689157] Total swap = 4194300kB
>> [39041.689157] 524181 pages RAM
>> [39041.689158] 0 pages HighMem/MovableOnly
>> [39041.689158] 101471 pages reserved
>> [39041.689159] 0 pages cma reserved
>>
>>
>>
>>
>>
>>> diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
>>> index e8a112149..3cca2ffb2 100644
>>> --- a/drivers/net/ethernet/realtek/r8169.c
>>> +++ b/drivers/net/ethernet/realtek/r8169.c
>>> @@ -6192,7 +6192,6 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
>>> struct device *d = tp_to_dev(tp);
>>> dma_addr_t mapping;
>>> u32 opts[2], len;
>>> - bool stop_queue;
>>> int frags;
>>>
>>> if (unlikely(!rtl_tx_slots_avail(tp, skb_shinfo(skb)->nr_frags))) {
>>> @@ -6234,6 +6233,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
>>>
>>> txd->opts2 = cpu_to_le32(opts[1]);
>>>
>>> + netdev_sent_queue(dev, skb->len);
>>> +
>>> skb_tx_timestamp(skb);
>>>
>>> /* Force memory writes to complete before releasing descriptor */
>>> @@ -6246,14 +6247,14 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
>>>
>>> tp->cur_tx += frags + 1;
>>>
>>> - stop_queue = !rtl_tx_slots_avail(tp, MAX_SKB_FRAGS);
>>> - if (unlikely(stop_queue))
>>> - netif_stop_queue(dev);
>>> -
>>> - if (__netdev_sent_queue(dev, skb->len, skb->xmit_more))
>>> - RTL_W8(tp, TxPoll, NPQ);
>>> + RTL_W8(tp, TxPoll, NPQ);
>>>
>>> - if (unlikely(stop_queue)) {
>>> + if (!rtl_tx_slots_avail(tp, MAX_SKB_FRAGS)) {
>>> + /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must
>>> + * not miss a ring update when it notices a stopped queue.
>>> + */
>>> + smp_wmb();
>>> + netif_stop_queue(dev);
>>> /* Sync with rtl_tx:
>>> * - publish queue status and cur_tx ring index (write barrier)
>>> * - refresh dirty_tx ring index (read barrier).
>>>
>>
>>
>
^ permalink raw reply
* RE: [PATCH net-next v5 09/12] socket: Add SO_TIMESTAMPING_NEW
From: Ran Rozenstein @ 2019-02-10 15:43 UTC (permalink / raw)
To: Deepa Dinamani, davem@davemloft.net, linux-kernel@vger.kernel.org
Cc: netdev@vger.kernel.org, arnd@arndb.de, y2038@lists.linaro.org,
chris@zankel.net, fenghua.yu@intel.com, rth@twiddle.net,
tglx@linutronix.de, ubraun@linux.ibm.com,
linux-alpha@vger.kernel.org, linux-arch@vger.kernel.org,
linux-ia64@vger.kernel.org, linux-mips@linux-mips.org,
linux-s390@vger.kernel.org, linux-xtensa@linux-xtensa.org,
sparclinux@vger.kernel.org
In-Reply-To: <20190202153454.7121-10-deepa.kernel@gmail.com>
> Subject: [PATCH net-next v5 09/12] socket: Add SO_TIMESTAMPING_NEW
>
> Add SO_TIMESTAMPING_NEW variant of socket timestamp options.
> This is the y2038 safe versions of the SO_TIMESTAMPING_OLD for all
> architectures.
>
> Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
> Acked-by: Willem de Bruijn <willemb@google.com>
Hi,
I have app that include:
#include <linux/errqueue.h>
It now fail with this error:
In file included from timestamping.c:6:0:
/usr/include/linux/errqueue.h:46:27: error: array type has incomplete element type 'struct __kernel_timespec'
struct __kernel_timespec ts[3];
^~
I tried to do the trivial fix, to include time.h:
In include/uapi/linux/errqueue.h
#include <linux/time.h>
#include <linux/types.h>
But it just add some other noises:
In file included from /usr/include/linux/errqueue.h:5:0,
from timestamping.c:6:
/usr/include/linux/time.h:10:8: error: redefinition of ?struct timespec?
struct timespec {
^~~~~~~~
In file included from /usr/include/sys/select.h:39:0,
from /usr/include/sys/types.h:197,
from /usr/include/stdlib.h:279,
from timestamping.c:2:
/usr/include/bits/types/struct_timespec.h:8:8: note: originally defined here
struct timespec
^~~~~~~~
In file included from /usr/include/linux/errqueue.h:5:0,
from timestamping.c:6:
/usr/include/linux/time.h:16:8: error: redefinition of ?struct timeval?
struct timeval {
^~~~~~~
In file included from /usr/include/sys/select.h:37:0,
from /usr/include/sys/types.h:197,
from /usr/include/stdlib.h:279,
from timestamping.c:2:
/usr/include/bits/types/struct_timeval.h:8:8: note: originally defined here
struct timeval
^~~~~~~
Can you please advise how to solve it?
Thanks,
Ran
> diff --git a/include/uapi/linux/errqueue.h b/include/uapi/linux/errqueue.h
> index c0151200f7d1..d955b9e32288 100644
> --- a/include/uapi/linux/errqueue.h
> +++ b/include/uapi/linux/errqueue.h
> @@ -41,6 +41,10 @@ struct scm_timestamping {
> struct timespec ts[3];
> };
>
> +struct scm_timestamping64 {
> + struct __kernel_timespec ts[3];
> +};
> +
> /* The type of scm_timestamping, passed in sock_extended_err ee_info.
> * This defines the type of ts[0]. For SCM_TSTAMP_SND only, if ts[0]
> * is zero, then this is a hardware timestamp and recorded in ts[2].
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox