* [PATCH net-next v3 1/3] devlink: Introduce PCI PF port flavour and port attribute
From: Parav Pandit @ 2019-07-06 6:16 UTC (permalink / raw)
To: netdev; +Cc: jiri, saeedm, jakub.kicinski, Parav Pandit
In-Reply-To: <20190706061626.31440-1-parav@mellanox.com>
In an eswitch, PCI PF may have port which is normally represented
using a representor netdevice.
To have better visibility of eswitch port, its association with
PF and a representor netdevice, introduce a PCI PF port
flavour and port attriute.
When devlink port flavour is PCI PF, fill up PCI PF attributes of the
port.
Extend port name creation using PCI PF number on best effort basis.
So that vendor drivers can skip defining their own scheme.
$ devlink port show
pci/0000:05:00.0/0: type eth netdev eth0 flavour pcipf pfnum 0
Signed-off-by: Parav Pandit <parav@mellanox.com>
---
Changelog:
v2->v3:
- Address comments from Jakub.
- Made port_number and split_port_number applicable only to
physical port flavours by having in union.
v1->v2:
- Limited port_num attribute to physical ports
- Updated PCI PF attribute set API to not have port_number
---
include/net/devlink.h | 21 +++++++-
include/uapi/linux/devlink.h | 5 ++
net/core/devlink.c | 97 ++++++++++++++++++++++++++++--------
3 files changed, 100 insertions(+), 23 deletions(-)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 6625ea068d5e..1455f60e4069 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -38,13 +38,27 @@ struct devlink {
char priv[0] __aligned(NETDEV_ALIGN);
};
+struct devlink_port_phys_attrs {
+ u32 port_number; /* same value as "split group".
+ * A physical port which is visible to the user
+ * for a given port flavour.
+ */
+ u32 split_subport_number;
+};
+
+struct devlink_port_pci_pf_attrs {
+ u16 pf; /* Associated PCI PF for this port. */
+};
+
struct devlink_port_attrs {
u8 set:1,
split:1,
switch_port:1;
enum devlink_port_flavour flavour;
- u32 port_number; /* same value as "split group" */
- u32 split_subport_number;
+ union {
+ struct devlink_port_phys_attrs phys_port;
+ struct devlink_port_pci_pf_attrs pci_pf;
+ };
struct netdev_phys_item_id switch_id;
};
@@ -590,6 +604,9 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port,
u32 split_subport_number,
const unsigned char *switch_id,
unsigned char switch_id_len);
+void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port,
+ const unsigned char *switch_id,
+ unsigned char switch_id_len, u16 pf);
int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
u32 size, u16 ingress_pools_count,
u16 egress_pools_count, u16 ingress_tc_count,
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 5287b42c181f..f7323884c3fe 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -169,6 +169,10 @@ enum devlink_port_flavour {
DEVLINK_PORT_FLAVOUR_DSA, /* Distributed switch architecture
* interconnect port.
*/
+ DEVLINK_PORT_FLAVOUR_PCI_PF, /* Represents eswitch port for
+ * the PCI PF. It is an internal
+ * port that faces the PCI PF.
+ */
};
enum devlink_param_cmode {
@@ -337,6 +341,7 @@ enum devlink_attr {
DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE, /* u64 */
DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL, /* u64 */
+ DEVLINK_ATTR_PORT_PCI_PF_NUMBER, /* u16 */
/* add new attributes above here, update the policy in devlink.c */
__DEVLINK_ATTR_MAX,
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 89c533778135..9aa36104b471 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -506,6 +506,14 @@ static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
}
+static bool
+is_devlink_phy_port_num_supported(const struct devlink_port *dl_port)
+{
+ return (dl_port->attrs.flavour == DEVLINK_PORT_FLAVOUR_PHYSICAL ||
+ dl_port->attrs.flavour == DEVLINK_PORT_FLAVOUR_CPU ||
+ dl_port->attrs.flavour == DEVLINK_PORT_FLAVOUR_DSA);
+}
+
static int devlink_nl_port_attrs_put(struct sk_buff *msg,
struct devlink_port *devlink_port)
{
@@ -515,14 +523,23 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
return 0;
if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
return -EMSGSIZE;
- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER, attrs->port_number))
+ if (devlink_port->attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_PF) {
+ if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
+ attrs->pci_pf.pf))
+ return -EMSGSIZE;
+ }
+ if (!is_devlink_phy_port_num_supported(devlink_port))
+ return 0;
+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
+ attrs->phys_port.port_number))
return -EMSGSIZE;
if (!attrs->split)
return 0;
- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP, attrs->port_number))
+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
+ attrs->phys_port.port_number))
return -EMSGSIZE;
if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
- attrs->split_subport_number))
+ attrs->phys_port.split_subport_number))
return -EMSGSIZE;
return 0;
}
@@ -5738,6 +5755,30 @@ void devlink_port_type_clear(struct devlink_port *devlink_port)
}
EXPORT_SYMBOL_GPL(devlink_port_type_clear);
+static void __devlink_port_attrs_set(struct devlink_port *devlink_port,
+ enum devlink_port_flavour flavour,
+ u32 port_number,
+ const unsigned char *switch_id,
+ unsigned char switch_id_len)
+{
+ struct devlink_port_attrs *attrs = &devlink_port->attrs;
+
+ if (WARN_ON(devlink_port->registered))
+ return;
+ attrs->set = true;
+ attrs->flavour = flavour;
+ attrs->phys_port.port_number = port_number;
+ if (switch_id) {
+ attrs->switch_port = true;
+ if (WARN_ON(switch_id_len > MAX_PHYS_ITEM_ID_LEN))
+ switch_id_len = MAX_PHYS_ITEM_ID_LEN;
+ memcpy(attrs->switch_id.id, switch_id, switch_id_len);
+ attrs->switch_id.id_len = switch_id_len;
+ } else {
+ attrs->switch_port = false;
+ }
+}
+
/**
* devlink_port_attrs_set - Set port attributes
*
@@ -5761,25 +5802,34 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port,
{
struct devlink_port_attrs *attrs = &devlink_port->attrs;
- if (WARN_ON(devlink_port->registered))
- return;
- attrs->set = true;
- attrs->flavour = flavour;
- attrs->port_number = port_number;
+ __devlink_port_attrs_set(devlink_port, flavour, port_number,
+ switch_id, switch_id_len);
attrs->split = split;
- attrs->split_subport_number = split_subport_number;
- if (switch_id) {
- attrs->switch_port = true;
- if (WARN_ON(switch_id_len > MAX_PHYS_ITEM_ID_LEN))
- switch_id_len = MAX_PHYS_ITEM_ID_LEN;
- memcpy(attrs->switch_id.id, switch_id, switch_id_len);
- attrs->switch_id.id_len = switch_id_len;
- } else {
- attrs->switch_port = false;
- }
+ attrs->phys_port.split_subport_number = split_subport_number;
}
EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
+/**
+ * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
+ *
+ * @devlink_port: devlink port
+ * @pf: associated PF for the devlink port instance
+ * @switch_id: if the port is part of switch, this is buffer with ID,
+ * otwerwise this is NULL
+ * @switch_id_len: length of the switch_id buffer
+ */
+void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port,
+ const unsigned char *switch_id,
+ unsigned char switch_id_len, u16 pf)
+{
+ struct devlink_port_attrs *attrs = &devlink_port->attrs;
+
+ __devlink_port_attrs_set(devlink_port, DEVLINK_PORT_FLAVOUR_PCI_PF,
+ 0, switch_id, switch_id_len);
+ attrs->pci_pf.pf = pf;
+}
+EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
+
static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
char *name, size_t len)
{
@@ -5792,10 +5842,12 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
switch (attrs->flavour) {
case DEVLINK_PORT_FLAVOUR_PHYSICAL:
if (!attrs->split)
- n = snprintf(name, len, "p%u", attrs->port_number);
+ n = snprintf(name, len, "p%u",
+ attrs->phys_port.port_number);
else
- n = snprintf(name, len, "p%us%u", attrs->port_number,
- attrs->split_subport_number);
+ n = snprintf(name, len, "p%us%u",
+ attrs->phys_port.port_number,
+ attrs->phys_port.split_subport_number);
break;
case DEVLINK_PORT_FLAVOUR_CPU:
case DEVLINK_PORT_FLAVOUR_DSA:
@@ -5804,6 +5856,9 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
*/
WARN_ON(1);
return -EINVAL;
+ case DEVLINK_PORT_FLAVOUR_PCI_PF:
+ n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
+ break;
}
if (n >= len)
--
2.19.2
^ permalink raw reply related
* [PATCH net-next v3 3/3] net/mlx5e: Register devlink ports for physical link, PCI PF, VFs
From: Parav Pandit @ 2019-07-06 6:16 UTC (permalink / raw)
To: netdev; +Cc: jiri, saeedm, jakub.kicinski, Parav Pandit
In-Reply-To: <20190706061626.31440-1-parav@mellanox.com>
Register devlink port of physical port, PCI PF and PCI VF flavour
for each PF, VF when a given devlink instance is in switchdev mode.
Implement ndo_get_devlink_port callback API to make use of registered
devlink ports.
This eliminates ndo_get_phys_port_name() and ndo_get_port_parent_id()
callbacks. Hence, remove them.
An example output with 2 VFs, without a PF and single uplink port is
below.
$devlink port show
pci/0000:06:00.0/65535: type eth netdev ens2f0 flavour physical
pci/0000:05:00.0/1: type eth netdev eth1 flavour pcivf pfnum 0 vfnum 0
pci/0000:05:00.0/2: type eth netdev eth2 flavour pcivf pfnum 0 vfnum 1
Reviewed-by: Roi Dayan <roid@mellanox.com>
Signed-off-by: Parav Pandit <parav@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/en_rep.c | 108 +++++++++++++-----
.../net/ethernet/mellanox/mlx5/core/en_rep.h | 1 +
2 files changed, 78 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 529f8e4b32c6..6810b9fa0705 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -37,6 +37,7 @@
#include <net/act_api.h>
#include <net/netevent.h>
#include <net/arp.h>
+#include <net/devlink.h>
#include "eswitch.h"
#include "en.h"
@@ -1119,32 +1120,6 @@ static int mlx5e_rep_close(struct net_device *dev)
return ret;
}
-static int mlx5e_rep_get_phys_port_name(struct net_device *dev,
- char *buf, size_t len)
-{
- struct mlx5e_priv *priv = netdev_priv(dev);
- struct mlx5e_rep_priv *rpriv = priv->ppriv;
- struct mlx5_eswitch_rep *rep = rpriv->rep;
- unsigned int fn;
- int ret;
-
- fn = PCI_FUNC(priv->mdev->pdev->devfn);
- if (fn >= MLX5_MAX_PORTS)
- return -EOPNOTSUPP;
-
- if (rep->vport == MLX5_VPORT_UPLINK)
- ret = snprintf(buf, len, "p%d", fn);
- else if (rep->vport == MLX5_VPORT_PF)
- ret = snprintf(buf, len, "pf%d", fn);
- else
- ret = snprintf(buf, len, "pf%dvf%d", fn, rep->vport - 1);
-
- if (ret >= len)
- return -EOPNOTSUPP;
-
- return 0;
-}
-
static int
mlx5e_rep_setup_tc_cls_flower(struct mlx5e_priv *priv,
struct tc_cls_flower_offload *cls_flower, int flags)
@@ -1298,17 +1273,24 @@ static int mlx5e_uplink_rep_set_vf_vlan(struct net_device *dev, int vf, u16 vlan
return 0;
}
+static struct devlink_port *mlx5e_get_devlink_port(struct net_device *dev)
+{
+ struct mlx5e_priv *priv = netdev_priv(dev);
+ struct mlx5e_rep_priv *rpriv = priv->ppriv;
+
+ return &rpriv->dl_port;
+}
+
static const struct net_device_ops mlx5e_netdev_ops_rep = {
.ndo_open = mlx5e_rep_open,
.ndo_stop = mlx5e_rep_close,
.ndo_start_xmit = mlx5e_xmit,
- .ndo_get_phys_port_name = mlx5e_rep_get_phys_port_name,
.ndo_setup_tc = mlx5e_rep_setup_tc,
+ .ndo_get_devlink_port = mlx5e_get_devlink_port,
.ndo_get_stats64 = mlx5e_rep_get_stats,
.ndo_has_offload_stats = mlx5e_rep_has_offload_stats,
.ndo_get_offload_stats = mlx5e_rep_get_offload_stats,
.ndo_change_mtu = mlx5e_rep_change_mtu,
- .ndo_get_port_parent_id = mlx5e_rep_get_port_parent_id,
};
static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
@@ -1316,8 +1298,8 @@ static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
.ndo_stop = mlx5e_close,
.ndo_start_xmit = mlx5e_xmit,
.ndo_set_mac_address = mlx5e_uplink_rep_set_mac,
- .ndo_get_phys_port_name = mlx5e_rep_get_phys_port_name,
.ndo_setup_tc = mlx5e_rep_setup_tc,
+ .ndo_get_devlink_port = mlx5e_get_devlink_port,
.ndo_get_stats64 = mlx5e_get_stats,
.ndo_has_offload_stats = mlx5e_rep_has_offload_stats,
.ndo_get_offload_stats = mlx5e_rep_get_offload_stats,
@@ -1330,7 +1312,6 @@ static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
.ndo_get_vf_config = mlx5e_get_vf_config,
.ndo_get_vf_stats = mlx5e_get_vf_stats,
.ndo_set_vf_vlan = mlx5e_uplink_rep_set_vf_vlan,
- .ndo_get_port_parent_id = mlx5e_rep_get_port_parent_id,
.ndo_set_features = mlx5e_set_features,
};
@@ -1731,6 +1712,55 @@ static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
.max_tc = MLX5E_MAX_NUM_TC,
};
+static bool
+is_devlink_port_supported(const struct mlx5_core_dev *dev,
+ const struct mlx5e_rep_priv *rpriv)
+{
+ return rpriv->rep->vport == MLX5_VPORT_UPLINK ||
+ rpriv->rep->vport == MLX5_VPORT_PF ||
+ mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport);
+}
+
+static int register_devlink_port(struct mlx5_core_dev *dev,
+ struct mlx5e_rep_priv *rpriv)
+{
+ struct devlink *devlink = priv_to_devlink(dev);
+ struct mlx5_eswitch_rep *rep = rpriv->rep;
+ struct netdev_phys_item_id ppid = {};
+ int ret;
+
+ if (!is_devlink_port_supported(dev, rpriv))
+ return 0;
+
+ ret = mlx5e_rep_get_port_parent_id(rpriv->netdev, &ppid);
+ if (ret)
+ return ret;
+
+ if (rep->vport == MLX5_VPORT_UPLINK)
+ devlink_port_attrs_set(&rpriv->dl_port,
+ DEVLINK_PORT_FLAVOUR_PHYSICAL,
+ PCI_FUNC(dev->pdev->devfn), false, 0,
+ &ppid.id[0], ppid.id_len);
+ else if (rep->vport == MLX5_VPORT_PF)
+ devlink_port_attrs_pci_pf_set(&rpriv->dl_port,
+ &ppid.id[0], ppid.id_len,
+ dev->pdev->devfn);
+ else if (mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport))
+ devlink_port_attrs_pci_vf_set(&rpriv->dl_port,
+ &ppid.id[0], ppid.id_len,
+ dev->pdev->devfn,
+ rep->vport - 1);
+
+ return devlink_port_register(devlink, &rpriv->dl_port, rep->vport);
+}
+
+static void unregister_devlink_port(struct mlx5_core_dev *dev,
+ struct mlx5e_rep_priv *rpriv)
+{
+ if (is_devlink_port_supported(dev, rpriv))
+ devlink_port_unregister(&rpriv->dl_port);
+}
+
/* e-Switch vport representors */
static int
mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
@@ -1782,15 +1812,27 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
goto err_detach_netdev;
}
+ err = register_devlink_port(dev, rpriv);
+ if (err) {
+ esw_warn(dev, "Failed to register devlink port %d\n",
+ rep->vport);
+ goto err_neigh_cleanup;
+ }
+
err = register_netdev(netdev);
if (err) {
pr_warn("Failed to register representor netdev for vport %d\n",
rep->vport);
- goto err_neigh_cleanup;
+ goto err_devlink_cleanup;
}
+ if (is_devlink_port_supported(dev, rpriv))
+ devlink_port_type_eth_set(&rpriv->dl_port, netdev);
return 0;
+err_devlink_cleanup:
+ unregister_devlink_port(dev, rpriv);
+
err_neigh_cleanup:
mlx5e_rep_neigh_cleanup(rpriv);
@@ -1813,9 +1855,13 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
struct net_device *netdev = rpriv->netdev;
struct mlx5e_priv *priv = netdev_priv(netdev);
+ struct mlx5_core_dev *dev = priv->mdev;
void *ppriv = priv->ppriv;
+ if (is_devlink_port_supported(dev, rpriv))
+ devlink_port_type_clear(&rpriv->dl_port);
unregister_netdev(netdev);
+ unregister_devlink_port(dev, rpriv);
mlx5e_rep_neigh_cleanup(rpriv);
mlx5e_detach_netdev(priv);
if (rep->vport == MLX5_VPORT_UPLINK)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
index d4585f3b8cb2..c56e6ee4350c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
@@ -86,6 +86,7 @@ struct mlx5e_rep_priv {
struct mlx5_flow_handle *vport_rx_rule;
struct list_head vport_sqs_list;
struct mlx5_rep_uplink_priv uplink_priv; /* valid for uplink rep */
+ struct devlink_port dl_port;
};
static inline
--
2.19.2
^ permalink raw reply related
* Re: INFO: rcu detected stall in ext4_write_checks
From: Paul E. McKenney @ 2019-07-06 6:16 UTC (permalink / raw)
To: Theodore Ts'o, Dmitry Vyukov, syzbot, Andreas Dilger,
David Miller, eladr, Ido Schimmel, Jiri Pirko, John Stultz,
linux-ext4, LKML, netdev, syzkaller-bugs, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar
In-Reply-To: <20190706042801.GD11665@mit.edu>
On Sat, Jul 06, 2019 at 12:28:01AM -0400, Theodore Ts'o wrote:
> On Fri, Jul 05, 2019 at 12:10:55PM -0700, Paul E. McKenney wrote:
> >
> > Exactly, so although my patch might help for CONFIG_PREEMPT=n, it won't
> > help in your scenario. But looking at the dmesg from your URL above,
> > I see the following:
>
> I just tested with CONFIG_PREEMPT=n
>
> % grep CONFIG_PREEMPT /build/ext4-64/.config
> CONFIG_PREEMPT_NONE=y
> # CONFIG_PREEMPT_VOLUNTARY is not set
> # CONFIG_PREEMPT is not set
> CONFIG_PREEMPT_COUNT=y
> CONFIG_PREEMPTIRQ_TRACEPOINTS=y
> # CONFIG_PREEMPTIRQ_EVENTS is not set
>
> And with your patch, it's still not helping.
>
> I think that's because SCHED_DEADLINE is a real-time style scheduler:
>
> In order to fulfill the guarantees that are made when a thread is ad‐
> mitted to the SCHED_DEADLINE policy, SCHED_DEADLINE threads are the
> highest priority (user controllable) threads in the system; if any
> SCHED_DEADLINE thread is runnable, it will preempt any thread scheduled
> under one of the other policies.
>
> So a SCHED_DEADLINE process is not going yield control of the CPU,
> even if it calls cond_resched() until the thread has run for more than
> the sched_runtime parameter --- which for the syzkaller repro, was set
> at 26 days.
>
> There are some safety checks when using SCHED_DEADLINE:
>
> The kernel requires that:
>
> sched_runtime <= sched_deadline <= sched_period
>
> In addition, under the current implementation, all of the parameter
> values must be at least 1024 (i.e., just over one microsecond, which is
> the resolution of the implementation), and less than 2^63. If any of
> these checks fails, sched_setattr(2) fails with the error EINVAL.
>
> The CBS guarantees non-interference between tasks, by throttling
> threads that attempt to over-run their specified Runtime.
>
> To ensure deadline scheduling guarantees, the kernel must prevent situ‐
> ations where the set of SCHED_DEADLINE threads is not feasible (schedu‐
> lable) within the given constraints. The kernel thus performs an ad‐
> mittance test when setting or changing SCHED_DEADLINE policy and at‐
> tributes. This admission test calculates whether the change is feasi‐
> ble; if it is not, sched_setattr(2) fails with the error EBUSY.
>
> The problem is that SCHED_DEADLINE is designed for sporadic tasks:
>
> A sporadic task is one that has a sequence of jobs, where each job is
> activated at most once per period. Each job also has a relative dead‐
> line, before which it should finish execution, and a computation time,
> which is the CPU time necessary for executing the job. The moment when
> a task wakes up because a new job has to be executed is called the ar‐
> rival time (also referred to as the request time or release time). The
> start time is the time at which a task starts its execution. The abso‐
> lute deadline is thus obtained by adding the relative deadline to the
> arrival time.
>
> It appears that kernel's admission control before allowing
> SCHED_DEADLINE to be set on a thread was designed for sane
> applications, and not abusive ones. Given that process started doing
> abusive things *after* SCHED_DEADLINE policy was set, in order kernel
> to figure out that in fact SCHED_DEADLINE should be denied for any
> arbitrary kernel thread would require either (a) solving the halting
> problem, or (b) being able to anticipate the future (in which case,
> we should be using that kernel algorithm to play the stock market :-)
26 days will definitely get you a large collection of RCU CPU stall
warnings! Thank you for digging into this, Ted.
I suppose RCU could take the dueling-banjos approach and use increasingly
aggressive scheduler policies itself, up to and including SCHED_DEADLINE,
until it started getting decent forward progress. However, that
sounds like the something that just might have unintended consequences,
particularly if other kernel subsystems were to also play similar
games of dueling banjos.
Alternatively, is it possible to provide stricter admission control?
For example, what sorts of policies do SCHED_DEADLINE users actually use?
Thanx, Paul
^ permalink raw reply
* Re: [PATCH net-next v3 1/3] devlink: Introduce PCI PF port flavour and port attribute
From: Jiri Pirko @ 2019-07-06 6:26 UTC (permalink / raw)
To: Parav Pandit; +Cc: netdev, jiri, saeedm, jakub.kicinski
In-Reply-To: <20190706061626.31440-2-parav@mellanox.com>
Sat, Jul 06, 2019 at 08:16:24AM CEST, parav@mellanox.com wrote:
>In an eswitch, PCI PF may have port which is normally represented
>using a representor netdevice.
>To have better visibility of eswitch port, its association with
>PF and a representor netdevice, introduce a PCI PF port
>flavour and port attriute.
>
>When devlink port flavour is PCI PF, fill up PCI PF attributes of the
>port.
>
>Extend port name creation using PCI PF number on best effort basis.
>So that vendor drivers can skip defining their own scheme.
>
>$ devlink port show
>pci/0000:05:00.0/0: type eth netdev eth0 flavour pcipf pfnum 0
>
>Signed-off-by: Parav Pandit <parav@mellanox.com>
>
>---
>Changelog:
>v2->v3:
> - Address comments from Jakub.
> - Made port_number and split_port_number applicable only to
> physical port flavours by having in union.
>v1->v2:
> - Limited port_num attribute to physical ports
> - Updated PCI PF attribute set API to not have port_number
>---
> include/net/devlink.h | 21 +++++++-
> include/uapi/linux/devlink.h | 5 ++
> net/core/devlink.c | 97 ++++++++++++++++++++++++++++--------
> 3 files changed, 100 insertions(+), 23 deletions(-)
>
>diff --git a/include/net/devlink.h b/include/net/devlink.h
>index 6625ea068d5e..1455f60e4069 100644
>--- a/include/net/devlink.h
>+++ b/include/net/devlink.h
>@@ -38,13 +38,27 @@ struct devlink {
> char priv[0] __aligned(NETDEV_ALIGN);
> };
>
>+struct devlink_port_phys_attrs {
>+ u32 port_number; /* same value as "split group".
"Same" with capital letter.
>+ * A physical port which is visible to the user
>+ * for a given port flavour.
>+ */
>+ u32 split_subport_number;
>+};
>+
>+struct devlink_port_pci_pf_attrs {
>+ u16 pf; /* Associated PCI PF for this port. */
>+};
>+
> struct devlink_port_attrs {
> u8 set:1,
> split:1,
> switch_port:1;
> enum devlink_port_flavour flavour;
>- u32 port_number; /* same value as "split group" */
>- u32 split_subport_number;
>+ union {
>+ struct devlink_port_phys_attrs phys_port;
>+ struct devlink_port_pci_pf_attrs pci_pf;
Be consistent in naming: "phys", "pci_pf".
>+ };
> struct netdev_phys_item_id switch_id;
> };
>
>@@ -590,6 +604,9 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port,
> u32 split_subport_number,
> const unsigned char *switch_id,
> unsigned char switch_id_len);
>+void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port,
>+ const unsigned char *switch_id,
>+ unsigned char switch_id_len, u16 pf);
> int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
> u32 size, u16 ingress_pools_count,
> u16 egress_pools_count, u16 ingress_tc_count,
>diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
>index 5287b42c181f..f7323884c3fe 100644
>--- a/include/uapi/linux/devlink.h
>+++ b/include/uapi/linux/devlink.h
>@@ -169,6 +169,10 @@ enum devlink_port_flavour {
> DEVLINK_PORT_FLAVOUR_DSA, /* Distributed switch architecture
> * interconnect port.
> */
>+ DEVLINK_PORT_FLAVOUR_PCI_PF, /* Represents eswitch port for
>+ * the PCI PF. It is an internal
>+ * port that faces the PCI PF.
>+ */
> };
>
> enum devlink_param_cmode {
>@@ -337,6 +341,7 @@ enum devlink_attr {
> DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE, /* u64 */
> DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL, /* u64 */
>
>+ DEVLINK_ATTR_PORT_PCI_PF_NUMBER, /* u16 */
> /* add new attributes above here, update the policy in devlink.c */
>
> __DEVLINK_ATTR_MAX,
>diff --git a/net/core/devlink.c b/net/core/devlink.c
>index 89c533778135..9aa36104b471 100644
>--- a/net/core/devlink.c
>+++ b/net/core/devlink.c
>@@ -506,6 +506,14 @@ static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
> msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
> }
>
>+static bool
>+is_devlink_phy_port_num_supported(const struct devlink_port *dl_port)
>+{
>+ return (dl_port->attrs.flavour == DEVLINK_PORT_FLAVOUR_PHYSICAL ||
>+ dl_port->attrs.flavour == DEVLINK_PORT_FLAVOUR_CPU ||
>+ dl_port->attrs.flavour == DEVLINK_PORT_FLAVOUR_DSA);
>+}
>+
> static int devlink_nl_port_attrs_put(struct sk_buff *msg,
> struct devlink_port *devlink_port)
> {
>@@ -515,14 +523,23 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
> return 0;
> if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
> return -EMSGSIZE;
>- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER, attrs->port_number))
>+ if (devlink_port->attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_PF) {
>+ if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
>+ attrs->pci_pf.pf))
>+ return -EMSGSIZE;
>+ }
>+ if (!is_devlink_phy_port_num_supported(devlink_port))
Please do the check here. No need for helper (the name with "is" and
"supported" is weird anyway.
>+ return 0;
>+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
>+ attrs->phys_port.port_number))
> return -EMSGSIZE;
> if (!attrs->split)
> return 0;
>- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP, attrs->port_number))
>+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
>+ attrs->phys_port.port_number))
Better to split this into 2 patches. One pushing phys things into
separate struct, the second the rest.
> return -EMSGSIZE;
> if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
>- attrs->split_subport_number))
>+ attrs->phys_port.split_subport_number))
> return -EMSGSIZE;
> return 0;
> }
>@@ -5738,6 +5755,30 @@ void devlink_port_type_clear(struct devlink_port *devlink_port)
> }
> EXPORT_SYMBOL_GPL(devlink_port_type_clear);
>
>+static void __devlink_port_attrs_set(struct devlink_port *devlink_port,
>+ enum devlink_port_flavour flavour,
>+ u32 port_number,
>+ const unsigned char *switch_id,
>+ unsigned char switch_id_len)
>+{
>+ struct devlink_port_attrs *attrs = &devlink_port->attrs;
>+
>+ if (WARN_ON(devlink_port->registered))
>+ return;
>+ attrs->set = true;
>+ attrs->flavour = flavour;
>+ attrs->phys_port.port_number = port_number;
>+ if (switch_id) {
>+ attrs->switch_port = true;
>+ if (WARN_ON(switch_id_len > MAX_PHYS_ITEM_ID_LEN))
>+ switch_id_len = MAX_PHYS_ITEM_ID_LEN;
>+ memcpy(attrs->switch_id.id, switch_id, switch_id_len);
>+ attrs->switch_id.id_len = switch_id_len;
>+ } else {
>+ attrs->switch_port = false;
>+ }
>+}
>+
> /**
> * devlink_port_attrs_set - Set port attributes
> *
>@@ -5761,25 +5802,34 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port,
> {
> struct devlink_port_attrs *attrs = &devlink_port->attrs;
>
>- if (WARN_ON(devlink_port->registered))
>- return;
>- attrs->set = true;
>- attrs->flavour = flavour;
>- attrs->port_number = port_number;
>+ __devlink_port_attrs_set(devlink_port, flavour, port_number,
>+ switch_id, switch_id_len);
> attrs->split = split;
>- attrs->split_subport_number = split_subport_number;
>- if (switch_id) {
>- attrs->switch_port = true;
>- if (WARN_ON(switch_id_len > MAX_PHYS_ITEM_ID_LEN))
>- switch_id_len = MAX_PHYS_ITEM_ID_LEN;
>- memcpy(attrs->switch_id.id, switch_id, switch_id_len);
>- attrs->switch_id.id_len = switch_id_len;
>- } else {
>- attrs->switch_port = false;
>- }
>+ attrs->phys_port.split_subport_number = split_subport_number;
> }
> EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
>
>+/**
>+ * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
>+ *
>+ * @devlink_port: devlink port
>+ * @pf: associated PF for the devlink port instance
>+ * @switch_id: if the port is part of switch, this is buffer with ID,
>+ * otwerwise this is NULL
>+ * @switch_id_len: length of the switch_id buffer
>+ */
>+void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port,
>+ const unsigned char *switch_id,
>+ unsigned char switch_id_len, u16 pf)
>+{
>+ struct devlink_port_attrs *attrs = &devlink_port->attrs;
>+
>+ __devlink_port_attrs_set(devlink_port, DEVLINK_PORT_FLAVOUR_PCI_PF,
>+ 0, switch_id, switch_id_len);
Please have this done differently. __devlink_port_attrs_set() sets
attrs->phys_port.port_number which does not make sense there.
>+ attrs->pci_pf.pf = pf;
>+}
>+EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
>+
> static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
> char *name, size_t len)
> {
>@@ -5792,10 +5842,12 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
> switch (attrs->flavour) {
> case DEVLINK_PORT_FLAVOUR_PHYSICAL:
> if (!attrs->split)
>- n = snprintf(name, len, "p%u", attrs->port_number);
>+ n = snprintf(name, len, "p%u",
>+ attrs->phys_port.port_number);
> else
>- n = snprintf(name, len, "p%us%u", attrs->port_number,
>- attrs->split_subport_number);
>+ n = snprintf(name, len, "p%us%u",
>+ attrs->phys_port.port_number,
>+ attrs->phys_port.split_subport_number);
> break;
> case DEVLINK_PORT_FLAVOUR_CPU:
> case DEVLINK_PORT_FLAVOUR_DSA:
>@@ -5804,6 +5856,9 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
> */
> WARN_ON(1);
> return -EINVAL;
>+ case DEVLINK_PORT_FLAVOUR_PCI_PF:
>+ n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
>+ break;
> }
>
> if (n >= len)
>--
>2.19.2
>
^ permalink raw reply
* Re: [PATCH net-next] tipc: use rcu dereference functions properly
From: Xin Long @ 2019-07-06 6:48 UTC (permalink / raw)
To: David Miller; +Cc: network dev, Jon Maloy, Ying Xue, tipc-discussion
In-Reply-To: <CADvbK_emyKTg8=ye8n2ZTBx0QFK9gPL02aVDfn44DuyUTP-ofw@mail.gmail.com>
On Wed, Jul 3, 2019 at 4:33 PM Xin Long <lucien.xin@gmail.com> wrote:
>
> On Wed, Jul 3, 2019 at 6:08 AM David Miller <davem@davemloft.net> wrote:
> >
> > From: Xin Long <lucien.xin@gmail.com>
> > Date: Tue, 2 Jul 2019 00:54:55 +0800
> >
> > > For these places are protected by rcu_read_lock, we change from
> > > rcu_dereference_rtnl to rcu_dereference, as there is no need to
> > > check if rtnl lock is held.
> > >
> > > For these places are protected by rtnl_lock, we change from
> > > rcu_dereference_rtnl to rtnl_dereference/rcu_dereference_protected,
> > > as no extra memory barriers are needed under rtnl_lock() which also
> > > protects tn->bearer_list[] and dev->tipc_ptr/b->media_ptr updating.
> > >
> > > rcu_dereference_rtnl will be only used in the places where it could
> > > be under rcu_read_lock or rtnl_lock.
> > >
> > > Signed-off-by: Xin Long <lucien.xin@gmail.com>
> >
> > In the cases where RTNL is held, even if rcu_read_lock() is also taken,
> > we should use rtnl_dereference() because that avoids the READ_ONCE().
> Right, that's what I did in this patch.
>
> But for the places where it's sometimes called under rtnl_lock() only and
> sometimes called under rcu_read_lock() only, like tipc_udp_is_known_peer()
> and tipc_udp_rcast_add(), I kept rcu_dereference_rtnl(). makes sense?
Hi, David, I saw this patch in "Changes Requested".
I've checked all places with this patch, no function calling rcu_dereference()
and rcu_dereference_rtnl() will be ONLY called under rtnl_lock() protection.
So I can't see a problem with it.
Do I need to resend?
^ permalink raw reply
* pull-request: wireless-drivers-next 2019-07-06
From: Kalle Valo @ 2019-07-06 7:04 UTC (permalink / raw)
To: David Miller; +Cc: linux-wireless, netdev, linux-kernel
Hi Dave,
here's a pull request to net-next tree for v5.3, more info below. I will
be offline from Sunday to Thursday, but Johannes should be able to help
during that time.
Kalle
The following changes since commit 8b89d8dad5df177032e7e97ecfb18f01134e0e4b:
Merge branch 'macb-build-fixes' (2019-06-26 14:09:38 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git tags/wireless-drivers-next-for-davem-2019-07-06
for you to fetch changes up to 5adcdab6ae1b0a53456e8a269b1856094dc20a59:
Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git (2019-07-01 22:23:11 +0300)
----------------------------------------------------------------
wireless-drivers-next patches for 5.3
Second, and last, set of patches for 5.3.
Major changes:
mt76
* use NAPI polling for tx cleanup on mt7603/mt7615
* add support for toggling edcca on mt7603
* fix rate control / tx status reporting issues on mt76x02/mt7603
* add support for eeprom calibration data from mtd on mt7615
* support configuring tx power on mt7615
* per-chain signal reporting on mt7615
iwlwifi
* Update the FW API for Channel State Information (CSI)
* Special Specific Absorption Rate (SAR) implementation for South Korea
ath10k
* fixes for SDIO support
* add support for firmware logging via WMI
----------------------------------------------------------------
Ahmad Masri (4):
wil6210: enlarge Tx status ring size
wil6210: increase the frequency of status ring hw tail update
wil6210: set WIL_WMI_CALL_GENERAL_TO_MS as wmi_call timeout
wil6210: drop old event after wmi_call timeout
Alexei Avshalom Lazar (3):
wil6210: do not reset FW in STA to P2P client interface switch
wil6210: Add support for setting RBUFCAP configuration
wil6210: update cid boundary check of wil_find_cid/_by_idx()
Andrei Otcheretianski (1):
iwlwifi: mvm: Drop large non sta frames
Ashok Raj Nagarajan (1):
ath10k: add support for controlling tx power to a station
Balaji Pothunoori (1):
ath10k: enabling tx stats support over pktlog
Brian Norris (2):
mwifiex: dispatch/rotate from reorder table atomically
mwifiex: don't disable hardirqs; just softirqs
Christian Lamparter (2):
carl9170: fix misuse of device driver API
carl9170: remove dead branch in op_conf_tx callback
Christoph Hellwig (4):
b43legacy: remove b43legacy_dma_set_mask
b43legacy: simplify engine type / DMA mask selection
b43: remove b43_dma_set_mask
b43: simplify engine type / DMA mask selection
Claire Chang (2):
ath10k: acquire lock to fix lockdep's warning
ath10k: add missing error handling
Dan Carpenter (3):
mt76: Fix a signedness bug in mt7615_add_interface()
mt76: mt7615: Use after free in mt7615_mcu_set_bcn()
iwlwifi: remove some unnecessary NULL checks
Dedy Lansky (1):
wil6210: fix printout in wil_read_pmccfg
Dundi Raviteja (2):
ath10k: Add peer delete response event
ath10k: Fix memory leak in qmi
Emmanuel Grumbach (7):
iwlwifi: support FSEQ TLV even when FMAC is not compiled
iwlwifi: mvm: make the usage of TWT configurable
iwlwifi: pcie: fix ALIVE interrupt handling for gen2 devices w/o MSI-X
iwlwifi: fix RF-Kill interrupt while FW load for gen2 devices
iwlwifi: pcie: don't service an interrupt that was masked
iwlwifi: don't WARN when calling iwl_get_shared_mem_conf with RF-Kill
iwlwifi: mvm: clear rfkill_safe_init_done when we start the firmware
Erik Stromdahl (2):
ath10k: add inline wrapper for htt_h2t_aggr_cfg_msg
ath10k: add htt_h2t_aggr_cfg_msg op for high latency devices
Fabio Estevam (1):
ath10k: Change the warning message string
Felix Fietkau (7):
mt76: mt7603: fix reading target tx power from eeprom
mt76: fix setting chan->max_power
mt76: mt76x02: fix tx status reporting issues
mt76: mt76x02: fix tx reordering on rate control probing without a-mpdu
mt76: mt76x0: fix RF frontend initialization for external PA
mt76: mt7603: rework and fix tx status reporting
mt76: mt7603: improve hardware rate switching configuration
Govind Singh (1):
ath10k: Add WMI diag fw logging support for WCN3990
Greg Kroah-Hartman (1):
wil6210: no need to check return value of debugfs_create functions
Gustavo A. R. Silva (2):
iwlwifi: lib: Use struct_size() helper
iwlwifi: d3: Use struct_size() helper
Haim Dreyfuss (2):
iwlwifi: Add support for SAR South Korea limitation
iwlwifi: mvm: Add log information about SAR status
Jiri Kosina (1):
iwlwifi: iwl_mvm_tx_mpdu() must be called with BH disabled
Johannes Berg (3):
iwlwifi: update CSI API
iwlwifi: fix module init error paths
iwlwifi: mvm: delay GTK setting in FW in AP mode
Kalle Valo (5):
ath10k: remove unnecessary 'out of memory' message
ath10k: pci: remove unnecessary casts
Merge tag 'mt76-for-kvalo-2019-06-27' of https://github.com/nbd168/wireless
Merge tag 'iwlwifi-next-for-kalle-2019-06-29' of git://git.kernel.org/.../iwlwifi/iwlwifi-next
Merge ath-next from git://git.kernel.org/.../kvalo/ath.git
Lorenzo Bianconi (53):
mt76: mt76x02: remove useless return in mt76x02_resync_beacon_timer
mt76: move tx_napi in mt76_dev
mt76: mt7603: use napi polling for tx cleanup
mt76: mt7615: use napi polling for tx cleanup
mt76: move netif_napi_del in mt76_dma_cleanup
mt7615: mcu: simplify __mt7615_mcu_set_wtbl
mt7615: mcu: simplify __mt7615_mcu_set_sta_rec
mt7615: mcu: remove bss_info_convert_vif_type routine
mt7615: mcu: use proper msg size in mt7615_mcu_add_wtbl_bmc
mt7615: mcu: use proper msg size in mt7615_mcu_add_wtbl
mt7615: mcu: unify mt7615_mcu_add_wtbl_bmc and mt7615_mcu_del_wtbl_bmc
mt7615: mcu: remove unused parameter in mt7615_mcu_del_wtbl
mt7615: remove query from mt7615_mcu_msg_send signature
mt7615: remove dest from mt7615_mcu_msg_send signature
mt7615: mcu: remove skb_ret from mt7615_mcu_msg_send
mt7615: mcu: unify __mt7615_mcu_set_dev_info and mt7615_mcu_set_dev_info
mt7615: mcu: do not use function pointers whenever possible
mt7615: mcu: remove unused structure in mcu.h
mt7615: mcu: use standard signature for mt7615_mcu_msg_send
mt7615: initialize mt76_mcu_ops data structure
mt7615: mcu: init mcu_restart function pointer
mt7615: mcu: run __mt76_mcu_send_msg in mt7615_mcu_send_firmware
mt76: mt7603: stop mac80211 queues before setting the channel
mt76: mt7615: rearrange cleanup operations in mt7615_unregister_device
mt76: mt7615: add static qualifier to mt7615_rx_poll_complete
mt76: mt76x02: remove enable from mt76x02_edcca_init signature
mt76: mt76x2u: remove mt76x02_edcca_init in mt76x2u_set_channel
mt76: mt76x2: move mutex_lock inside mt76x2_set_channel
mt76: mt76x02: run mt76x02_edcca_init atomically in mt76_edcca_set
mt76: mt7603: add debugfs knob to enable/disable edcca
mt76: mt76x02: fix edcca file permission
mt76: mt7615: do not process rx packets if the device is not initialized
mt76: move mt76_insert_ccmp_hdr in mt76-module
mt76: mt7615: add support for mtd eeprom parsing
mt76: mt7615: select wifi band according to eeprom
mt76: generalize mt76_get_txpower for 4x4:4 devices
mt76: mt7615: add the capability to configure tx power
mt76: mt7615: init get_txpower mac80211 callback
mt76: mt7615: rearrange locking in mt7615_config
mt76: move mt76_get_rate in mt76-module
mt76: mt7615: remove unused variable in mt7615_mcu_set_bcn
mt76: mt7615: remove key check in mt7615_mcu_set_wtbl_key
mt76: mt7615: simplify mt7615_mcu_set_sta_rec routine
mt76: mt7615: init per-channel target power
mt76: mt7615: take into account extPA when configuring tx power
mt76: mt76x02u: fix sparse warnings: should it be static?
mt76: mt76u: reduce rx memory footprint
mt76: mt7615: remove cfg80211_chan_def from mt7615_set_channel signature
mt76: move nl80211_dfs_regions in mt76_dev data structure
mt76: mt76u: get rid of {out,in}_max_packet
mt76: mt7615: fix sparse warnings: incorrect type in assignment (different base types)
mt76: mt7615: fix sparse warnings: warning: cast from restricted __le16
mt76: mt7603: fix sparse warnings: warning: incorrect type in assignment (different base types)
Luca Coelho (2):
iwlwifi: pcie: increase the size of PCI dumps
iwlwifi: mvm: remove MAC_FILTER_IN_11AX for AP mode
Maya Erez (2):
wil6210: clear FW and ucode log address
wil6210: publish max_msdu_size to FW on BCAST ring
Miaoqing Pan (3):
ath10k: fix fw crash by moving chip reset after napi disabled
ath10k: fix failure to set multiple fixed rate
ath10k: fix PCIE device wake up failed
Mordechay Goodstein (2):
iwlwifi: mvm: add a debugfs entry to set a fixed size AMSDU for all TX packets
iwlwifi: mvm: remove multiple debugfs entries
Naftali Goldstein (1):
iwlwifi: mvm: correctly fill the ac array in the iwl_mac_ctx_cmd
Rakesh Pillai (1):
ath10k: wait for vdev delete response from firmware
Ryder Lee (5):
mt76: mt7615: enable support for mesh
mt76: mt7615: fix slow performance when enable encryption
mt76: mt7615: add support for per-chain signal strength reporting
mt76: mt7615: fix incorrect settings in mesh mode
mt76: mt7615: update peer's bssid when state transition occurs
Shahar S Matityahu (15):
iwlwifi: dbg: allow dump collection in case of an early error
iwlwifi: dbg_ini: dump headers cleanup
iwlwifi: dbg_ini: abort region collection in case the size is 0
iwlwifi: dbg_ini: add consecutive trigger firing support
iwlwifi: dbg_ini: use different barker for ini dump
iwlwifi: dbg_ini: support debug info TLV
iwlwifi: dbg_ini: implement dump info collection
iwlwifi: fw api: support adwell HB default APs number api
iwlwifi: dbg: fix debug monitor stop and restart delays
iwlwifi: dbg_ini: enforce apply point early on buffer allocation tlv
iwlwifi: dbg_ini: remove redundant checking of ini mode
iwlwifi: dbg: move trans debug fields to a separate struct
iwlwifi: dbg_ini: fix debug monitor stop and restart in ini mode
iwlwifi: dbg: don't stop dbg recording before entering D3 from 9000 devices
iwlwifi: dbg: debug recording stop and restart command remove
Shaul Triebitz (1):
iwlwifi: mvm: convert to FW AC when configuring MU EDCA
Tzahi Sabo (1):
wil6210: add support for reading multiple RFs temperature via debugfs
Tzu-En Huang (1):
rtw88: remove all RTW_MAX_POWER_INDEX macro
Venkateswara Naralasetty (1):
ath10k: Add wrapper function to ath10k debug
Wen Gong (6):
ath10k: add support for firmware crash recovery on SDIO chip
ath10k: change firmware file name for UTF mode of SDIO/USB
ath10k: add report MIC error for sdio chip
ath10k: add new hw_ops for sdio chip
ath10k: Move non-fatal warn logs to dbg level for SDIO chip
ath10k: destroy sdio workqueue while remove sdio module
Yan-Hsuan Chuang (6):
rtw88: resolve order of tx power setting routines
rtw88: do not use (void *) as argument
rtw88: unify prefixes for tx power setting routine
rtw88: remove unused variable
rtw88: fix incorrect tx power limit at 5G
rtw88: choose the lowest as world-wide power limit
YueHaibing (2):
mt76: mt7615: Make mt7615_irq_handler static
mt76: Remove set but not used variables 'pid' and 'final_mpdu'
Zefir Kurtisi (1):
ath9k: correctly handle short radar pulses
Zong-Zhe Yang (3):
rtw88: correct power limit selection
rtw88: update tx power limit table to RF v20
rtw88: refine flow to get tx power index
drivers/net/wireless/ath/ath10k/core.c | 34 +-
drivers/net/wireless/ath/ath10k/core.h | 15 +-
drivers/net/wireless/ath/ath10k/debug.c | 8 +-
drivers/net/wireless/ath/ath10k/debug.h | 25 +-
drivers/net/wireless/ath/ath10k/hif.h | 15 +
drivers/net/wireless/ath/ath10k/htt.c | 2 +-
drivers/net/wireless/ath/ath10k/htt.h | 16 +-
drivers/net/wireless/ath/ath10k/htt_rx.c | 20 +-
drivers/net/wireless/ath/ath10k/htt_tx.c | 9 +-
drivers/net/wireless/ath/ath10k/hw.c | 6 +-
drivers/net/wireless/ath/ath10k/hw.h | 7 +
drivers/net/wireless/ath/ath10k/mac.c | 209 +++-
drivers/net/wireless/ath/ath10k/pci.c | 25 +-
drivers/net/wireless/ath/ath10k/qmi.c | 46 +
drivers/net/wireless/ath/ath10k/qmi.h | 1 +
drivers/net/wireless/ath/ath10k/sdio.c | 17 +-
drivers/net/wireless/ath/ath10k/snoc.c | 15 +
drivers/net/wireless/ath/ath10k/swap.c | 4 +-
drivers/net/wireless/ath/ath10k/testmode.c | 17 +-
drivers/net/wireless/ath/ath10k/trace.c | 1 +
drivers/net/wireless/ath/ath10k/trace.h | 6 +-
drivers/net/wireless/ath/ath10k/usb.c | 2 +-
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 33 +-
drivers/net/wireless/ath/ath10k/wmi-tlv.h | 8 +-
drivers/net/wireless/ath/ath10k/wmi.h | 16 +-
drivers/net/wireless/ath/ath9k/recv.c | 6 +-
drivers/net/wireless/ath/carl9170/main.c | 9 +-
drivers/net/wireless/ath/carl9170/usb.c | 39 +-
drivers/net/wireless/ath/wil6210/cfg80211.c | 22 +-
drivers/net/wireless/ath/wil6210/debugfs.c | 168 +--
drivers/net/wireless/ath/wil6210/main.c | 19 +-
drivers/net/wireless/ath/wil6210/pcie_bus.c | 1 +
drivers/net/wireless/ath/wil6210/rx_reorder.c | 31 +-
drivers/net/wireless/ath/wil6210/txrx.c | 9 +-
drivers/net/wireless/ath/wil6210/txrx_edma.c | 16 +-
drivers/net/wireless/ath/wil6210/txrx_edma.h | 2 +-
drivers/net/wireless/ath/wil6210/wil6210.h | 6 +
drivers/net/wireless/ath/wil6210/wmi.c | 127 +-
drivers/net/wireless/ath/wil6210/wmi.h | 47 +-
drivers/net/wireless/broadcom/b43/dma.c | 69 +-
drivers/net/wireless/broadcom/b43legacy/dma.c | 57 +-
drivers/net/wireless/intel/iwlwifi/dvm/lib.c | 3 +-
drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 28 +-
drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 5 +-
.../net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 22 +
.../net/wireless/intel/iwlwifi/fw/api/location.h | 11 +-
drivers/net/wireless/intel/iwlwifi/fw/api/power.h | 12 +
drivers/net/wireless/intel/iwlwifi/fw/api/scan.h | 15 +
drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 427 ++++---
drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 133 +-
drivers/net/wireless/intel/iwlwifi/fw/error-dump.h | 111 +-
drivers/net/wireless/intel/iwlwifi/fw/file.h | 17 +-
drivers/net/wireless/intel/iwlwifi/fw/init.c | 7 +-
drivers/net/wireless/intel/iwlwifi/fw/runtime.h | 28 +-
drivers/net/wireless/intel/iwlwifi/fw/smem.c | 12 +-
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 33 +-
drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 35 +-
drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 75 +-
drivers/net/wireless/intel/iwlwifi/mvm/constants.h | 1 +
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 14 +-
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 66 +-
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 72 +-
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 16 +-
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 66 +-
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 12 +-
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 9 +
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 26 +-
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c | 25 +-
drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 12 +-
drivers/net/wireless/intel/iwlwifi/mvm/sta.h | 4 +
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 16 +-
drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 20 +-
.../wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c | 10 +-
.../net/wireless/intel/iwlwifi/pcie/ctxt-info.c | 2 +-
drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 29 +-
drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 68 +-
.../net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 11 +-
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 187 +--
drivers/net/wireless/marvell/mwifiex/11n.c | 53 +-
drivers/net/wireless/marvell/mwifiex/11n.h | 5 +-
drivers/net/wireless/marvell/mwifiex/11n_aggr.c | 26 +-
drivers/net/wireless/marvell/mwifiex/11n_aggr.h | 2 +-
.../net/wireless/marvell/mwifiex/11n_rxreorder.c | 125 +-
drivers/net/wireless/marvell/mwifiex/cfg80211.c | 35 +-
drivers/net/wireless/marvell/mwifiex/cmdevt.c | 76 +-
drivers/net/wireless/marvell/mwifiex/init.c | 32 +-
drivers/net/wireless/marvell/mwifiex/main.c | 29 +-
drivers/net/wireless/marvell/mwifiex/scan.c | 58 +-
drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 5 +-
drivers/net/wireless/marvell/mwifiex/sta_event.c | 10 +-
drivers/net/wireless/marvell/mwifiex/tdls.c | 68 +-
drivers/net/wireless/marvell/mwifiex/txrx.c | 5 +-
drivers/net/wireless/marvell/mwifiex/uap_txrx.c | 10 +-
drivers/net/wireless/marvell/mwifiex/usb.c | 10 +-
drivers/net/wireless/marvell/mwifiex/util.c | 15 +-
drivers/net/wireless/marvell/mwifiex/wmm.c | 109 +-
drivers/net/wireless/mediatek/mt76/dma.c | 1 +
drivers/net/wireless/mediatek/mt76/mac80211.c | 62 +-
drivers/net/wireless/mediatek/mt76/mt76.h | 23 +-
drivers/net/wireless/mediatek/mt76/mt7603/core.c | 2 +-
.../net/wireless/mediatek/mt76/mt7603/debugfs.c | 30 +
drivers/net/wireless/mediatek/mt76/mt7603/dma.c | 29 +-
drivers/net/wireless/mediatek/mt76/mt7603/eeprom.h | 2 +
drivers/net/wireless/mediatek/mt76/mt7603/init.c | 26 +-
drivers/net/wireless/mediatek/mt76/mt7603/mac.c | 191 +--
drivers/net/wireless/mediatek/mt76/mt7603/main.c | 8 +-
drivers/net/wireless/mediatek/mt76/mt7603/mcu.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h | 15 +-
drivers/net/wireless/mediatek/mt76/mt7603/regs.h | 6 +
drivers/net/wireless/mediatek/mt76/mt7615/dma.c | 23 +-
drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c | 97 +-
drivers/net/wireless/mediatek/mt76/mt7615/eeprom.h | 61 +
drivers/net/wireless/mediatek/mt76/mt7615/init.c | 77 +-
drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 85 +-
drivers/net/wireless/mediatek/mt76/mt7615/mac.h | 5 +
drivers/net/wireless/mediatek/mt76/mt7615/main.c | 52 +-
drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 1265 ++++++++++---------
drivers/net/wireless/mediatek/mt76/mt7615/mcu.h | 56 +-
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h | 16 +-
drivers/net/wireless/mediatek/mt76/mt7615/pci.c | 7 +-
drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 5 +-
drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | 13 +-
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x02.h | 1 -
.../net/wireless/mediatek/mt76/mt76x02_beacon.c | 4 +-
.../net/wireless/mediatek/mt76/mt76x02_debugfs.c | 10 +-
drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c | 18 +-
drivers/net/wireless/mediatek/mt76/mt76x02_dfs.h | 2 -
.../net/wireless/mediatek/mt76/mt76x02_eeprom.h | 1 +
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 106 +-
drivers/net/wireless/mediatek/mt76/mt76x02_mac.h | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 18 +-
drivers/net/wireless/mediatek/mt76/mt76x02_regs.h | 3 +
drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c | 9 +-
.../net/wireless/mediatek/mt76/mt76x02_usb_core.c | 11 +-
drivers/net/wireless/mediatek/mt76/mt76x2/init.c | 9 +-
.../net/wireless/mediatek/mt76/mt76x2/pci_main.c | 16 +-
.../net/wireless/mediatek/mt76/mt76x2/pci_phy.c | 8 +-
.../net/wireless/mediatek/mt76/mt76x2/usb_init.c | 2 +-
.../net/wireless/mediatek/mt76/mt76x2/usb_main.c | 23 +-
.../net/wireless/mediatek/mt76/mt76x2/usb_phy.c | 7 +-
drivers/net/wireless/mediatek/mt76/usb.c | 20 +-
drivers/net/wireless/realtek/rtw88/main.c | 26 +-
drivers/net/wireless/realtek/rtw88/main.h | 27 +-
drivers/net/wireless/realtek/rtw88/phy.c | 1298 +++++++++++---------
drivers/net/wireless/realtek/rtw88/phy.h | 18 +-
drivers/net/wireless/realtek/rtw88/regd.c | 69 +-
drivers/net/wireless/realtek/rtw88/regd.h | 4 +
.../net/wireless/realtek/rtw88/rtw8822c_table.c | 799 +++++++++++-
150 files changed, 5196 insertions(+), 2976 deletions(-)
^ permalink raw reply
* [PATCH net-next 0/4] bnxt_en: Add XDP_REDIRECT support.
From: Michael Chan @ 2019-07-06 7:36 UTC (permalink / raw)
To: davem, gospo; +Cc: netdev, hawk, ast
This patch series adds XDP_REDIRECT support by Andy Gospodarek.
Andy Gospodarek (3):
bnxt_en: rename some xdp functions
bnxt_en: optimized XDP_REDIRECT support
bnxt_en: add page_pool support
Michael Chan (1):
bnxt_en: Refactor __bnxt_xmit_xdp().
drivers/net/ethernet/broadcom/Kconfig | 1 +
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 65 +++++++++-
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 17 ++-
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 +-
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 144 +++++++++++++++++++---
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h | 7 +-
6 files changed, 208 insertions(+), 28 deletions(-)
--
2.5.1
^ permalink raw reply
* [PATCH net-next 1/4] bnxt_en: rename some xdp functions
From: Michael Chan @ 2019-07-06 7:36 UTC (permalink / raw)
To: davem, gospo; +Cc: netdev, hawk, ast
In-Reply-To: <1562398578-26020-1-git-send-email-michael.chan@broadcom.com>
From: Andy Gospodarek <gospo@broadcom.com>
Renaming bnxt_xmit_xdp to __bnxt_xmit_xdp to get ready for XDP_REDIRECT
support and reduce confusion/namespace collision.
Signed-off-by: Andy Gospodarek <gospo@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 +-
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 8 ++++----
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h | 4 ++--
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index a6c7baf..21a0431 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -2799,7 +2799,7 @@ static int bnxt_run_loopback(struct bnxt *bp)
dev_kfree_skb(skb);
return -EIO;
}
- bnxt_xmit_xdp(bp, txr, map, pkt_size, 0);
+ __bnxt_xmit_xdp(bp, txr, map, pkt_size, 0);
/* Sync BD data before updating doorbell */
wmb();
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index 0184ef6..4bc9595 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -19,8 +19,8 @@
#include "bnxt.h"
#include "bnxt_xdp.h"
-void bnxt_xmit_xdp(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
- dma_addr_t mapping, u32 len, u16 rx_prod)
+void __bnxt_xmit_xdp(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
+ dma_addr_t mapping, u32 len, u16 rx_prod)
{
struct bnxt_sw_tx_bd *tx_buf;
struct tx_bd *txbd;
@@ -132,8 +132,8 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
*event = BNXT_TX_EVENT;
dma_sync_single_for_device(&pdev->dev, mapping + offset, *len,
bp->rx_dir);
- bnxt_xmit_xdp(bp, txr, mapping + offset, *len,
- NEXT_RX(rxr->rx_prod));
+ __bnxt_xmit_xdp(bp, txr, mapping + offset, *len,
+ NEXT_RX(rxr->rx_prod));
bnxt_reuse_rx_data(rxr, cons, page);
return true;
default:
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
index 414b748..b36087b 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
@@ -10,8 +10,8 @@
#ifndef BNXT_XDP_H
#define BNXT_XDP_H
-void bnxt_xmit_xdp(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
- dma_addr_t mapping, u32 len, u16 rx_prod);
+void __bnxt_xmit_xdp(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
+ dma_addr_t mapping, u32 len, u16 rx_prod);
void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts);
bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
struct page *page, u8 **data_ptr, unsigned int *len,
--
2.5.1
^ permalink raw reply related
* [PATCH net-next 2/4] bnxt_en: Refactor __bnxt_xmit_xdp().
From: Michael Chan @ 2019-07-06 7:36 UTC (permalink / raw)
To: davem, gospo; +Cc: netdev, hawk, ast
In-Reply-To: <1562398578-26020-1-git-send-email-michael.chan@broadcom.com>
__bnxt_xmit_xdp() is used by XDP_TX and ethtool loopback packet transmit.
Refactor it so that it can be re-used by the XDP_REDIRECT logic.
Restructure the TX interrupt handler logic to cleanly separate XDP_TX
logic in preparation for XDP_REDIRECT.
Acked-by: Andy Gospodarek <gospo@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 +
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 +-
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 33 ++++++++++++++++-------
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h | 5 ++--
4 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 4b3ae92..bf12cfc 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -596,6 +596,7 @@ struct bnxt_sw_tx_bd {
DEFINE_DMA_UNMAP_ADDR(mapping);
u8 is_gso;
u8 is_push;
+ u8 action;
union {
unsigned short nr_frags;
u16 rx_prod;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index 21a0431..a0f3277 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -2799,7 +2799,7 @@ static int bnxt_run_loopback(struct bnxt *bp)
dev_kfree_skb(skb);
return -EIO;
}
- __bnxt_xmit_xdp(bp, txr, map, pkt_size, 0);
+ bnxt_xmit_bd(bp, txr, map, pkt_size);
/* Sync BD data before updating doorbell */
wmb();
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index 4bc9595..41e232e 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -19,8 +19,9 @@
#include "bnxt.h"
#include "bnxt_xdp.h"
-void __bnxt_xmit_xdp(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
- dma_addr_t mapping, u32 len, u16 rx_prod)
+struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,
+ struct bnxt_tx_ring_info *txr,
+ dma_addr_t mapping, u32 len)
{
struct bnxt_sw_tx_bd *tx_buf;
struct tx_bd *txbd;
@@ -29,7 +30,6 @@ void __bnxt_xmit_xdp(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
prod = txr->tx_prod;
tx_buf = &txr->tx_buf_ring[prod];
- tx_buf->rx_prod = rx_prod;
txbd = &txr->tx_desc_ring[TX_RING(prod)][TX_IDX(prod)];
flags = (len << TX_BD_LEN_SHIFT) | (1 << TX_BD_FLAGS_BD_CNT_SHIFT) |
@@ -40,30 +40,43 @@ void __bnxt_xmit_xdp(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
prod = NEXT_TX(prod);
txr->tx_prod = prod;
+ return tx_buf;
+}
+
+static void __bnxt_xmit_xdp(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
+ dma_addr_t mapping, u32 len, u16 rx_prod)
+{
+ struct bnxt_sw_tx_bd *tx_buf;
+
+ tx_buf = bnxt_xmit_bd(bp, txr, mapping, len);
+ tx_buf->rx_prod = rx_prod;
+ tx_buf->action = XDP_TX;
}
void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
{
struct bnxt_tx_ring_info *txr = bnapi->tx_ring;
struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
+ bool rx_doorbell_needed = false;
struct bnxt_sw_tx_bd *tx_buf;
u16 tx_cons = txr->tx_cons;
u16 last_tx_cons = tx_cons;
- u16 rx_prod;
int i;
for (i = 0; i < nr_pkts; i++) {
- last_tx_cons = tx_cons;
+ tx_buf = &txr->tx_buf_ring[tx_cons];
+
+ if (tx_buf->action == XDP_TX) {
+ rx_doorbell_needed = true;
+ last_tx_cons = tx_cons;
+ }
tx_cons = NEXT_TX(tx_cons);
}
txr->tx_cons = tx_cons;
- if (bnxt_tx_avail(bp, txr) == bp->tx_ring_size) {
- rx_prod = rxr->rx_prod;
- } else {
+ if (rx_doorbell_needed) {
tx_buf = &txr->tx_buf_ring[last_tx_cons];
- rx_prod = tx_buf->rx_prod;
+ bnxt_db_write(bp, &rxr->rx_db, tx_buf->rx_prod);
}
- bnxt_db_write(bp, &rxr->rx_db, rx_prod);
}
/* returns the following:
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
index b36087b..20e470c 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
@@ -10,8 +10,9 @@
#ifndef BNXT_XDP_H
#define BNXT_XDP_H
-void __bnxt_xmit_xdp(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
- dma_addr_t mapping, u32 len, u16 rx_prod);
+struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,
+ struct bnxt_tx_ring_info *txr,
+ dma_addr_t mapping, u32 len);
void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts);
bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
struct page *page, u8 **data_ptr, unsigned int *len,
--
2.5.1
^ permalink raw reply related
* [PATCH net-next 3/4] bnxt_en: optimized XDP_REDIRECT support
From: Michael Chan @ 2019-07-06 7:36 UTC (permalink / raw)
To: davem, gospo; +Cc: netdev, hawk, ast
In-Reply-To: <1562398578-26020-1-git-send-email-michael.chan@broadcom.com>
From: Andy Gospodarek <gospo@broadcom.com>
This adds basic support for XDP_REDIRECT in the bnxt_en driver. Next
patch adds the more optimized page pool support.
Signed-off-by: Andy Gospodarek <gospo@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 27 ++++++-
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 13 +++-
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 108 ++++++++++++++++++++++++--
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h | 2 +
4 files changed, 140 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index b7b6227..d8f0846 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -1989,6 +1989,9 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
}
}
+ if (event & BNXT_REDIRECT_EVENT)
+ xdp_do_flush_map();
+
if (event & BNXT_TX_EVENT) {
struct bnxt_tx_ring_info *txr = bnapi->tx_ring;
u16 prod = txr->tx_prod;
@@ -2254,9 +2257,23 @@ static void bnxt_free_tx_skbs(struct bnxt *bp)
for (j = 0; j < max_idx;) {
struct bnxt_sw_tx_bd *tx_buf = &txr->tx_buf_ring[j];
- struct sk_buff *skb = tx_buf->skb;
+ struct sk_buff *skb;
int k, last;
+ if (i < bp->tx_nr_rings_xdp &&
+ tx_buf->action == XDP_REDIRECT) {
+ dma_unmap_single(&pdev->dev,
+ dma_unmap_addr(tx_buf, mapping),
+ dma_unmap_len(tx_buf, len),
+ PCI_DMA_TODEVICE);
+ xdp_return_frame(tx_buf->xdpf);
+ tx_buf->action = 0;
+ tx_buf->xdpf = NULL;
+ j++;
+ continue;
+ }
+
+ skb = tx_buf->skb;
if (!skb) {
j++;
continue;
@@ -2517,6 +2534,13 @@ static int bnxt_alloc_rx_rings(struct bnxt *bp)
if (rc < 0)
return rc;
+ rc = xdp_rxq_info_reg_mem_model(&rxr->xdp_rxq,
+ MEM_TYPE_PAGE_SHARED, NULL);
+ if (rc) {
+ xdp_rxq_info_unreg(&rxr->xdp_rxq);
+ return rc;
+ }
+
rc = bnxt_alloc_ring(bp, &ring->ring_mem);
if (rc)
return rc;
@@ -10233,6 +10257,7 @@ static const struct net_device_ops bnxt_netdev_ops = {
.ndo_udp_tunnel_add = bnxt_udp_tunnel_add,
.ndo_udp_tunnel_del = bnxt_udp_tunnel_del,
.ndo_bpf = bnxt_xdp,
+ .ndo_xdp_xmit = bnxt_xdp_xmit,
.ndo_bridge_getlink = bnxt_bridge_getlink,
.ndo_bridge_setlink = bnxt_bridge_setlink,
.ndo_get_devlink_port = bnxt_get_devlink_port,
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index bf12cfc..8ac51fa 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -587,13 +587,18 @@ struct nqe_cn {
#define BNXT_HWRM_CHNL_CHIMP 0
#define BNXT_HWRM_CHNL_KONG 1
-#define BNXT_RX_EVENT 1
-#define BNXT_AGG_EVENT 2
-#define BNXT_TX_EVENT 4
+#define BNXT_RX_EVENT 1
+#define BNXT_AGG_EVENT 2
+#define BNXT_TX_EVENT 4
+#define BNXT_REDIRECT_EVENT 8
struct bnxt_sw_tx_bd {
- struct sk_buff *skb;
+ union {
+ struct sk_buff *skb;
+ struct xdp_frame *xdpf;
+ };
DEFINE_DMA_UNMAP_ADDR(mapping);
+ DEFINE_DMA_UNMAP_LEN(len);
u8 is_gso;
u8 is_push;
u8 action;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index 41e232e..12489d2 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -53,6 +53,20 @@ static void __bnxt_xmit_xdp(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
tx_buf->action = XDP_TX;
}
+static void __bnxt_xmit_xdp_redirect(struct bnxt *bp,
+ struct bnxt_tx_ring_info *txr,
+ dma_addr_t mapping, u32 len,
+ struct xdp_frame *xdpf)
+{
+ struct bnxt_sw_tx_bd *tx_buf;
+
+ tx_buf = bnxt_xmit_bd(bp, txr, mapping, len);
+ tx_buf->action = XDP_REDIRECT;
+ tx_buf->xdpf = xdpf;
+ dma_unmap_addr_set(tx_buf, mapping, mapping);
+ dma_unmap_len_set(tx_buf, len, 0);
+}
+
void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
{
struct bnxt_tx_ring_info *txr = bnapi->tx_ring;
@@ -66,7 +80,17 @@ void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
for (i = 0; i < nr_pkts; i++) {
tx_buf = &txr->tx_buf_ring[tx_cons];
- if (tx_buf->action == XDP_TX) {
+ if (tx_buf->action == XDP_REDIRECT) {
+ struct pci_dev *pdev = bp->pdev;
+
+ dma_unmap_single(&pdev->dev,
+ dma_unmap_addr(tx_buf, mapping),
+ dma_unmap_len(tx_buf, len),
+ PCI_DMA_TODEVICE);
+ xdp_return_frame(tx_buf->xdpf);
+ tx_buf->action = 0;
+ tx_buf->xdpf = NULL;
+ } else if (tx_buf->action == XDP_TX) {
rx_doorbell_needed = true;
last_tx_cons = tx_cons;
}
@@ -101,19 +125,19 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
return false;
pdev = bp->pdev;
- txr = rxr->bnapi->tx_ring;
rx_buf = &rxr->rx_buf_ring[cons];
offset = bp->rx_offset;
+ mapping = rx_buf->mapping - bp->rx_dma_offset;
+ dma_sync_single_for_cpu(&pdev->dev, mapping + offset, *len, bp->rx_dir);
+
+ txr = rxr->bnapi->tx_ring;
xdp.data_hard_start = *data_ptr - offset;
xdp.data = *data_ptr;
xdp_set_data_meta_invalid(&xdp);
xdp.data_end = *data_ptr + *len;
xdp.rxq = &rxr->xdp_rxq;
orig_data = xdp.data;
- mapping = rx_buf->mapping - bp->rx_dma_offset;
-
- dma_sync_single_for_cpu(&pdev->dev, mapping + offset, *len, bp->rx_dir);
rcu_read_lock();
act = bpf_prog_run_xdp(xdp_prog, &xdp);
@@ -149,6 +173,30 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
NEXT_RX(rxr->rx_prod));
bnxt_reuse_rx_data(rxr, cons, page);
return true;
+ case XDP_REDIRECT:
+ /* if we are calling this here then we know that the
+ * redirect is coming from a frame received by the
+ * bnxt_en driver.
+ */
+ dma_unmap_page_attrs(&pdev->dev, mapping,
+ PAGE_SIZE, bp->rx_dir,
+ DMA_ATTR_WEAK_ORDERING);
+
+ /* if we are unable to allocate a new buffer, abort and reuse */
+ if (bnxt_alloc_rx_data(bp, rxr, rxr->rx_prod, GFP_ATOMIC)) {
+ trace_xdp_exception(bp->dev, xdp_prog, act);
+ bnxt_reuse_rx_data(rxr, cons, page);
+ return true;
+ }
+
+ if (xdp_do_redirect(bp->dev, &xdp, xdp_prog)) {
+ trace_xdp_exception(bp->dev, xdp_prog, act);
+ __free_page(page);
+ return true;
+ }
+
+ *event |= BNXT_REDIRECT_EVENT;
+ break;
default:
bpf_warn_invalid_xdp_action(act);
/* Fall thru */
@@ -162,6 +210,56 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
return true;
}
+int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
+ struct xdp_frame **frames, u32 flags)
+{
+ struct bnxt *bp = netdev_priv(dev);
+ struct bpf_prog *xdp_prog = READ_ONCE(bp->xdp_prog);
+ struct pci_dev *pdev = bp->pdev;
+ struct bnxt_tx_ring_info *txr;
+ dma_addr_t mapping;
+ int drops = 0;
+ int ring;
+ int i;
+
+ if (!test_bit(BNXT_STATE_OPEN, &bp->state) ||
+ !bp->tx_nr_rings_xdp ||
+ !xdp_prog)
+ return -EINVAL;
+
+ ring = smp_processor_id() % bp->tx_nr_rings_xdp;
+ txr = &bp->tx_ring[ring];
+
+ for (i = 0; i < num_frames; i++) {
+ struct xdp_frame *xdp = frames[i];
+
+ if (!txr || !bnxt_tx_avail(bp, txr) ||
+ !(bp->bnapi[ring]->flags & BNXT_NAPI_FLAG_XDP)) {
+ xdp_return_frame_rx_napi(xdp);
+ drops++;
+ continue;
+ }
+
+ mapping = dma_map_single(&pdev->dev, xdp->data, xdp->len,
+ DMA_TO_DEVICE);
+
+ if (dma_mapping_error(&pdev->dev, mapping)) {
+ xdp_return_frame_rx_napi(xdp);
+ drops++;
+ continue;
+ }
+ __bnxt_xmit_xdp_redirect(bp, txr, mapping, xdp->len, xdp);
+ }
+
+ if (flags & XDP_XMIT_FLUSH) {
+ /* Sync BD data before updating doorbell */
+ wmb();
+ bnxt_db_write(bp, &txr->tx_db, txr->tx_prod);
+ }
+
+ return num_frames - drops;
+}
+
/* Under rtnl_lock */
static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
{
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
index 20e470c..0df40c3 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
@@ -18,5 +18,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
struct page *page, u8 **data_ptr, unsigned int *len,
u8 *event);
int bnxt_xdp(struct net_device *dev, struct netdev_bpf *xdp);
+int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
+ struct xdp_frame **frames, u32 flags);
#endif
--
2.5.1
^ permalink raw reply related
* [PATCH net-next 4/4] bnxt_en: add page_pool support
From: Michael Chan @ 2019-07-06 7:36 UTC (permalink / raw)
To: davem, gospo; +Cc: netdev, hawk, ast
In-Reply-To: <1562398578-26020-1-git-send-email-michael.chan@broadcom.com>
From: Andy Gospodarek <gospo@broadcom.com>
This removes contention over page allocation for XDP_REDIRECT actions by
adding page_pool support per queue for the driver. The performance for
XDP_REDIRECT actions scales linearly with the number of cores performing
redirect actions when using the page pools instead of the standard page
allocator.
Signed-off-by: Andy Gospodarek <gospo@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
drivers/net/ethernet/broadcom/Kconfig | 1 +
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 40 +++++++++++++++++++++++----
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 3 ++
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 3 +-
4 files changed, 41 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
index 2e4a8c7..e9017ca 100644
--- a/drivers/net/ethernet/broadcom/Kconfig
+++ b/drivers/net/ethernet/broadcom/Kconfig
@@ -199,6 +199,7 @@ config BNXT
select FW_LOADER
select LIBCRC32C
select NET_DEVLINK
+ select PAGE_POOL
---help---
This driver supports Broadcom NetXtreme-C/E 10/25/40/50 gigabit
Ethernet cards. To compile this driver as a module, choose M here:
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index d8f0846..b6777e5 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -54,6 +54,7 @@
#include <net/pkt_cls.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
+#include <net/page_pool.h>
#include "bnxt_hsi.h"
#include "bnxt.h"
@@ -668,19 +669,20 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
}
static struct page *__bnxt_alloc_rx_page(struct bnxt *bp, dma_addr_t *mapping,
+ struct bnxt_rx_ring_info *rxr,
gfp_t gfp)
{
struct device *dev = &bp->pdev->dev;
struct page *page;
- page = alloc_page(gfp);
+ page = page_pool_dev_alloc_pages(rxr->page_pool);
if (!page)
return NULL;
*mapping = dma_map_page_attrs(dev, page, 0, PAGE_SIZE, bp->rx_dir,
DMA_ATTR_WEAK_ORDERING);
if (dma_mapping_error(dev, *mapping)) {
- __free_page(page);
+ page_pool_recycle_direct(rxr->page_pool, page);
return NULL;
}
*mapping += bp->rx_dma_offset;
@@ -716,7 +718,8 @@ int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
dma_addr_t mapping;
if (BNXT_RX_PAGE_MODE(bp)) {
- struct page *page = __bnxt_alloc_rx_page(bp, &mapping, gfp);
+ struct page *page =
+ __bnxt_alloc_rx_page(bp, &mapping, rxr, gfp);
if (!page)
return -ENOMEM;
@@ -2360,7 +2363,7 @@ static void bnxt_free_rx_skbs(struct bnxt *bp)
dma_unmap_page_attrs(&pdev->dev, mapping,
PAGE_SIZE, bp->rx_dir,
DMA_ATTR_WEAK_ORDERING);
- __free_page(data);
+ page_pool_recycle_direct(rxr->page_pool, data);
} else {
dma_unmap_single_attrs(&pdev->dev, mapping,
bp->rx_buf_use_size,
@@ -2497,6 +2500,8 @@ static void bnxt_free_rx_rings(struct bnxt *bp)
if (xdp_rxq_info_is_reg(&rxr->xdp_rxq))
xdp_rxq_info_unreg(&rxr->xdp_rxq);
+ rxr->page_pool = NULL;
+
kfree(rxr->rx_tpa);
rxr->rx_tpa = NULL;
@@ -2511,6 +2516,26 @@ static void bnxt_free_rx_rings(struct bnxt *bp)
}
}
+static int bnxt_alloc_rx_page_pool(struct bnxt *bp,
+ struct bnxt_rx_ring_info *rxr)
+{
+ struct page_pool_params pp = { 0 };
+
+ pp.pool_size = bp->rx_ring_size;
+ pp.nid = dev_to_node(&bp->pdev->dev);
+ pp.dev = &bp->pdev->dev;
+ pp.dma_dir = DMA_BIDIRECTIONAL;
+
+ rxr->page_pool = page_pool_create(&pp);
+ if (IS_ERR(rxr->page_pool)) {
+ int err = PTR_ERR(rxr->page_pool);
+
+ rxr->page_pool = NULL;
+ return err;
+ }
+ return 0;
+}
+
static int bnxt_alloc_rx_rings(struct bnxt *bp)
{
int i, rc, agg_rings = 0, tpa_rings = 0;
@@ -2530,12 +2555,17 @@ static int bnxt_alloc_rx_rings(struct bnxt *bp)
ring = &rxr->rx_ring_struct;
+ rc = bnxt_alloc_rx_page_pool(bp, rxr);
+ if (rc)
+ return rc;
+
rc = xdp_rxq_info_reg(&rxr->xdp_rxq, bp->dev, i);
if (rc < 0)
return rc;
rc = xdp_rxq_info_reg_mem_model(&rxr->xdp_rxq,
- MEM_TYPE_PAGE_SHARED, NULL);
+ MEM_TYPE_PAGE_POOL,
+ rxr->page_pool);
if (rc) {
xdp_rxq_info_unreg(&rxr->xdp_rxq);
return rc;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 8ac51fa..16694b7 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -26,6 +26,8 @@
#include <net/xdp.h>
#include <linux/dim.h>
+struct page_pool;
+
struct tx_bd {
__le32 tx_bd_len_flags_type;
#define TX_BD_TYPE (0x3f << 0)
@@ -799,6 +801,7 @@ struct bnxt_rx_ring_info {
struct bnxt_ring_struct rx_ring_struct;
struct bnxt_ring_struct rx_agg_ring_struct;
struct xdp_rxq_info xdp_rxq;
+ struct page_pool *page_pool;
};
struct bnxt_cp_ring_info {
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index 12489d2..c6f6f20 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -15,6 +15,7 @@
#include <linux/bpf.h>
#include <linux/bpf_trace.h>
#include <linux/filter.h>
+#include <net/page_pool.h>
#include "bnxt_hsi.h"
#include "bnxt.h"
#include "bnxt_xdp.h"
@@ -191,7 +192,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
if (xdp_do_redirect(bp->dev, &xdp, xdp_prog)) {
trace_xdp_exception(bp->dev, xdp_prog, act);
- __free_page(page);
+ page_pool_recycle_direct(rxr->page_pool, page);
return true;
}
--
2.5.1
^ permalink raw reply related
* Re: [net-next 1/3] ice: Initialize and register platform device to provide RDMA
From: Greg KH @ 2019-07-06 8:25 UTC (permalink / raw)
To: Saleem, Shiraz
Cc: Jason Gunthorpe, Kirsher, Jeffrey T, davem@davemloft.net,
dledford@redhat.com, Nguyen, Anthony L, netdev@vger.kernel.org,
linux-rdma@vger.kernel.org, nhorman@redhat.com,
sassmann@redhat.com, poswald@suse.com, Ismail, Mustafa,
Ertman, David M, Bowers, AndrewX
In-Reply-To: <9DD61F30A802C4429A01CA4200E302A7A684DA23@fmsmsx124.amr.corp.intel.com>
On Fri, Jul 05, 2019 at 04:33:07PM +0000, Saleem, Shiraz wrote:
> > Subject: Re: [net-next 1/3] ice: Initialize and register platform device to provide
> > RDMA
> >
> > On Thu, Jul 04, 2019 at 12:48:29PM +0000, Jason Gunthorpe wrote:
> > > On Thu, Jul 04, 2019 at 02:42:47PM +0200, Greg KH wrote:
> > > > On Thu, Jul 04, 2019 at 12:37:33PM +0000, Jason Gunthorpe wrote:
> > > > > On Thu, Jul 04, 2019 at 02:29:50PM +0200, Greg KH wrote:
> > > > > > On Thu, Jul 04, 2019 at 12:16:41PM +0000, Jason Gunthorpe wrote:
> > > > > > > On Wed, Jul 03, 2019 at 07:12:50PM -0700, Jeff Kirsher wrote:
> > > > > > > > From: Tony Nguyen <anthony.l.nguyen@intel.com>
> > > > > > > >
> > > > > > > > The RDMA block does not advertise on the PCI bus or any other bus.
> > > > > > > > Thus the ice driver needs to provide access to the RDMA
> > > > > > > > hardware block via a virtual bus; utilize the platform bus to provide this
> > access.
> > > > > > > >
> > > > > > > > This patch initializes the driver to support RDMA as well as
> > > > > > > > creates and registers a platform device for the RDMA driver
> > > > > > > > to register to. At this point the driver is fully
> > > > > > > > initialized to register a platform driver, however, can not
> > > > > > > > yet register as the ops have not been implemented.
> > > > > > >
> > > > > > > I think you need Greg's ack on all this driver stuff -
> > > > > > > particularly that a platform_device is OK.
> > > > > >
> > > > > > A platform_device is almost NEVER ok.
> > > > > >
> > > > > > Don't abuse it, make a real device on a real bus. If you don't
> > > > > > have a real bus and just need to create a device to hang other
> > > > > > things off of, then use the virtual one, that's what it is there for.
> > > > >
> > > > > Ideally I'd like to see all the RDMA drivers that connect to
> > > > > ethernet drivers use some similar scheme.
> > > >
> > > > Why? They should be attached to a "real" device, why make any up?
> > >
> > > ? A "real" device, like struct pci_device, can only bind to one
> > > driver. How can we bind it concurrently to net, rdma, scsi, etc?
> >
> > MFD was designed for this very problem.
> >
> > > > > This is for a PCI device that plugs into multiple subsystems in
> > > > > the kernel, ie it has net driver functionality, rdma
> > > > > functionality, some even have SCSI functionality
> > > >
> > > > Sounds like a MFD device, why aren't you using that functionality
> > > > instead?
> > >
> > > This was also my advice, but in another email Jeff says:
> > >
> > > MFD architecture was also considered, and we selected the simpler
> > > platform model. Supporting a MFD architecture would require an
> > > additional MFD core driver, individual platform netdev, RDMA function
> > > drivers, and stripping a large portion of the netdev drivers into
> > > MFD core. The sub-devices registered by MFD core for function
> > > drivers are indeed platform devices.
> >
> > So, "mfd is too hard, let's abuse a platform device" is ok?
> >
> > People have been wanting to do MFD drivers for PCI devices for a long time, it's
> > about time someone actually did the work for it, I bet it will not be all that complex
> > if tiny embedded drivers can do it :)
> >
> Hi Greg - Thanks for your feedback!
>
> We currently have 2 PCI function netdev drivers in the kernel (i40e & ice) that support devices (x722 & e810)
> which are RDMA capable. Our objective is to add a single unified RDMA driver
> (as this a subsystem specific requirement) which needs to access HW resources from the
> netdev PF drivers. Attaching platform devices from the netdev drivers to the platform bus
> and having a single RDMA platform driver bind to them and access these resources seemed
> like a simple approach to realize our objective. But seems like attaching platform devices is
> wrong. I would like to understand why.
Because that is NOT what a platform device is for.
It was originally created for those types of devices that live on the
"platform" bus, i.e. things that are hard-wired and you just "know" are
in your system because they are located at specific locations. We used
to generate them from board files, and then when we got DT, we create
them from the resources that DT says where the locations of the devices
are.
They are NOT to be abused and used whenever someone wants to put them
somewhere in the "middle" of the device tree because they feel like they
are easier to use instead of creating a real bus and drivers.
Yes, they do get abused, and I need to sweep the tree again and fix up
all of the places where this has crept back in. But now that I know you
are thinking of doing this, I'll keep saying to NOT do it for your use
case either :)
> Are platform sub devices only to be added from an MFD core driver? I
> am also wondering if MFD arch. would allow for realizing a single
> RDMA driver and whether we need an MFD core driver for each device,
> x722 & e810 or whether it can be a single driver.
I do not know the details of how MFD works, please ask those developers
for specifics. If MFD doesn't work, then create a tiny virtual bus and
make sub-devices out of that. If you need a "generic" way to do this
for PCI devices, then please create that as you are not the only one
that keeps wanting this, as for some reason PCI hardware vendors don't
like dividing up their devices in ways that would have made it much
simpler to create individual devices (probably saves some gates and
firmware complexity on the device).
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH bpf-next 3/3] xdp: Add devmap_hash map type for looking up devices by hashed index
From: Toke Høiland-Jørgensen @ 2019-07-06 8:41 UTC (permalink / raw)
To: Y Song
Cc: Daniel Borkmann, Alexei Starovoitov, netdev, David Miller,
Jesper Dangaard Brouer, Jakub Kicinski, Björn Töpel
In-Reply-To: <CAH3MdRVHnG+cbHUmwFpkjdtBMVOVasoekxKHKn_upQuDxe5v7Q@mail.gmail.com>
Y Song <ys114321@gmail.com> writes:
> On Fri, Jul 5, 2019 at 11:14 AM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>>
>> From: Toke Høiland-Jørgensen <toke@redhat.com>
>>
>> A common pattern when using xdp_redirect_map() is to create a device map
>> where the lookup key is simply ifindex. Because device maps are arrays,
>> this leaves holes in the map, and the map has to be sized to fit the
>> largest ifindex, regardless of how many devices actually are actually
>> needed in the map.
>>
>> This patch adds a second type of device map where the key is looked up
>> using a hashmap, instead of being used as an array index. This allows maps
>> to be densely packed, so they can be smaller.
>>
>> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
>> ---
>> include/linux/bpf.h | 7 +
>> include/linux/bpf_types.h | 1
>> include/trace/events/xdp.h | 3
>> include/uapi/linux/bpf.h | 7 +
>> kernel/bpf/devmap.c | 192 +++++++++++++++++++++++++++++++
>> kernel/bpf/verifier.c | 2
>> net/core/filter.c | 9 +
>> tools/bpf/bpftool/map.c | 1
>> tools/include/uapi/linux/bpf.h | 7 +
>> tools/lib/bpf/libbpf_probes.c | 1
>> tools/testing/selftests/bpf/test_maps.c | 16 +++
>> 11 files changed, 237 insertions(+), 9 deletions(-)
>
> Could you break this patch into multiple commits for easy backporting
> and easy syncing to libbpf repo?
> For example, you can break it into 4 patches:
> . kernel patch
> . sync uapi bpf.h
> . tools/lib/bpf/libbpf_probes.c
> . other tools changes.
Sure, I'll send a v2.
-Toke
^ permalink raw reply
* [PATCH bpf-next v2 1/6] include/bpf.h: Remove map_insert_ctx() stubs
From: Toke Høiland-Jørgensen @ 2019-07-06 8:47 UTC (permalink / raw)
To: Daniel Borkmann
Cc: Alexei Starovoitov, netdev, David Miller, Jesper Dangaard Brouer,
Jakub Kicinski, Björn Töpel
In-Reply-To: <156240283550.10171.1727292671613975908.stgit@alrua-x1>
From: Toke Høiland-Jørgensen <toke@redhat.com>
When we changed the device and CPU maps to use linked lists instead of
bitmaps, we also removed the need for the map_insert_ctx() helpers to keep
track of the bitmaps inside each map. However, it seems I forgot to remove
the function definitions stubs, so remove those here.
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
include/linux/bpf.h | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 18f4cc2c6acd..bfdb54dd2ad1 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -713,7 +713,6 @@ struct xdp_buff;
struct sk_buff;
struct bpf_dtab_netdev *__dev_map_lookup_elem(struct bpf_map *map, u32 key);
-void __dev_map_insert_ctx(struct bpf_map *map, u32 index);
void __dev_map_flush(struct bpf_map *map);
int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_buff *xdp,
struct net_device *dev_rx);
@@ -721,7 +720,6 @@ int dev_map_generic_redirect(struct bpf_dtab_netdev *dst, struct sk_buff *skb,
struct bpf_prog *xdp_prog);
struct bpf_cpu_map_entry *__cpu_map_lookup_elem(struct bpf_map *map, u32 key);
-void __cpu_map_insert_ctx(struct bpf_map *map, u32 index);
void __cpu_map_flush(struct bpf_map *map);
int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_buff *xdp,
struct net_device *dev_rx);
@@ -801,10 +799,6 @@ static inline struct net_device *__dev_map_lookup_elem(struct bpf_map *map,
return NULL;
}
-static inline void __dev_map_insert_ctx(struct bpf_map *map, u32 index)
-{
-}
-
static inline void __dev_map_flush(struct bpf_map *map)
{
}
@@ -834,10 +828,6 @@ struct bpf_cpu_map_entry *__cpu_map_lookup_elem(struct bpf_map *map, u32 key)
return NULL;
}
-static inline void __cpu_map_insert_ctx(struct bpf_map *map, u32 index)
-{
-}
-
static inline void __cpu_map_flush(struct bpf_map *map)
{
}
^ permalink raw reply related
* [PATCH bpf-next v2 3/6] uapi/bpf: Add new devmap_hash type
From: Toke Høiland-Jørgensen @ 2019-07-06 8:47 UTC (permalink / raw)
To: Daniel Borkmann
Cc: Alexei Starovoitov, netdev, David Miller, Jesper Dangaard Brouer,
Jakub Kicinski, Björn Töpel
In-Reply-To: <156240283550.10171.1727292671613975908.stgit@alrua-x1>
From: Toke Høiland-Jørgensen <toke@redhat.com>
This adds the BPF_MAP_TYPE_DEVMAP_HASH type to the uapi bpf.h header, for
use in the subsequent patch adding the support to the kernel.
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
include/uapi/linux/bpf.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index ead27aebf491..7a0301407f3a 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -134,6 +134,7 @@ enum bpf_map_type {
BPF_MAP_TYPE_QUEUE,
BPF_MAP_TYPE_STACK,
BPF_MAP_TYPE_SK_STORAGE,
+ BPF_MAP_TYPE_DEVMAP_HASH,
};
/* Note that tracing related programs such as
^ permalink raw reply related
* [PATCH bpf-next v2 5/6] tools/libbpf_probes: Add new devmap_hash type
From: Toke Høiland-Jørgensen @ 2019-07-06 8:47 UTC (permalink / raw)
To: Daniel Borkmann
Cc: Alexei Starovoitov, netdev, David Miller, Jesper Dangaard Brouer,
Jakub Kicinski, Björn Töpel
In-Reply-To: <156240283550.10171.1727292671613975908.stgit@alrua-x1>
From: Toke Høiland-Jørgensen <toke@redhat.com>
This adds the definition for BPF_MAP_TYPE_DEVMAP_HASH to libbpf_probes.c in
tools/lib/bpf.
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
tools/lib/bpf/libbpf_probes.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
index ace1a0708d99..4b0b0364f5fc 100644
--- a/tools/lib/bpf/libbpf_probes.c
+++ b/tools/lib/bpf/libbpf_probes.c
@@ -244,6 +244,7 @@ bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex)
case BPF_MAP_TYPE_ARRAY_OF_MAPS:
case BPF_MAP_TYPE_HASH_OF_MAPS:
case BPF_MAP_TYPE_DEVMAP:
+ case BPF_MAP_TYPE_DEVMAP_HASH:
case BPF_MAP_TYPE_SOCKMAP:
case BPF_MAP_TYPE_CPUMAP:
case BPF_MAP_TYPE_XSKMAP:
^ permalink raw reply related
* [PATCH bpf-next v2 2/6] xdp: Refactor devmap allocation code for reuse
From: Toke Høiland-Jørgensen @ 2019-07-06 8:47 UTC (permalink / raw)
To: Daniel Borkmann
Cc: Alexei Starovoitov, netdev, David Miller, Jesper Dangaard Brouer,
Jakub Kicinski, Björn Töpel
In-Reply-To: <156240283550.10171.1727292671613975908.stgit@alrua-x1>
From: Toke Høiland-Jørgensen <toke@redhat.com>
The subsequent patch to add a new devmap sub-type can re-use much of the
initialisation and allocation code, so refactor it into separate functions.
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
kernel/bpf/devmap.c | 137 +++++++++++++++++++++++++++++++--------------------
1 file changed, 84 insertions(+), 53 deletions(-)
diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
index d83cf8ccc872..a2fe16362129 100644
--- a/kernel/bpf/devmap.c
+++ b/kernel/bpf/devmap.c
@@ -60,7 +60,7 @@ struct xdp_bulk_queue {
struct bpf_dtab_netdev {
struct net_device *dev; /* must be first member, due to tracepoint */
struct bpf_dtab *dtab;
- unsigned int bit;
+ unsigned int idx; /* keep track of map index for tracepoint */
struct xdp_bulk_queue __percpu *bulkq;
struct rcu_head rcu;
};
@@ -75,28 +75,22 @@ struct bpf_dtab {
static DEFINE_SPINLOCK(dev_map_lock);
static LIST_HEAD(dev_map_list);
-static struct bpf_map *dev_map_alloc(union bpf_attr *attr)
+static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr,
+ bool check_memlock)
{
- struct bpf_dtab *dtab;
int err, cpu;
u64 cost;
- if (!capable(CAP_NET_ADMIN))
- return ERR_PTR(-EPERM);
-
/* check sanity of attributes */
if (attr->max_entries == 0 || attr->key_size != 4 ||
attr->value_size != 4 || attr->map_flags & ~DEV_CREATE_FLAG_MASK)
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
/* Lookup returns a pointer straight to dev->ifindex, so make sure the
* verifier prevents writes from the BPF side
*/
attr->map_flags |= BPF_F_RDONLY_PROG;
- dtab = kzalloc(sizeof(*dtab), GFP_USER);
- if (!dtab)
- return ERR_PTR(-ENOMEM);
bpf_map_init_from_attr(&dtab->map, attr);
@@ -107,9 +101,7 @@ static struct bpf_map *dev_map_alloc(union bpf_attr *attr)
/* if map size is larger than memlock limit, reject it */
err = bpf_map_charge_init(&dtab->map.memory, cost);
if (err)
- goto free_dtab;
-
- err = -ENOMEM;
+ return -EINVAL;
dtab->flush_list = alloc_percpu(struct list_head);
if (!dtab->flush_list)
@@ -124,19 +116,38 @@ static struct bpf_map *dev_map_alloc(union bpf_attr *attr)
if (!dtab->netdev_map)
goto free_percpu;
- spin_lock(&dev_map_lock);
- list_add_tail_rcu(&dtab->list, &dev_map_list);
- spin_unlock(&dev_map_lock);
-
- return &dtab->map;
+ return 0;
free_percpu:
free_percpu(dtab->flush_list);
free_charge:
bpf_map_charge_finish(&dtab->map.memory);
-free_dtab:
- kfree(dtab);
- return ERR_PTR(err);
+ return -ENOMEM;
+}
+
+static struct bpf_map *dev_map_alloc(union bpf_attr *attr)
+{
+ struct bpf_dtab *dtab;
+ int err;
+
+ if (!capable(CAP_NET_ADMIN))
+ return ERR_PTR(-EPERM);
+
+ dtab = kzalloc(sizeof(*dtab), GFP_USER);
+ if (!dtab)
+ return ERR_PTR(-ENOMEM);
+
+ err = dev_map_init_map(dtab, attr, true);
+ if (err) {
+ kfree(dtab);
+ return ERR_PTR(err);
+ }
+
+ spin_lock(&dev_map_lock);
+ list_add_tail_rcu(&dtab->list, &dev_map_list);
+ spin_unlock(&dev_map_lock);
+
+ return &dtab->map;
}
static void dev_map_free(struct bpf_map *map)
@@ -235,7 +246,7 @@ static int bq_xmit_all(struct xdp_bulk_queue *bq, u32 flags,
out:
bq->count = 0;
- trace_xdp_devmap_xmit(&obj->dtab->map, obj->bit,
+ trace_xdp_devmap_xmit(&obj->dtab->map, obj->idx,
sent, drops, bq->dev_rx, dev, err);
bq->dev_rx = NULL;
__list_del_clearprev(&bq->flush_node);
@@ -412,17 +423,52 @@ static int dev_map_delete_elem(struct bpf_map *map, void *key)
return 0;
}
-static int dev_map_update_elem(struct bpf_map *map, void *key, void *value,
- u64 map_flags)
+static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,
+ struct bpf_dtab *dtab,
+ u32 ifindex,
+ unsigned int idx)
{
- struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
- struct net *net = current->nsproxy->net_ns;
gfp_t gfp = GFP_ATOMIC | __GFP_NOWARN;
+ struct bpf_dtab_netdev *dev;
+ struct xdp_bulk_queue *bq;
+ int cpu;
+
+ dev = kmalloc_node(sizeof(*dev), gfp, dtab->map.numa_node);
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
+
+ dev->bulkq = __alloc_percpu_gfp(sizeof(*dev->bulkq),
+ sizeof(void *), gfp);
+ if (!dev->bulkq) {
+ kfree(dev);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ for_each_possible_cpu(cpu) {
+ bq = per_cpu_ptr(dev->bulkq, cpu);
+ bq->obj = dev;
+ }
+
+ dev->dev = dev_get_by_index(net, ifindex);
+ if (!dev->dev) {
+ free_percpu(dev->bulkq);
+ kfree(dev);
+ return ERR_PTR(-EINVAL);
+ }
+
+ dev->idx = idx;
+ dev->dtab = dtab;
+
+ return dev;
+}
+
+static int __dev_map_update_elem(struct net *net, struct bpf_map *map,
+ void *key, void *value, u64 map_flags)
+{
+ struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
struct bpf_dtab_netdev *dev, *old_dev;
u32 ifindex = *(u32 *)value;
- struct xdp_bulk_queue *bq;
u32 i = *(u32 *)key;
- int cpu;
if (unlikely(map_flags > BPF_EXIST))
return -EINVAL;
@@ -434,31 +480,9 @@ static int dev_map_update_elem(struct bpf_map *map, void *key, void *value,
if (!ifindex) {
dev = NULL;
} else {
- dev = kmalloc_node(sizeof(*dev), gfp, map->numa_node);
- if (!dev)
- return -ENOMEM;
-
- dev->bulkq = __alloc_percpu_gfp(sizeof(*dev->bulkq),
- sizeof(void *), gfp);
- if (!dev->bulkq) {
- kfree(dev);
- return -ENOMEM;
- }
-
- for_each_possible_cpu(cpu) {
- bq = per_cpu_ptr(dev->bulkq, cpu);
- bq->obj = dev;
- }
-
- dev->dev = dev_get_by_index(net, ifindex);
- if (!dev->dev) {
- free_percpu(dev->bulkq);
- kfree(dev);
- return -EINVAL;
- }
-
- dev->bit = i;
- dev->dtab = dtab;
+ dev = __dev_map_alloc_node(net, dtab, ifindex, i);
+ if (IS_ERR(dev))
+ return PTR_ERR(dev);
}
/* Use call_rcu() here to ensure rcu critical sections have completed
@@ -472,6 +496,13 @@ static int dev_map_update_elem(struct bpf_map *map, void *key, void *value,
return 0;
}
+static int dev_map_update_elem(struct bpf_map *map, void *key, void *value,
+ u64 map_flags)
+{
+ return __dev_map_update_elem(current->nsproxy->net_ns,
+ map, key, value, map_flags);
+}
+
const struct bpf_map_ops dev_map_ops = {
.map_alloc = dev_map_alloc,
.map_free = dev_map_free,
^ permalink raw reply related
* [PATCH bpf-next v2 6/6] tools: Add definitions for devmap_hash map type
From: Toke Høiland-Jørgensen @ 2019-07-06 8:47 UTC (permalink / raw)
To: Daniel Borkmann
Cc: Alexei Starovoitov, netdev, David Miller, Jesper Dangaard Brouer,
Jakub Kicinski, Björn Töpel
In-Reply-To: <156240283550.10171.1727292671613975908.stgit@alrua-x1>
From: Toke Høiland-Jørgensen <toke@redhat.com>
This adds a selftest, syncs the tools/ uapi header and adds the
devmap_hash name to bpftool for the new devmap_hash map type.
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
tools/bpf/bpftool/map.c | 1 +
tools/include/uapi/linux/bpf.h | 1 +
tools/testing/selftests/bpf/test_maps.c | 16 ++++++++++++++++
3 files changed, 18 insertions(+)
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index 5da5a7311f13..c345f819b840 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -37,6 +37,7 @@ const char * const map_type_name[] = {
[BPF_MAP_TYPE_ARRAY_OF_MAPS] = "array_of_maps",
[BPF_MAP_TYPE_HASH_OF_MAPS] = "hash_of_maps",
[BPF_MAP_TYPE_DEVMAP] = "devmap",
+ [BPF_MAP_TYPE_DEVMAP_HASH] = "devmap_hash",
[BPF_MAP_TYPE_SOCKMAP] = "sockmap",
[BPF_MAP_TYPE_CPUMAP] = "cpumap",
[BPF_MAP_TYPE_XSKMAP] = "xskmap",
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index cecf42c871d4..8afaa0a19c67 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -134,6 +134,7 @@ enum bpf_map_type {
BPF_MAP_TYPE_QUEUE,
BPF_MAP_TYPE_STACK,
BPF_MAP_TYPE_SK_STORAGE,
+ BPF_MAP_TYPE_DEVMAP_HASH,
};
/* Note that tracing related programs such as
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c
index a3fbc571280a..086319caf2d9 100644
--- a/tools/testing/selftests/bpf/test_maps.c
+++ b/tools/testing/selftests/bpf/test_maps.c
@@ -508,6 +508,21 @@ static void test_devmap(unsigned int task, void *data)
close(fd);
}
+static void test_devmap_hash(unsigned int task, void *data)
+{
+ int fd;
+ __u32 key, value;
+
+ fd = bpf_create_map(BPF_MAP_TYPE_DEVMAP_HASH, sizeof(key), sizeof(value),
+ 2, 0);
+ if (fd < 0) {
+ printf("Failed to create devmap_hash '%s'!\n", strerror(errno));
+ exit(1);
+ }
+
+ close(fd);
+}
+
static void test_queuemap(unsigned int task, void *data)
{
const int MAP_SIZE = 32;
@@ -1675,6 +1690,7 @@ static void run_all_tests(void)
test_arraymap_percpu_many_keys();
test_devmap(0, NULL);
+ test_devmap_hash(0, NULL);
test_sockmap(0, NULL);
test_map_large();
^ permalink raw reply related
* [PATCH bpf-next v2 0/6] xdp: Add devmap_hash map type
From: Toke Høiland-Jørgensen @ 2019-07-06 8:47 UTC (permalink / raw)
To: Daniel Borkmann
Cc: Alexei Starovoitov, netdev, David Miller, Jesper Dangaard Brouer,
Jakub Kicinski, Björn Töpel
This series adds a new map type, devmap_hash, that works like the existing
devmap type, but using a hash-based indexing scheme. This is useful for the use
case where a devmap is indexed by ifindex (for instance for use with the routing
table lookup helper). For this use case, the regular devmap needs to be sized
after the maximum ifindex number, not the number of devices in it. A hash-based
indexing scheme makes it possible to size the map after the number of devices it
should contain instead.
This was previously part of my patch series that also turned the regular
bpf_redirect() helper into a map-based one; for this series I just pulled out
the patches that introduced the new map type.
Changelog:
v2:
- Split commit adding the new map type so uapi and tools changes are separate.
Changes to these patches since the previous series:
- Rebase on top of the other devmap changes (makes this one simpler!)
- Don't enforce key==val, but allow arbitrary indexes.
- Rename the type to devmap_hash to reflect the fact that it's just a hashmap now.
---
Toke Høiland-Jørgensen (6):
include/bpf.h: Remove map_insert_ctx() stubs
xdp: Refactor devmap allocation code for reuse
uapi/bpf: Add new devmap_hash type
xdp: Add devmap_hash map type for looking up devices by hashed index
tools/libbpf_probes: Add new devmap_hash type
tools: Add definitions for devmap_hash map type
include/linux/bpf.h | 11 -
include/linux/bpf_types.h | 1
include/trace/events/xdp.h | 3
include/uapi/linux/bpf.h | 1
kernel/bpf/devmap.c | 325 ++++++++++++++++++++++++++-----
kernel/bpf/verifier.c | 2
net/core/filter.c | 9 +
tools/bpf/bpftool/map.c | 1
tools/include/uapi/linux/bpf.h | 1
tools/lib/bpf/libbpf_probes.c | 1
tools/testing/selftests/bpf/test_maps.c | 16 ++
11 files changed, 310 insertions(+), 61 deletions(-)
^ permalink raw reply
* [PATCH bpf-next v2 4/6] xdp: Add devmap_hash map type for looking up devices by hashed index
From: Toke Høiland-Jørgensen @ 2019-07-06 8:47 UTC (permalink / raw)
To: Daniel Borkmann
Cc: Alexei Starovoitov, netdev, David Miller, Jesper Dangaard Brouer,
Jakub Kicinski, Björn Töpel
In-Reply-To: <156240283550.10171.1727292671613975908.stgit@alrua-x1>
From: Toke Høiland-Jørgensen <toke@redhat.com>
A common pattern when using xdp_redirect_map() is to create a device map
where the lookup key is simply ifindex. Because device maps are arrays,
this leaves holes in the map, and the map has to be sized to fit the
largest ifindex, regardless of how many devices actually are actually
needed in the map.
This patch adds a second type of device map where the key is looked up
using a hashmap, instead of being used as an array index. This allows maps
to be densely packed, so they can be smaller.
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
include/linux/bpf.h | 7 ++
include/linux/bpf_types.h | 1
include/trace/events/xdp.h | 3 -
kernel/bpf/devmap.c | 192 ++++++++++++++++++++++++++++++++++++++++++++
kernel/bpf/verifier.c | 2
net/core/filter.c | 9 ++
6 files changed, 211 insertions(+), 3 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index bfdb54dd2ad1..f9a506147c8a 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -713,6 +713,7 @@ struct xdp_buff;
struct sk_buff;
struct bpf_dtab_netdev *__dev_map_lookup_elem(struct bpf_map *map, u32 key);
+struct bpf_dtab_netdev *__dev_map_hash_lookup_elem(struct bpf_map *map, u32 key);
void __dev_map_flush(struct bpf_map *map);
int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_buff *xdp,
struct net_device *dev_rx);
@@ -799,6 +800,12 @@ static inline struct net_device *__dev_map_lookup_elem(struct bpf_map *map,
return NULL;
}
+static inline struct net_device *__dev_map_hash_lookup_elem(struct bpf_map *map,
+ u32 key)
+{
+ return NULL;
+}
+
static inline void __dev_map_flush(struct bpf_map *map)
{
}
diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
index eec5aeeeaf92..36a9c2325176 100644
--- a/include/linux/bpf_types.h
+++ b/include/linux/bpf_types.h
@@ -62,6 +62,7 @@ BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY_OF_MAPS, array_of_maps_map_ops)
BPF_MAP_TYPE(BPF_MAP_TYPE_HASH_OF_MAPS, htab_of_maps_map_ops)
#ifdef CONFIG_NET
BPF_MAP_TYPE(BPF_MAP_TYPE_DEVMAP, dev_map_ops)
+BPF_MAP_TYPE(BPF_MAP_TYPE_DEVMAP_HASH, dev_map_hash_ops)
BPF_MAP_TYPE(BPF_MAP_TYPE_SK_STORAGE, sk_storage_map_ops)
#if defined(CONFIG_BPF_STREAM_PARSER)
BPF_MAP_TYPE(BPF_MAP_TYPE_SOCKMAP, sock_map_ops)
diff --git a/include/trace/events/xdp.h b/include/trace/events/xdp.h
index 68899fdc985b..8c8420230a10 100644
--- a/include/trace/events/xdp.h
+++ b/include/trace/events/xdp.h
@@ -175,7 +175,8 @@ struct _bpf_dtab_netdev {
#endif /* __DEVMAP_OBJ_TYPE */
#define devmap_ifindex(fwd, map) \
- ((map->map_type == BPF_MAP_TYPE_DEVMAP) ? \
+ ((map->map_type == BPF_MAP_TYPE_DEVMAP || \
+ map->map_type == BPF_MAP_TYPE_DEVMAP_HASH) ? \
((struct _bpf_dtab_netdev *)fwd)->dev->ifindex : 0)
#define _trace_xdp_redirect_map(dev, xdp, fwd, map, idx) \
diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
index a2fe16362129..341af02f049d 100644
--- a/kernel/bpf/devmap.c
+++ b/kernel/bpf/devmap.c
@@ -37,6 +37,12 @@
* notifier hook walks the map we know that new dev references can not be
* added by the user because core infrastructure ensures dev_get_by_index()
* calls will fail at this point.
+ *
+ * The devmap_hash type is a map type which interprets keys as ifindexes and
+ * indexes these using a hashmap. This allows maps that use ifindex as key to be
+ * densely packed instead of having holes in the lookup array for unused
+ * ifindexes. The setup and packet enqueue/send code is shared between the two
+ * types of devmap; only the lookup and insertion is different.
*/
#include <linux/bpf.h>
#include <net/xdp.h>
@@ -59,6 +65,7 @@ struct xdp_bulk_queue {
struct bpf_dtab_netdev {
struct net_device *dev; /* must be first member, due to tracepoint */
+ struct hlist_node index_hlist;
struct bpf_dtab *dtab;
unsigned int idx; /* keep track of map index for tracepoint */
struct xdp_bulk_queue __percpu *bulkq;
@@ -70,11 +77,29 @@ struct bpf_dtab {
struct bpf_dtab_netdev **netdev_map;
struct list_head __percpu *flush_list;
struct list_head list;
+
+ /* these are only used for DEVMAP_HASH type maps */
+ unsigned int items;
+ struct hlist_head *dev_index_head;
+ spinlock_t index_lock;
};
static DEFINE_SPINLOCK(dev_map_lock);
static LIST_HEAD(dev_map_list);
+static struct hlist_head *dev_map_create_hash(void)
+{
+ int i;
+ struct hlist_head *hash;
+
+ hash = kmalloc_array(NETDEV_HASHENTRIES, sizeof(*hash), GFP_KERNEL);
+ if (hash != NULL)
+ for (i = 0; i < NETDEV_HASHENTRIES; i++)
+ INIT_HLIST_HEAD(&hash[i]);
+
+ return hash;
+}
+
static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr,
bool check_memlock)
{
@@ -98,6 +123,9 @@ static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr,
cost = (u64) dtab->map.max_entries * sizeof(struct bpf_dtab_netdev *);
cost += sizeof(struct list_head) * num_possible_cpus();
+ if (attr->map_type == BPF_MAP_TYPE_DEVMAP_HASH)
+ cost += sizeof(struct hlist_head) * NETDEV_HASHENTRIES;
+
/* if map size is larger than memlock limit, reject it */
err = bpf_map_charge_init(&dtab->map.memory, cost);
if (err)
@@ -116,8 +144,18 @@ static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr,
if (!dtab->netdev_map)
goto free_percpu;
+ if (attr->map_type == BPF_MAP_TYPE_DEVMAP_HASH) {
+ dtab->dev_index_head = dev_map_create_hash();
+ if (!dtab->dev_index_head)
+ goto free_map_area;
+
+ spin_lock_init(&dtab->index_lock);
+ }
+
return 0;
+free_map_area:
+ bpf_map_area_free(dtab->netdev_map);
free_percpu:
free_percpu(dtab->flush_list);
free_charge:
@@ -199,6 +237,7 @@ static void dev_map_free(struct bpf_map *map)
free_percpu(dtab->flush_list);
bpf_map_area_free(dtab->netdev_map);
+ kfree(dtab->dev_index_head);
kfree(dtab);
}
@@ -219,6 +258,70 @@ static int dev_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
return 0;
}
+static inline struct hlist_head *dev_map_index_hash(struct bpf_dtab *dtab,
+ int idx)
+{
+ return &dtab->dev_index_head[idx & (NETDEV_HASHENTRIES - 1)];
+}
+
+struct bpf_dtab_netdev *__dev_map_hash_lookup_elem(struct bpf_map *map, u32 key)
+{
+ struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
+ struct hlist_head *head = dev_map_index_hash(dtab, key);
+ struct bpf_dtab_netdev *dev;
+
+ hlist_for_each_entry_rcu(dev, head, index_hlist)
+ if (dev->idx == key)
+ return dev;
+
+ return NULL;
+}
+
+static int dev_map_hash_get_next_key(struct bpf_map *map, void *key,
+ void *next_key)
+{
+ struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
+ u32 idx, *next = next_key;
+ struct bpf_dtab_netdev *dev, *next_dev;
+ struct hlist_head *head;
+ int i = 0;
+
+ if (!key)
+ goto find_first;
+
+ idx = *(u32 *)key;
+
+ dev = __dev_map_hash_lookup_elem(map, idx);
+ if (!dev)
+ goto find_first;
+
+ next_dev = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(&dev->index_hlist)),
+ struct bpf_dtab_netdev, index_hlist);
+
+ if (next_dev) {
+ *next = next_dev->idx;
+ return 0;
+ }
+
+ i = idx & (NETDEV_HASHENTRIES - 1);
+ i++;
+
+ find_first:
+ for (; i < NETDEV_HASHENTRIES; i++) {
+ head = dev_map_index_hash(dtab, i);
+
+ next_dev = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(head)),
+ struct bpf_dtab_netdev,
+ index_hlist);
+ if (next_dev) {
+ *next = next_dev->idx;
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
static int bq_xmit_all(struct xdp_bulk_queue *bq, u32 flags,
bool in_napi_ctx)
{
@@ -374,6 +477,15 @@ static void *dev_map_lookup_elem(struct bpf_map *map, void *key)
return dev ? &dev->ifindex : NULL;
}
+static void *dev_map_hash_lookup_elem(struct bpf_map *map, void *key)
+{
+ struct bpf_dtab_netdev *obj = __dev_map_hash_lookup_elem(map,
+ *(u32 *)key);
+ struct net_device *dev = obj ? obj->dev : NULL;
+
+ return dev ? &dev->ifindex : NULL;
+}
+
static void dev_map_flush_old(struct bpf_dtab_netdev *dev)
{
if (dev->dev->netdev_ops->ndo_xdp_xmit) {
@@ -423,6 +535,27 @@ static int dev_map_delete_elem(struct bpf_map *map, void *key)
return 0;
}
+static int dev_map_hash_delete_elem(struct bpf_map *map, void *key)
+{
+ struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
+ struct bpf_dtab_netdev *old_dev;
+ int k = *(u32 *)key;
+
+ old_dev = __dev_map_hash_lookup_elem(map, k);
+ if (!old_dev)
+ return 0;
+
+ spin_lock(&dtab->index_lock);
+ if (!hlist_unhashed(&old_dev->index_hlist)) {
+ dtab->items--;
+ hlist_del_init_rcu(&old_dev->index_hlist);
+ }
+ spin_unlock(&dtab->index_lock);
+
+ call_rcu(&old_dev->rcu, __dev_map_entry_free);
+ return 0;
+}
+
static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,
struct bpf_dtab *dtab,
u32 ifindex,
@@ -503,6 +636,55 @@ static int dev_map_update_elem(struct bpf_map *map, void *key, void *value,
map, key, value, map_flags);
}
+static int __dev_map_hash_update_elem(struct net *net, struct bpf_map *map,
+ void *key, void *value, u64 map_flags)
+{
+ struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
+ struct bpf_dtab_netdev *dev, *old_dev;
+ u32 ifindex = *(u32 *)value;
+ u32 idx = *(u32 *)key;
+
+ if (unlikely(map_flags > BPF_EXIST || !ifindex))
+ return -EINVAL;
+
+ old_dev = __dev_map_hash_lookup_elem(map, idx);
+ if (old_dev && (map_flags & BPF_NOEXIST))
+ return -EEXIST;
+
+ dev = __dev_map_alloc_node(net, dtab, ifindex, idx);
+ if (IS_ERR(dev))
+ return PTR_ERR(dev);
+
+ spin_lock(&dtab->index_lock);
+
+ if (old_dev) {
+ hlist_del_rcu(&old_dev->index_hlist);
+ } else {
+ if (dtab->items >= dtab->map.max_entries) {
+ spin_unlock(&dtab->index_lock);
+ call_rcu(&dev->rcu, __dev_map_entry_free);
+ return -ENOSPC;
+ }
+ dtab->items++;
+ }
+
+ hlist_add_head_rcu(&dev->index_hlist,
+ dev_map_index_hash(dtab, idx));
+ spin_unlock(&dtab->index_lock);
+
+ if (old_dev)
+ call_rcu(&old_dev->rcu, __dev_map_entry_free);
+
+ return 0;
+}
+
+static int dev_map_hash_update_elem(struct bpf_map *map, void *key, void *value,
+ u64 map_flags)
+{
+ return __dev_map_hash_update_elem(current->nsproxy->net_ns,
+ map, key, value, map_flags);
+}
+
const struct bpf_map_ops dev_map_ops = {
.map_alloc = dev_map_alloc,
.map_free = dev_map_free,
@@ -513,6 +695,16 @@ const struct bpf_map_ops dev_map_ops = {
.map_check_btf = map_check_no_btf,
};
+const struct bpf_map_ops dev_map_hash_ops = {
+ .map_alloc = dev_map_alloc,
+ .map_free = dev_map_free,
+ .map_get_next_key = dev_map_hash_get_next_key,
+ .map_lookup_elem = dev_map_hash_lookup_elem,
+ .map_update_elem = dev_map_hash_update_elem,
+ .map_delete_elem = dev_map_hash_delete_elem,
+ .map_check_btf = map_check_no_btf,
+};
+
static int dev_map_notification(struct notifier_block *notifier,
ulong event, void *ptr)
{
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index a2e763703c30..231b9e22827c 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3460,6 +3460,7 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
goto error;
break;
case BPF_MAP_TYPE_DEVMAP:
+ case BPF_MAP_TYPE_DEVMAP_HASH:
if (func_id != BPF_FUNC_redirect_map &&
func_id != BPF_FUNC_map_lookup_elem)
goto error;
@@ -3542,6 +3543,7 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
break;
case BPF_FUNC_redirect_map:
if (map->map_type != BPF_MAP_TYPE_DEVMAP &&
+ map->map_type != BPF_MAP_TYPE_DEVMAP_HASH &&
map->map_type != BPF_MAP_TYPE_CPUMAP &&
map->map_type != BPF_MAP_TYPE_XSKMAP)
goto error;
diff --git a/net/core/filter.c b/net/core/filter.c
index 089aaea0ccc6..276961c4e0d4 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3517,7 +3517,8 @@ static int __bpf_tx_xdp_map(struct net_device *dev_rx, void *fwd,
int err;
switch (map->map_type) {
- case BPF_MAP_TYPE_DEVMAP: {
+ case BPF_MAP_TYPE_DEVMAP:
+ case BPF_MAP_TYPE_DEVMAP_HASH: {
struct bpf_dtab_netdev *dst = fwd;
err = dev_map_enqueue(dst, xdp, dev_rx);
@@ -3554,6 +3555,7 @@ void xdp_do_flush_map(void)
if (map) {
switch (map->map_type) {
case BPF_MAP_TYPE_DEVMAP:
+ case BPF_MAP_TYPE_DEVMAP_HASH:
__dev_map_flush(map);
break;
case BPF_MAP_TYPE_CPUMAP:
@@ -3574,6 +3576,8 @@ static inline void *__xdp_map_lookup_elem(struct bpf_map *map, u32 index)
switch (map->map_type) {
case BPF_MAP_TYPE_DEVMAP:
return __dev_map_lookup_elem(map, index);
+ case BPF_MAP_TYPE_DEVMAP_HASH:
+ return __dev_map_hash_lookup_elem(map, index);
case BPF_MAP_TYPE_CPUMAP:
return __cpu_map_lookup_elem(map, index);
case BPF_MAP_TYPE_XSKMAP:
@@ -3655,7 +3659,8 @@ static int xdp_do_generic_redirect_map(struct net_device *dev,
ri->tgt_value = NULL;
WRITE_ONCE(ri->map, NULL);
- if (map->map_type == BPF_MAP_TYPE_DEVMAP) {
+ if (map->map_type == BPF_MAP_TYPE_DEVMAP ||
+ map->map_type == BPF_MAP_TYPE_DEVMAP_HASH) {
struct bpf_dtab_netdev *dst = fwd;
err = dev_map_generic_redirect(dst, skb, xdp_prog);
^ permalink raw reply related
* Re: [PATCH bpf-next v3] libbpf: add xsk_ring_prod__nb_free() function
From: Magnus Karlsson @ 2019-07-06 9:57 UTC (permalink / raw)
To: Daniel Borkmann
Cc: Eelco Chaudron, Network Development, Alexei Starovoitov,
Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko
In-Reply-To: <c86151f8-9a16-d2e4-a888-d0836ff3c10a@iogearbox.net>
On Fri, Jul 5, 2019 at 4:35 PM Daniel Borkmann <daniel@iogearbox.net> wrote:
>
> On 07/03/2019 02:52 PM, Eelco Chaudron wrote:
> > When an AF_XDP application received X packets, it does not mean X
> > frames can be stuffed into the producer ring. To make it easier for
> > AF_XDP applications this API allows them to check how many frames can
> > be added into the ring.
> >
> > Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
>
> The commit log as it is along with the code is a bit too confusing for
> readers. After all you only do a rename below. It would need to additionally
> state that the rename is as per libbpf convention (xyz__ prefix) in order to
> denote that this API is exposed to be used by applications.
>
> Given you are doing this for xsk_prod_nb_free(), should we do the same for
> xsk_cons_nb_avail() as well? Extending XDP sample app would be reasonable
> addition as well in this context.
Sorry for the late reply Eelco. My e-mail filter is apparently not set
up correctly since it does not catch mails where I am on the CC line.
Will fix.
At the same time you are rewording the commit log according to
Daniel's suggestion, could you please also add a line or two
explaining how to use the nb parameter? If you set it to the size of
the ring, you will get the exact amount of slots available, at the
cost of performance (you touch shared state for sure). nb is there to
limit the touching of shared state. The same kind of comment in the
header file would be great too.
Have you found any use of the xsk_cons_nb_avail() function from your
sample application? If so, let us add it to the public API.
Thanks: Magnus
> > ---
> >
> > v2 -> v3
> > - Removed cache by pass option
> >
> > v1 -> v2
> > - Renamed xsk_ring_prod__free() to xsk_ring_prod__nb_free()
> > - Add caching so it will only touch global state when needed
> >
> > tools/lib/bpf/xsk.h | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/tools/lib/bpf/xsk.h b/tools/lib/bpf/xsk.h
> > index 82ea71a0f3ec..3411556e04d9 100644
> > --- a/tools/lib/bpf/xsk.h
> > +++ b/tools/lib/bpf/xsk.h
> > @@ -76,7 +76,7 @@ xsk_ring_cons__rx_desc(const struct xsk_ring_cons *rx, __u32 idx)
> > return &descs[idx & rx->mask];
> > }
> >
> > -static inline __u32 xsk_prod_nb_free(struct xsk_ring_prod *r, __u32 nb)
> > +static inline __u32 xsk_prod__nb_free(struct xsk_ring_prod *r, __u32 nb)
> > {
> > __u32 free_entries = r->cached_cons - r->cached_prod;
> >
> > @@ -110,7 +110,7 @@ static inline __u32 xsk_cons_nb_avail(struct xsk_ring_cons *r, __u32 nb)
> > static inline size_t xsk_ring_prod__reserve(struct xsk_ring_prod *prod,
> > size_t nb, __u32 *idx)
> > {
> > - if (xsk_prod_nb_free(prod, nb) < nb)
> > + if (xsk_prod__nb_free(prod, nb) < nb)
> > return 0;
> >
> > *idx = prod->cached_prod;
> >
>
^ permalink raw reply
* Re: kernel BUG at net/rxrpc/local_object.c:LINE!
From: syzbot @ 2019-07-06 10:03 UTC (permalink / raw)
To: davem, dhowells, dvyukov, ebiggers, linux-afs, linux-kernel,
netdev, syzkaller-bugs
In-Reply-To: <CACT4Y+YjdV8CqX5=PzKsHnLsJOzsydqiq3igYDm_=nSdmFo2YQ@mail.gmail.com>
Hello,
syzbot has tested the proposed patch but the reproducer still triggered
crash:
kernel BUG at net/rxrpc/local_object.c:LINE!
rxrpc: Assertion failed
------------[ cut here ]------------
kernel BUG at net/rxrpc/local_object.c:468!
invalid opcode: 0000 [#1] PREEMPT SMP KASAN
CPU: 1 PID: 10548 Comm: udevd Not tainted 5.2.0-rc7+ #1
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
RIP: 0010:rxrpc_local_rcu net/rxrpc/local_object.c:468 [inline]
RIP: 0010:rxrpc_local_rcu.cold+0x11/0x13 net/rxrpc/local_object.c:462
Code: 83 eb 20 e9 74 ff ff ff e8 68 a9 2d fb eb cc 4c 89 ef e8 7e a9 2d fb
eb e2 e8 97 f2 f4 fa 48 c7 c7 e0 8c 15 88 e8 2f f8 de fa <0f> 0b e8 84 f2
f4 fa 48 c7 c7 e0 8c 15 88 e8 1c f8 de fa 0f 0b e8
RSP: 0018:ffff8880ae909de8 EFLAGS: 00010282
RAX: 0000000000000017 RBX: 0000000000000001 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffffffff815ad9e6 RDI: ffffed1015d213af
RBP: ffff8880ae909df8 R08: 0000000000000017 R09: ffffed1015d260a1
R10: ffffed1015d260a0 R11: ffff8880ae930507 R12: ffff888095d10940
R13: ffff888095d10940 R14: ffffffff867b9b10 R15: ffff8880ae909e78
FS: 0000000000000000(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000625208 CR3: 00000000a11ba000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<IRQ>
__rcu_reclaim kernel/rcu/rcu.h:222 [inline]
rcu_do_batch kernel/rcu/tree.c:2092 [inline]
invoke_rcu_callbacks kernel/rcu/tree.c:2310 [inline]
rcu_core+0xba5/0x1500 kernel/rcu/tree.c:2291
__do_softirq+0x25c/0x94c kernel/softirq.c:292
invoke_softirq kernel/softirq.c:373 [inline]
irq_exit+0x180/0x1d0 kernel/softirq.c:413
exiting_irq arch/x86/include/asm/apic.h:536 [inline]
smp_apic_timer_interrupt+0x13b/0x550 arch/x86/kernel/apic/apic.c:1068
apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:806
</IRQ>
RIP: 0010:arch_local_irq_restore arch/x86/include/asm/paravirt.h:767
[inline]
RIP: 0010:__raw_spin_unlock_irqrestore include/linux/spinlock_api_smp.h:160
[inline]
RIP: 0010:_raw_spin_unlock_irqrestore+0x95/0xe0
kernel/locking/spinlock.c:191
Code: 48 c7 c0 30 76 b2 88 48 ba 00 00 00 00 00 fc ff df 48 c1 e8 03 80 3c
10 00 75 39 48 83 3d 82 18 95 01 00 74 24 48 89 df 57 9d <0f> 1f 44 00 00
bf 01 00 00 00 e8 dc 2e 30 fa 65 8b 05 bd 9f e4 78
RSP: 0018:ffff8880a78bf728 EFLAGS: 00000286 ORIG_RAX: ffffffffffffff13
RAX: 1ffffffff1164ec6 RBX: 0000000000000286 RCX: 1ffff11011248d84
RDX: dffffc0000000000 RSI: ffff888089246c00 RDI: 0000000000000286
RBP: ffff8880a78bf738 R08: ffff888089246380 R09: ffff888089246c20
R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff8a758108
R13: 0000000000000286 R14: ffffffff8a758108 R15: 0000000000000000
__debug_check_no_obj_freed lib/debugobjects.c:798 [inline]
debug_check_no_obj_freed+0x200/0x464 lib/debugobjects.c:817
free_pages_prepare mm/page_alloc.c:1140 [inline]
free_pcp_prepare mm/page_alloc.c:1156 [inline]
free_unref_page_prepare mm/page_alloc.c:2947 [inline]
free_unref_page_list+0x1f9/0xc30 mm/page_alloc.c:3016
release_pages+0x5df/0x1930 mm/swap.c:795
free_pages_and_swap_cache+0x2a0/0x3d0 mm/swap_state.c:295
tlb_batch_pages_flush mm/mmu_gather.c:49 [inline]
tlb_flush_mmu_free mm/mmu_gather.c:184 [inline]
tlb_flush_mmu+0x89/0x630 mm/mmu_gather.c:191
tlb_finish_mmu+0x98/0x3b0 mm/mmu_gather.c:272
exit_mmap+0x2cd/0x510 mm/mmap.c:3147
__mmput kernel/fork.c:1063 [inline]
mmput+0x15f/0x4c0 kernel/fork.c:1084
exec_mmap fs/exec.c:1047 [inline]
flush_old_exec+0x8c8/0x1c00 fs/exec.c:1280
load_elf_binary+0xa53/0x56c0 fs/binfmt_elf.c:867
search_binary_handler fs/exec.c:1658 [inline]
search_binary_handler+0x16d/0x570 fs/exec.c:1635
exec_binprm fs/exec.c:1701 [inline]
__do_execve_file.isra.0+0x1310/0x22f0 fs/exec.c:1821
do_execveat_common fs/exec.c:1868 [inline]
do_execve fs/exec.c:1885 [inline]
__do_sys_execve fs/exec.c:1961 [inline]
__se_sys_execve fs/exec.c:1956 [inline]
__x64_sys_execve+0x8f/0xc0 fs/exec.c:1956
do_syscall_64+0xfd/0x680 arch/x86/entry/common.c:301
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x7f67dfd66207
Code: Bad RIP value.
RSP: 002b:00007fff900c3538 EFLAGS: 00000202 ORIG_RAX: 000000000000003b
RAX: ffffffffffffffda RBX: 00000000ffffffff RCX: 00007f67dfd66207
RDX: 0000000000695c20 RSI: 00007fff900c3630 RDI: 00007fff900c4640
RBP: 0000000000625500 R08: 00000000000020d5 R09: 00000000000020d5
R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000695c20
R13: 0000000000000007 R14: 0000000000691250 R15: 0000000000000005
Modules linked in:
---[ end trace 5b4a4001a18479d0 ]---
RIP: 0010:rxrpc_local_rcu net/rxrpc/local_object.c:468 [inline]
RIP: 0010:rxrpc_local_rcu.cold+0x11/0x13 net/rxrpc/local_object.c:462
Code: 83 eb 20 e9 74 ff ff ff e8 68 a9 2d fb eb cc 4c 89 ef e8 7e a9 2d fb
eb e2 e8 97 f2 f4 fa 48 c7 c7 e0 8c 15 88 e8 2f f8 de fa <0f> 0b e8 84 f2
f4 fa 48 c7 c7 e0 8c 15 88 e8 1c f8 de fa 0f 0b e8
RSP: 0018:ffff8880ae909de8 EFLAGS: 00010282
RAX: 0000000000000017 RBX: 0000000000000001 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffffffff815ad9e6 RDI: ffffed1015d213af
RBP: ffff8880ae909df8 R08: 0000000000000017 R09: ffffed1015d260a1
R10: ffffed1015d260a0 R11: ffff8880ae930507 R12: ffff888095d10940
R13: ffff888095d10940 R14: ffffffff867b9b10 R15: ffff8880ae909e78
FS: 0000000000000000(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f67dfd661dd CR3: 00000000a11ba000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Tested on:
commit: 69bf4b6b Revert "mm: page cache: store only head pages in ..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=146e5673a00000
kernel config: https://syzkaller.appspot.com/x/.config?x=f6451f0da3d42d53
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
^ permalink raw reply
* Re: [PATCH 24/43] docs: leds: convert to ReST
From: Mauro Carvalho Chehab @ 2019-07-06 10:41 UTC (permalink / raw)
To: Jacek Anaszewski
Cc: Linux Doc Mailing List, Mauro Carvalho Chehab, linux-kernel,
Jonathan Corbet, Vadim Pasternak, Pavel Machek, Dan Murphy,
Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
David S. Miller, linux-leds, netfilter-devel, coreteam, netdev
In-Reply-To: <0b2a2452-20ca-1651-e03b-a15a8502b028@gmail.com>
Em Fri, 28 Jun 2019 21:01:40 +0200
Jacek Anaszewski <jacek.anaszewski@gmail.com> escreveu:
> Hi Mauro,
>
> On 6/28/19 2:20 PM, Mauro Carvalho Chehab wrote:
> > Rename the leds documentation files to ReST, add an
> > index for them and adjust in order to produce a nice html
> > output via the Sphinx build system.
> >
> > At its new index.rst, let's add a :orphan: while this is not linked to
> > the main index.rst file, in order to avoid build warnings.
> >
> > Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
> > Acked-by: Pavel Machek <pavel@ucw.cz>
> > ---
> > Documentation/laptops/thinkpad-acpi.txt | 4 +-
> > Documentation/leds/index.rst | 25 ++
> > .../leds/{leds-blinkm.txt => leds-blinkm.rst} | 64 ++---
> > ...s-class-flash.txt => leds-class-flash.rst} | 49 ++--
> > .../leds/{leds-class.txt => leds-class.rst} | 15 +-
> > .../leds/{leds-lm3556.txt => leds-lm3556.rst} | 100 ++++++--
> > .../leds/{leds-lp3944.txt => leds-lp3944.rst} | 23 +-
> > Documentation/leds/leds-lp5521.rst | 115 +++++++++
> > Documentation/leds/leds-lp5521.txt | 101 --------
> > Documentation/leds/leds-lp5523.rst | 147 ++++++++++++
> > Documentation/leds/leds-lp5523.txt | 130 ----------
> > Documentation/leds/leds-lp5562.rst | 137 +++++++++++
> > Documentation/leds/leds-lp5562.txt | 120 ----------
> > Documentation/leds/leds-lp55xx.rst | 224 ++++++++++++++++++
> > Documentation/leds/leds-lp55xx.txt | 194 ---------------
> > Documentation/leds/leds-mlxcpld.rst | 118 +++++++++
> > Documentation/leds/leds-mlxcpld.txt | 110 ---------
> > ...edtrig-oneshot.txt => ledtrig-oneshot.rst} | 11 +-
> > ...ig-transient.txt => ledtrig-transient.rst} | 63 +++--
> > ...edtrig-usbport.txt => ledtrig-usbport.rst} | 11 +-
> > Documentation/leds/{uleds.txt => uleds.rst} | 5 +-
> > MAINTAINERS | 2 +-
> > drivers/leds/trigger/Kconfig | 2 +-
> > drivers/leds/trigger/ledtrig-transient.c | 2 +-
> > net/netfilter/Kconfig | 2 +-
> > 25 files changed, 996 insertions(+), 778 deletions(-)
> > create mode 100644 Documentation/leds/index.rst
> > rename Documentation/leds/{leds-blinkm.txt => leds-blinkm.rst} (57%)
> > rename Documentation/leds/{leds-class-flash.txt => leds-class-flash.rst} (74%)
> > rename Documentation/leds/{leds-class.txt => leds-class.rst} (92%)
> > rename Documentation/leds/{leds-lm3556.txt => leds-lm3556.rst} (70%)
> > rename Documentation/leds/{leds-lp3944.txt => leds-lp3944.rst} (78%)
> > create mode 100644 Documentation/leds/leds-lp5521.rst
> > delete mode 100644 Documentation/leds/leds-lp5521.txt
> > create mode 100644 Documentation/leds/leds-lp5523.rst
> > delete mode 100644 Documentation/leds/leds-lp5523.txt
> > create mode 100644 Documentation/leds/leds-lp5562.rst
> > delete mode 100644 Documentation/leds/leds-lp5562.txt
> > create mode 100644 Documentation/leds/leds-lp55xx.rst
> > delete mode 100644 Documentation/leds/leds-lp55xx.txt
> > create mode 100644 Documentation/leds/leds-mlxcpld.rst
> > delete mode 100644 Documentation/leds/leds-mlxcpld.txt
> > rename Documentation/leds/{ledtrig-oneshot.txt => ledtrig-oneshot.rst} (90%)
> > rename Documentation/leds/{ledtrig-transient.txt => ledtrig-transient.rst} (81%)
> > rename Documentation/leds/{ledtrig-usbport.txt => ledtrig-usbport.rst} (86%)
> > rename Documentation/leds/{uleds.txt => uleds.rst} (95%)
>
> Patches 4/9 and 24/43 applied to the for-next branch of linux-leds.git.
Thanks!
I'll keep this one on my tree:
[PATCH 10/39] docs: leds: add it to the driver-api book
From the other series. If everything goes well, either Jon or I should
be sending upstream by the end of the merge window, after rebasing it,
together with a bunch of other patches touching the driver-api index.rst.
That should hopefully avoid merge conflicts.
Regards,
Mauro
^ permalink raw reply
* Re: [PATCH][next] 6lowpan: fix off-by-one comparison of index id with LOWPAN_IPHC_CTX_TABLE_SIZE
From: Marcel Holtmann @ 2019-07-06 10:51 UTC (permalink / raw)
To: Colin King
Cc: Alexander Aring, Jukka Rissanen, David S. Miller, linux-bluetooth,
linux-wpan, netdev, kernel-janitors, linux-kernel
In-Reply-To: <20190624144757.1285-1-colin.king@canonical.com>
Hi Colin,
> The WARN_ON_ONCE check on id is off-by-one, it should be greater or equal
> to LOWPAN_IPHC_CTX_TABLE_SIZE and not greater than. Fix this.
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> ---
> net/6lowpan/debugfs.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/6lowpan/debugfs.c b/net/6lowpan/debugfs.c
> index 1c140af06d52..a510bed8165b 100644
> --- a/net/6lowpan/debugfs.c
> +++ b/net/6lowpan/debugfs.c
> @@ -170,7 +170,7 @@ static void lowpan_dev_debugfs_ctx_init(struct net_device *dev,
> struct dentry *root;
> char buf[32];
>
> - WARN_ON_ONCE(id > LOWPAN_IPHC_CTX_TABLE_SIZE);
> + WARN_ON_ONCE(id >= LOWPAN_IPHC_CTX_TABLE_SIZE);
this patch no longer applied cleanly to bluetooth-next. Can you send me an updated version.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH v6 1/2] Bluetooth: hci_qca: Load customized NVM based on the device property
From: Marcel Holtmann @ 2019-07-06 10:51 UTC (permalink / raw)
To: Rocky Liao
Cc: robh+dt, mark.rutland, Johan Hedberg, thierry.escande, netdev,
devicetree, linux-kernel, linux-bluetooth, linux-arm-msm,
bgodavar, c-hbandi
In-Reply-To: <1559814030-13833-1-git-send-email-rjliao@codeaurora.org>
Hi Rocky,
> QCA BTSOC NVM is a customized firmware file and different vendors may
> want to have different BTSOC configuration (e.g. Configure SCO over PCM
> or I2S, Setting Tx power, etc.) via this file. This patch will allow
> vendors to download different NVM firmware file by reading a device
> property "firmware-name".
>
> Signed-off-by: Rocky Liao <rjliao@codeaurora.org>
> ---
> Changes in v6:
> * Added read firmware-name property for both QCA6174 and WCN399X
> ---
> drivers/bluetooth/btqca.c | 8 ++++++--
> drivers/bluetooth/btqca.h | 6 ++++--
> drivers/bluetooth/hci_qca.c | 18 +++++++++++++++++-
> 3 files changed, 27 insertions(+), 5 deletions(-)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ 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