* [RFC net-next 2/4] net: Prepare EnOcean device drivers
From: Andreas Färber @ 2019-01-29 5:01 UTC (permalink / raw)
To: linux-lpwan, linux-wpan
Cc: Alexander Aring, Stefan Schmidt, netdev, linux-kernel, support,
Andreas Färber
In-Reply-To: <20190129050130.10932-1-afaerber@suse.de>
Add net_device helpers for EnOcean.
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
drivers/net/enocean/Makefile | 2 +
drivers/net/enocean/enocean.c | 124 ++++++++++++++++++++++++++++++++++++++++++
include/linux/enocean/dev.h | 23 ++++++++
3 files changed, 149 insertions(+)
create mode 100644 drivers/net/enocean/Makefile
create mode 100644 drivers/net/enocean/enocean.c
create mode 100644 include/linux/enocean/dev.h
diff --git a/drivers/net/enocean/Makefile b/drivers/net/enocean/Makefile
new file mode 100644
index 000000000000..efb3cd16c7f2
--- /dev/null
+++ b/drivers/net/enocean/Makefile
@@ -0,0 +1,2 @@
+obj-m += enocean-dev.o
+enocean-dev-y := enocean.o
diff --git a/drivers/net/enocean/enocean.c b/drivers/net/enocean/enocean.c
new file mode 100644
index 000000000000..087a4de274c8
--- /dev/null
+++ b/drivers/net/enocean/enocean.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * EnOcean net device
+ *
+ * Copyright (c) 2019 Andreas Färber
+ */
+
+#include <linux/enocean/dev.h>
+#include <linux/if_arp.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <net/rtnetlink.h>
+
+int open_enocean_dev(struct net_device *dev)
+{
+ if (!netif_carrier_ok(dev))
+ netif_carrier_on(dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(open_enocean_dev);
+
+void close_enocean_dev(struct net_device *dev)
+{
+}
+EXPORT_SYMBOL_GPL(close_enocean_dev);
+
+static void enocean_setup(struct net_device *dev)
+{
+ dev->type = ARPHRD_ENOCEAN;
+ dev->mtu = 255; /* XXX */
+ dev->hard_header_len = 0;
+ dev->addr_len = 0; /* XXX 4 */
+ dev->tx_queue_len = 10;
+
+ dev->flags = IFF_NOARP;
+ dev->features = 0;
+}
+
+struct net_device *alloc_enocean_dev(size_t priv_size)
+{
+ struct enocean_dev_priv *priv;
+ struct net_device *netdev;
+
+ netdev = alloc_netdev(priv_size, "enocean%d", NET_NAME_UNKNOWN, enocean_setup);
+ if (!netdev)
+ return NULL;
+
+ priv = netdev_priv(netdev);
+ priv->dev = netdev;
+
+ return netdev;
+}
+EXPORT_SYMBOL_GPL(alloc_enocean_dev);
+
+void free_enocean_dev(struct net_device *netdev)
+{
+ free_netdev(netdev);
+}
+EXPORT_SYMBOL_GPL(free_enocean_dev);
+
+static void devm_free_enocean_dev(struct device *dev, void *res)
+{
+ struct net_device **net = res;
+
+ free_enocean_dev(*net);
+}
+
+struct net_device *devm_alloc_enocean_dev(struct device *dev, size_t priv)
+{
+ struct net_device **ptr;
+ struct net_device *net;
+
+ net = alloc_enocean_dev(priv);
+ if (!net)
+ return NULL;
+
+ ptr = devres_alloc(devm_free_enocean_dev, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr) {
+ free_enocean_dev(net);
+ return NULL;
+ }
+
+ *ptr = net;
+ devres_add(dev, ptr);
+
+ return net;
+}
+EXPORT_SYMBOL_GPL(devm_alloc_enocean_dev);
+
+static struct rtnl_link_ops enocean_link_ops __read_mostly = {
+ .kind = "enocean",
+ .setup = enocean_setup,
+};
+
+int register_enocean_dev(struct net_device *dev)
+{
+ dev->rtnl_link_ops = &enocean_link_ops;
+ return register_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(register_enocean_dev);
+
+void unregister_enocean_dev(struct net_device *dev)
+{
+ unregister_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(unregister_enocean_dev);
+
+static int __init enocean_dev_init(void)
+{
+ return rtnl_link_register(&enocean_link_ops);
+}
+module_init(enocean_dev_init);
+
+static void __exit enocean_dev_exit(void)
+{
+ rtnl_link_unregister(&enocean_link_ops);
+}
+module_exit(enocean_dev_exit);
+
+MODULE_DESCRIPTION("EnOcean device driver interface");
+MODULE_ALIAS_RTNL_LINK("enocean");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Andreas Färber");
diff --git a/include/linux/enocean/dev.h b/include/linux/enocean/dev.h
new file mode 100644
index 000000000000..be9d37cdde37
--- /dev/null
+++ b/include/linux/enocean/dev.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * linux/enocean/dev.h
+ *
+ * Copyright (c) 2019 Andreas Färber
+ */
+#ifndef _ENOCEAN_DEV_H
+#define _ENOCEAN_DEV_H
+
+#include <linux/netdevice.h>
+
+struct net_device *alloc_enocean_dev(size_t priv_size);
+struct net_device *devm_alloc_enocean_dev(struct device *dev, size_t priv_size);
+int register_enocean_dev(struct net_device *netdev);
+void unregister_enocean_dev(struct net_device *netdev);
+int open_enocean_dev(struct net_device *netdev);
+void close_enocean_dev(struct net_device *netdev);
+
+struct enocean_dev_priv {
+ struct net_device *dev;
+};
+
+#endif
--
2.16.4
^ permalink raw reply related
* [PATCH] kernel/bpf/core.c - fix bitrotted kerneldoc.
From: valdis.kletnieks @ 2019-01-29 4:04 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann; +Cc: netdev, linux-kernel
Over the years, the function signature has changed, the kerneldoc block hasn't.
Signed-off-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 2a81b8af3748..2728b6247091 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -1216,8 +1216,9 @@ bool bpf_opcode_in_insntable(u8 code)
#ifndef CONFIG_BPF_JIT_ALWAYS_ON
/**
* __bpf_prog_run - run eBPF program on a given context
- * @ctx: is the data we are operating on
+ * @regs: is the array of MAX_BPF_EXT_REG eBPF pseudo-registers
* @insn: is the array of eBPF instructions
+ * @stack: is the eBPF storage stack
*
* Decode and execute eBPF instructions.
*/
^ permalink raw reply related
* Re: [PATCH bpf] bpf, doc: add reviewers to maintainers entry
From: Alexei Starovoitov @ 2019-01-29 4:04 UTC (permalink / raw)
To: Song Liu
Cc: Daniel Borkmann, Alexei Starovoitov, netdev@vger.kernel.org,
Martin Lau, Yonghong Song
In-Reply-To: <4D178736-570A-4D43-B8AF-4846D525EA63@fb.com>
On Tue, Jan 29, 2019 at 03:08:54AM +0000, Song Liu wrote:
>
>
> > On Jan 28, 2019, at 2:55 PM, Daniel Borkmann <daniel@iogearbox.net> wrote:
> >
> > In order to better scale BPF development on netdev, we've adopted a
> > reviewer rotation for all BPF patches among the five of us for some
> > time now. Lets give credit where credit is due, and add Martin, Song
> > and Yonghong as official BPF reviewers to MAINTAINERS file. Also
> > while at it, add regex matching for BPF such that we get properly
> > Cc'ed for files not listed here.
> >
> > Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
>
> Thanks!
>
> Acked-by: Song Liu <songliubraving@fb.com>
Applied to bpf tree. Thanks!
^ permalink raw reply
* Re: [PATCH net-next] net: udp Allow CHECKSUM_UNNECESSARY packets to do GRO.
From: Tom Herbert @ 2019-01-29 4:01 UTC (permalink / raw)
To: maowenan; +Cc: Linux Kernel Network Developers, David S. Miller, Eric Dumazet
In-Reply-To: <b3bdb7c7-17dd-ac52-ff8e-4e312ccaaaa8@huawei.com>
On Mon, Jan 28, 2019 at 7:00 PM maowenan <maowenan@huawei.com> wrote:
>
> Hi all,
> Do you have any comments about this change?
>
>
> On 2019/1/23 11:33, Mao Wenan wrote:
> > When udp4_gro_receive() get one packet that uh->check=0,
> > skb_gro_checksum_validate_zero_check() will set the
> > skb->ip_summed = CHECKSUM_UNNECESSARY;
> > skb->csum_level = 0;
> > Then udp_gro_receive() will flush the packet which is not CHECKSUM_PARTIAL,
> > It is not our expect, because check=0 in udp header indicates this
> > packet is no need to caculate checksum, we should go further to do GRO.
> >
> > This patch changes the value of csum_cnt according to skb->csum_level.
> > ---
> > include/linux/netdevice.h | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> > index 1377d08..9c819f1 100644
> > --- a/include/linux/netdevice.h
> > +++ b/include/linux/netdevice.h
> > @@ -2764,6 +2764,7 @@ static inline void skb_gro_incr_csum_unnecessary(struct sk_buff *skb)
> > * during GRO. This saves work if we fallback to normal path.
> > */
> > __skb_incr_checksum_unnecessary(skb);
> > + NAPI_GRO_CB(skb)->csum_cnt = skb->csum_level + 1;
That doesn't look right. This would be reinitializing the GRO
checksums from the beginning.
> > }
> > }
> >
> >
>
I assume the code is bailing on this conditional:
if (NAPI_GRO_CB(skb)->encap_mark ||
(skb->ip_summed != CHECKSUM_PARTIAL &&
NAPI_GRO_CB(skb)->csum_cnt == 0 &&
!NAPI_GRO_CB(skb)->csum_valid) ||
!udp_sk(sk)->gro_receive)
goto out_unlock;
I am trying to remember why this needs to check csum_cnt. If there was
a csum_cnt for the UDP csum being zero from checksum-unnecessary, it
was consumed by skb_gro_checksum_validate_zero_check in UDP4 GRO
received.
^ permalink raw reply
* Re: pull-request: bpf-next 2019-01-29
From: David Miller @ 2019-01-29 3:38 UTC (permalink / raw)
To: daniel; +Cc: ast, netdev
In-Reply-To: <20190129014627.22132-1-daniel@iogearbox.net>
From: Daniel Borkmann <daniel@iogearbox.net>
Date: Tue, 29 Jan 2019 02:46:27 +0100
> The following pull-request contains BPF updates for your *net-next* tree.
>
> The main changes are:
...
> Please consider pulling these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
Pulled, thanks Daniel!
^ permalink raw reply
* [PATCH net-next 7/7] ethtool: add compat for devlink info
From: Jakub Kicinski @ 2019-01-29 3:34 UTC (permalink / raw)
To: davem
Cc: netdev, oss-drivers, jiri, andrew, f.fainelli, mkubecek, eugenem,
jonathan.lemon, Jakub Kicinski
In-Reply-To: <20190129033420.27235-1-jakub.kicinski@netronome.com>
If driver did not fill the fw_version field, try to call into
the new devlink get_info op and collect the versions that way.
We assume ethtool was always reporting running versions.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
include/net/devlink.h | 7 ++++++
net/core/devlink.c | 52 ++++++++++++++++++++++++++++++++++++++++++-
net/core/ethtool.c | 7 ++++++
3 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 14da3632e8fc..b047360b88a9 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -616,6 +616,8 @@ int devlink_info_report_version(struct devlink_info_req *req,
enum devlink_version_type type,
const char *version_name,
const char *version_value);
+void devlink_compat_running_versions(struct net_device *dev,
+ char *buf, size_t len);
#else
@@ -896,6 +898,11 @@ devlink_info_report_version(struct devlink_info_req *req,
{
return 0;
}
+
+static inline void
+devlink_compat_running_versions(struct net_device *dev, char *buf, size_t len)
+{
+}
#endif
#endif /* _NET_DEVLINK_H_ */
diff --git a/net/core/devlink.c b/net/core/devlink.c
index f0c5f9bd96b7..99037bf15fb8 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -3598,12 +3598,18 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
}
struct devlink_info_req {
+ bool compat;
struct sk_buff *msg;
+ /* For compat call */
+ char *buf;
+ size_t len;
};
int devlink_info_report_driver_name(struct devlink_info_req *req,
const char *name)
{
+ if (req->compat)
+ return 0;
return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRV_NAME, name);
}
EXPORT_SYMBOL_GPL(devlink_info_report_driver_name);
@@ -3611,6 +3617,8 @@ EXPORT_SYMBOL_GPL(devlink_info_report_driver_name);
int devlink_info_report_serial_number(struct devlink_info_req *req,
const char *sn)
{
+ if (req->compat)
+ return 0;
return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
}
EXPORT_SYMBOL_GPL(devlink_info_report_serial_number);
@@ -3626,7 +3634,15 @@ int devlink_info_report_version(struct devlink_info_req *req,
[DEVLINK_VERSION_RUNNING] = DEVLINK_ATTR_INFO_VERSION_RUNNING,
};
struct nlattr *nest;
- int err;
+ int len, err;
+
+ if (req->compat) {
+ if (type == DEVLINK_VERSION_RUNNING) {
+ len = strlcpy(req->buf, version_value, req->len);
+ req->len = max_t(size_t, 0, req->len - len);
+ }
+ return 0;
+ }
if (type >= ARRAY_SIZE(type2attr) || !type2attr[type])
return -EINVAL;
@@ -3672,6 +3688,7 @@ devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
if (devlink_nl_put_handle(msg, devlink))
goto err_cancel_msg;
+ memset(&req, 0, sizeof(req));
req.msg = msg;
err = devlink->ops->info_get(devlink, &req, extack);
if (err)
@@ -4962,6 +4979,39 @@ int devlink_region_snapshot_create(struct devlink_region *region, u64 data_len,
}
EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
+void devlink_compat_running_versions(struct net_device *dev,
+ char *buf, size_t len)
+{
+ struct devlink_port *devlink_port;
+ struct devlink_info_req req;
+ struct devlink *devlink;
+ bool found = false;
+
+ mutex_lock(&devlink_mutex);
+ list_for_each_entry(devlink, &devlink_list, list) {
+ mutex_lock(&devlink->lock);
+ list_for_each_entry(devlink_port, &devlink->port_list, list) {
+ if (devlink_port->type == DEVLINK_PORT_TYPE_ETH ||
+ devlink_port->type_dev == dev) {
+ mutex_unlock(&devlink->lock);
+ found = true;
+ goto out;
+ }
+ }
+ mutex_unlock(&devlink->lock);
+ }
+out:
+ if (found && devlink->ops->info_get) {
+ memset(&req, 0, sizeof(req));
+ req.compat = true;
+ req.buf = buf;
+ req.len = len;
+
+ devlink->ops->info_get(devlink, &req, NULL);
+ }
+ mutex_unlock(&devlink_mutex);
+}
+
static int __init devlink_module_init(void)
{
return genl_register_family(&devlink_nl_family);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 158264f7cfaf..176b17d11f08 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -27,6 +27,7 @@
#include <linux/rtnetlink.h>
#include <linux/sched/signal.h>
#include <linux/net.h>
+#include <net/devlink.h>
#include <net/xdp_sock.h>
/*
@@ -803,6 +804,12 @@ static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
if (ops->get_eeprom_len)
info.eedump_len = ops->get_eeprom_len(dev);
+ rtnl_unlock();
+ if (!info.fw_version[0])
+ devlink_compat_running_versions(dev, info.fw_version,
+ ARRAY_SIZE(info.fw_version));
+ rtnl_lock();
+
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
--
2.19.2
^ permalink raw reply related
* [PATCH net-next 6/7] nfp: devlink: report the running and flashed versions
From: Jakub Kicinski @ 2019-01-29 3:34 UTC (permalink / raw)
To: davem
Cc: netdev, oss-drivers, jiri, andrew, f.fainelli, mkubecek, eugenem,
jonathan.lemon, Jakub Kicinski
In-Reply-To: <20190129033420.27235-1-jakub.kicinski@netronome.com>
Report versions of firmware components using the new NSP command.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
.../net/ethernet/netronome/nfp/nfp_devlink.c | 86 +++++++++++++++++++
include/net/devlink.h | 11 +++
2 files changed, 97 insertions(+)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
index 9857fa663adf..fade37d2b796 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
@@ -207,11 +207,59 @@ nfp_devlink_versions_get_hwinfo(struct nfp_pf *pf, struct devlink_info_req *req)
return 0;
}
+static const struct nfp_devlink_versions {
+ enum nfp_nsp_versions id;
+ const char *key;
+} nfp_devlink_versions_nsp[] = {
+ { NFP_VERSIONS_BUNDLE, "fw.bundle_id", },
+ { NFP_VERSIONS_BSP, DEVLINK_VERSION_GENERIC_FW_MGMT, },
+ { NFP_VERSIONS_CPLD, "fw.cpld", },
+ { NFP_VERSIONS_APP, DEVLINK_VERSION_GENERIC_FW_APP, },
+ { NFP_VERSIONS_UNDI, DEVLINK_VERSION_GENERIC_FW_UNDI, },
+ { NFP_VERSIONS_NCSI, DEVLINK_VERSION_GENERIC_FW_NCSI, },
+ { NFP_VERSIONS_CFGR, "chip.init", },
+};
+
+static int
+nfp_devlink_versions_get_nsp(struct devlink_info_req *req, bool flash,
+ const u8 *buf, unsigned int size)
+{
+ enum devlink_version_type type;
+ unsigned int i;
+ int err;
+
+ type = flash ? DEVLINK_VERSION_STORED : DEVLINK_VERSION_RUNNING;
+
+ for (i = 0; i < ARRAY_SIZE(nfp_devlink_versions_nsp); i++) {
+ const struct nfp_devlink_versions *info;
+ const char *version;
+
+ info = &nfp_devlink_versions_nsp[i];
+
+ version = nfp_nsp_versions_get(info->id, flash, buf, size);
+ if (IS_ERR(version)) {
+ if (PTR_ERR(version) == -ENOENT)
+ continue;
+ else
+ return PTR_ERR(version);
+ }
+
+ err = devlink_info_report_version(req, type,
+ info->key, version);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
static int
nfp_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
struct netlink_ext_ack *extack)
{
struct nfp_pf *pf = devlink_priv(devlink);
+ struct nfp_nsp *nsp;
+ char *buf = NULL;
const char *sn;
int err;
@@ -226,7 +274,45 @@ nfp_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
return err;
}
+ nsp = nfp_nsp_open(pf->cpp);
+ if (IS_ERR(nsp)) {
+ NL_SET_ERR_MSG_MOD(extack, "can't access NSP");
+ return PTR_ERR(nsp);
+ }
+
+ if (nfp_nsp_has_versions(nsp)) {
+ buf = kzalloc(NFP_NSP_VERSION_BUFSZ, GFP_KERNEL);
+ if (!buf) {
+ err = -ENOMEM;
+ goto err_close_nsp;
+ }
+
+ err = nfp_nsp_versions(nsp, buf, NFP_NSP_VERSION_BUFSZ);
+ if (err)
+ goto err_free_buf;
+
+ err = nfp_devlink_versions_get_nsp(req, false,
+ buf, NFP_NSP_VERSION_BUFSZ);
+ if (err)
+ goto err_free_buf;
+
+ err = nfp_devlink_versions_get_nsp(req, true,
+ buf, NFP_NSP_VERSION_BUFSZ);
+ if (err)
+ goto err_free_buf;
+
+ kfree(buf);
+ }
+
+ nfp_nsp_close(nsp);
+
return nfp_devlink_versions_get_hwinfo(pf, req);
+
+err_free_buf:
+ kfree(buf);
+err_close_nsp:
+ nfp_nsp_close(nsp);
+ return err;
}
const struct devlink_ops nfp_devlink_ops = {
diff --git a/include/net/devlink.h b/include/net/devlink.h
index dc08301028a9..14da3632e8fc 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -424,6 +424,17 @@ enum devlink_param_generic_id {
/* Revision of board design */
#define DEVLINK_VERSION_GENERIC_BOARD_REV "board.rev"
+/* Control processor FW version, FW is responsible for house keeping tasks,
+ * PHY control etc.
+ */
+#define DEVLINK_VERSION_GENERIC_FW_MGMT "fw.mgmt"
+/* Data path microcode controlling high-speed packet processing */
+#define DEVLINK_VERSION_GENERIC_FW_APP "fw.app"
+/* UNDI software version */
+#define DEVLINK_VERSION_GENERIC_FW_UNDI "fw.undi"
+/* NCSI support/handler version */
+#define DEVLINK_VERSION_GENERIC_FW_NCSI "fw.ncsi"
+
enum devlink_version_type {
DEVLINK_VERSION_FIXED,
DEVLINK_VERSION_STORED,
--
2.19.2
^ permalink raw reply related
* [PATCH net-next 5/7] nfp: nsp: add support for versions command
From: Jakub Kicinski @ 2019-01-29 3:34 UTC (permalink / raw)
To: davem
Cc: netdev, oss-drivers, jiri, andrew, f.fainelli, mkubecek, eugenem,
jonathan.lemon, Jakub Kicinski
In-Reply-To: <20190129033420.27235-1-jakub.kicinski@netronome.com>
Retrieve the FW versions with the new command.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
.../ethernet/netronome/nfp/nfpcore/nfp_nsp.c | 61 +++++++++++++++++++
.../ethernet/netronome/nfp/nfpcore/nfp_nsp.h | 20 ++++++
2 files changed, 81 insertions(+)
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
index ce1577bbbd2a..a9d53df0070c 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
@@ -7,6 +7,7 @@
* Jason McMullan <jason.mcmullan@netronome.com>
*/
+#include <asm/unaligned.h>
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/firmware.h>
@@ -62,6 +63,16 @@
#define NFP_HWINFO_LOOKUP_SIZE GENMASK(11, 0)
+#define NFP_VERSIONS_SIZE GENMASK(11, 0)
+#define NFP_VERSIONS_CNT_OFF 0
+#define NFP_VERSIONS_BSP_OFF 2
+#define NFP_VERSIONS_CPLD_OFF 6
+#define NFP_VERSIONS_APP_OFF 10
+#define NFP_VERSIONS_BUNDLE_OFF 14
+#define NFP_VERSIONS_UNDI_OFF 18
+#define NFP_VERSIONS_NCSI_OFF 22
+#define NFP_VERSIONS_CFGR_OFF 26
+
enum nfp_nsp_cmd {
SPCODE_NOOP = 0, /* No operation */
SPCODE_SOFT_RESET = 1, /* Soft reset the NFP */
@@ -77,6 +88,7 @@ enum nfp_nsp_cmd {
SPCODE_NSP_IDENTIFY = 13, /* Read NSP version */
SPCODE_FW_STORED = 16, /* If no FW loaded, load flash app FW */
SPCODE_HWINFO_LOOKUP = 17, /* Lookup HWinfo with overwrites etc. */
+ SPCODE_VERSIONS = 21, /* Report FW versions */
};
static const struct {
@@ -711,3 +723,52 @@ int nfp_nsp_hwinfo_lookup(struct nfp_nsp *state, void *buf, unsigned int size)
return 0;
}
+
+int nfp_nsp_versions(struct nfp_nsp *state, void *buf, unsigned int size)
+{
+ struct nfp_nsp_command_buf_arg versions = {
+ {
+ .code = SPCODE_VERSIONS,
+ .option = min_t(u32, size, NFP_VERSIONS_SIZE),
+ },
+ .out_buf = buf,
+ .out_size = min_t(u32, size, NFP_VERSIONS_SIZE),
+ };
+
+ return nfp_nsp_command_buf(state, &versions);
+}
+
+const char *nfp_nsp_versions_get(enum nfp_nsp_versions id, bool flash,
+ const u8 *buf, unsigned int size)
+{
+ static const u32 id2off[] = {
+ [NFP_VERSIONS_BSP] = NFP_VERSIONS_BSP_OFF,
+ [NFP_VERSIONS_CPLD] = NFP_VERSIONS_CPLD_OFF,
+ [NFP_VERSIONS_APP] = NFP_VERSIONS_APP_OFF,
+ [NFP_VERSIONS_BUNDLE] = NFP_VERSIONS_BUNDLE_OFF,
+ [NFP_VERSIONS_UNDI] = NFP_VERSIONS_UNDI_OFF,
+ [NFP_VERSIONS_NCSI] = NFP_VERSIONS_NCSI_OFF,
+ [NFP_VERSIONS_CFGR] = NFP_VERSIONS_CFGR_OFF,
+ };
+ unsigned int field, buf_field_cnt, buf_off;
+
+ if (id >= ARRAY_SIZE(id2off) || !id2off[id])
+ return ERR_PTR(-EINVAL);
+
+ field = id * 2 + flash;
+
+ buf_field_cnt = get_unaligned_le16(buf);
+ if (buf_field_cnt <= field)
+ return ERR_PTR(-ENOENT);
+
+ buf_off = get_unaligned_le16(buf + id2off[id] + flash * 2);
+ if (!buf_off)
+ return ERR_PTR(-ENOENT);
+
+ if (buf_off >= size)
+ return ERR_PTR(-EINVAL);
+ if (strnlen(&buf[buf_off], size - buf_off) == size - buf_off)
+ return ERR_PTR(-EINVAL);
+
+ return (const char *)&buf[buf_off];
+}
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h
index ff33ac54097a..246e213f1514 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h
@@ -38,6 +38,11 @@ static inline bool nfp_nsp_has_hwinfo_lookup(struct nfp_nsp *state)
return nfp_nsp_get_abi_ver_minor(state) > 24;
}
+static inline bool nfp_nsp_has_versions(struct nfp_nsp *state)
+{
+ return nfp_nsp_get_abi_ver_minor(state) > 27;
+}
+
enum nfp_eth_interface {
NFP_INTERFACE_NONE = 0,
NFP_INTERFACE_SFP = 1,
@@ -208,4 +213,19 @@ enum nfp_nsp_sensor_id {
int nfp_hwmon_read_sensor(struct nfp_cpp *cpp, enum nfp_nsp_sensor_id id,
long *val);
+#define NFP_NSP_VERSION_BUFSZ 1024 /* reasonable size, not in the ABI */
+
+enum nfp_nsp_versions {
+ NFP_VERSIONS_BSP,
+ NFP_VERSIONS_CPLD,
+ NFP_VERSIONS_APP,
+ NFP_VERSIONS_BUNDLE,
+ NFP_VERSIONS_UNDI,
+ NFP_VERSIONS_NCSI,
+ NFP_VERSIONS_CFGR,
+};
+
+int nfp_nsp_versions(struct nfp_nsp *state, void *buf, unsigned int size);
+const char *nfp_nsp_versions_get(enum nfp_nsp_versions id, bool flash,
+ const u8 *buf, unsigned int size);
#endif
--
2.19.2
^ permalink raw reply related
* [PATCH net-next 4/7] nfp: devlink: report fixed versions
From: Jakub Kicinski @ 2019-01-29 3:34 UTC (permalink / raw)
To: davem
Cc: netdev, oss-drivers, jiri, andrew, f.fainelli, mkubecek, eugenem,
jonathan.lemon, Jakub Kicinski
In-Reply-To: <20190129033420.27235-1-jakub.kicinski@netronome.com>
Report information about the hardware.
RFCv2:
- add defines for board IDs which are likely to be reusable for
other drivers (Jiri).
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
.../net/ethernet/netronome/nfp/nfp_devlink.c | 37 ++++++++++++++++++-
include/net/devlink.h | 5 +++
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
index cb3ef7e46614..9857fa663adf 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
@@ -172,6 +172,41 @@ static int nfp_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
return ret;
}
+static const struct nfp_devlink_versions_simple {
+ const char *key;
+ const char *hwinfo;
+} nfp_devlink_versions_hwinfo[] = {
+ { DEVLINK_VERSION_GENERIC_BOARD_ID, "assembly.partno", },
+ { DEVLINK_VERSION_GENERIC_BOARD_REV, "assembly.revision", },
+ { "board.vendor", /* fab */ "assembly.vendor", },
+ { "board.model", /* code name */ "assembly.model", },
+};
+
+static int
+nfp_devlink_versions_get_hwinfo(struct nfp_pf *pf, struct devlink_info_req *req)
+{
+ unsigned int i;
+ int err;
+
+ for (i = 0; i < ARRAY_SIZE(nfp_devlink_versions_hwinfo); i++) {
+ const struct nfp_devlink_versions_simple *info;
+ const char *val;
+
+ info = &nfp_devlink_versions_hwinfo[i];
+
+ val = nfp_hwinfo_lookup(pf->hwinfo, info->hwinfo);
+ if (!val)
+ continue;
+
+ err = devlink_info_report_version(req, DEVLINK_VERSION_FIXED,
+ info->key, val);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
static int
nfp_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
struct netlink_ext_ack *extack)
@@ -191,7 +226,7 @@ nfp_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
return err;
}
- return 0;
+ return nfp_devlink_versions_get_hwinfo(pf, req);
}
const struct devlink_ops nfp_devlink_ops = {
diff --git a/include/net/devlink.h b/include/net/devlink.h
index f53ace3ac4b3..dc08301028a9 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -419,6 +419,11 @@ enum devlink_param_generic_id {
.validate = _validate, \
}
+/* Part number, identifier of board design */
+#define DEVLINK_VERSION_GENERIC_BOARD_ID "board.id"
+/* Revision of board design */
+#define DEVLINK_VERSION_GENERIC_BOARD_REV "board.rev"
+
enum devlink_version_type {
DEVLINK_VERSION_FIXED,
DEVLINK_VERSION_STORED,
--
2.19.2
^ permalink raw reply related
* [PATCH net-next 3/7] nfp: devlink: report driver name and serial number
From: Jakub Kicinski @ 2019-01-29 3:34 UTC (permalink / raw)
To: davem
Cc: netdev, oss-drivers, jiri, andrew, f.fainelli, mkubecek, eugenem,
jonathan.lemon, Jakub Kicinski
In-Reply-To: <20190129033420.27235-1-jakub.kicinski@netronome.com>
Report the basic info through new devlink info API.
RFCv2:
- add driver name;
- align serial to core changes.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
.../net/ethernet/netronome/nfp/nfp_devlink.c | 24 +++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
index 808647ec3573..cb3ef7e46614 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
@@ -4,6 +4,7 @@
#include <linux/rtnetlink.h>
#include <net/devlink.h>
+#include "nfpcore/nfp.h"
#include "nfpcore/nfp_nsp.h"
#include "nfp_app.h"
#include "nfp_main.h"
@@ -171,6 +172,28 @@ static int nfp_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
return ret;
}
+static int
+nfp_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
+ struct netlink_ext_ack *extack)
+{
+ struct nfp_pf *pf = devlink_priv(devlink);
+ const char *sn;
+ int err;
+
+ err = devlink_info_report_driver_name(req, "nfp");
+ if (err)
+ return err;
+
+ sn = nfp_hwinfo_lookup(pf->hwinfo, "assembly.serial");
+ if (sn) {
+ err = devlink_info_report_serial_number(req, sn);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
const struct devlink_ops nfp_devlink_ops = {
.port_split = nfp_devlink_port_split,
.port_unsplit = nfp_devlink_port_unsplit,
@@ -178,6 +201,7 @@ const struct devlink_ops nfp_devlink_ops = {
.sb_pool_set = nfp_devlink_sb_pool_set,
.eswitch_mode_get = nfp_devlink_eswitch_mode_get,
.eswitch_mode_set = nfp_devlink_eswitch_mode_set,
+ .info_get = nfp_devlink_info_get,
};
int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
--
2.19.2
^ permalink raw reply related
* [PATCH net-next 2/7] devlink: add version reporting to devlink info API
From: Jakub Kicinski @ 2019-01-29 3:34 UTC (permalink / raw)
To: davem
Cc: netdev, oss-drivers, jiri, andrew, f.fainelli, mkubecek, eugenem,
jonathan.lemon, Jakub Kicinski
In-Reply-To: <20190129033420.27235-1-jakub.kicinski@netronome.com>
ethtool -i has a few fixed-size fields which can be used to report
firmware version and expansion ROM version. Unfortunately, modern
hardware has more firmware components. There is usually some
datapath microcode, management controller, PXE drivers, and a
CPLD load. Running ethtool -i on modern controllers reveals the
fact that vendors cram multiple values into firmware version field.
Here are some examples from systems I could lay my hands on quickly:
tg3: "FFV20.2.17 bc 5720-v1.39"
i40e: "6.01 0x800034a4 1.1747.0"
nfp: "0.0.3.5 0.25 sriov-2.1.16 nic"
Add a new devlink API to allow retrieving multiple versions, and
provide user-readable name for those versions.
While at it break down the versions into three categories:
- fixed - this is the board/fixed component version, usually vendors
report information like the board version in the PCI VPD,
but it will benefit from naming and common API as well;
- running - this is the running firmware version;
- stored - this is firmware in the flash, after firmware update
this value will reflect the flashed version, while the
running version may only be updated after reboot.
RFCv2:
- remove the nesting in attr DEVLINK_ATTR_INFO_VERSIONS (now
versions are mixed with other info attrs)l
- have the driver report versions from the same callback as
other info.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
include/net/devlink.h | 18 ++++++++++++++++
include/uapi/linux/devlink.h | 5 +++++
net/core/devlink.c | 40 ++++++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index d8d425028d55..f53ace3ac4b3 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -419,6 +419,12 @@ enum devlink_param_generic_id {
.validate = _validate, \
}
+enum devlink_version_type {
+ DEVLINK_VERSION_FIXED,
+ DEVLINK_VERSION_STORED,
+ DEVLINK_VERSION_RUNNING,
+};
+
struct devlink_region;
struct devlink_info_req;
@@ -590,6 +596,10 @@ int devlink_info_report_serial_number(struct devlink_info_req *req,
const char *sn);
int devlink_info_report_driver_name(struct devlink_info_req *req,
const char *name);
+int devlink_info_report_version(struct devlink_info_req *req,
+ enum devlink_version_type type,
+ const char *version_name,
+ const char *version_value);
#else
@@ -862,6 +872,14 @@ devlink_info_report_serial_number(struct devlink_info_req *req, const char *sn)
{
return 0;
}
+
+static inline int
+devlink_info_report_version(struct devlink_info_req *req,
+ enum devlink_version_type type,
+ const char *version_name, const char *version_value)
+{
+ return 0;
+}
#endif
#endif /* _NET_DEVLINK_H_ */
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index c4b5d923f59f..e8d449a203ec 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -289,6 +289,11 @@ enum devlink_attr {
DEVLINK_ATTR_INFO_DRV_NAME, /* string */
DEVLINK_ATTR_INFO_SERIAL_NUMBER, /* string */
+ DEVLINK_ATTR_INFO_VERSION_FIXED, /* nested */
+ DEVLINK_ATTR_INFO_VERSION_RUNNING, /* nested */
+ DEVLINK_ATTR_INFO_VERSION_STORED, /* nested */
+ DEVLINK_ATTR_INFO_VERSION_NAME, /* string */
+ DEVLINK_ATTR_INFO_VERSION_VALUE, /* string */
/* add new attributes above here, update the policy in devlink.c */
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 844e086ff038..f0c5f9bd96b7 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -3615,6 +3615,46 @@ int devlink_info_report_serial_number(struct devlink_info_req *req,
}
EXPORT_SYMBOL_GPL(devlink_info_report_serial_number);
+int devlink_info_report_version(struct devlink_info_req *req,
+ enum devlink_version_type type,
+ const char *version_name,
+ const char *version_value)
+{
+ static const enum devlink_attr type2attr[] = {
+ [DEVLINK_VERSION_FIXED] = DEVLINK_ATTR_INFO_VERSION_FIXED,
+ [DEVLINK_VERSION_STORED] = DEVLINK_ATTR_INFO_VERSION_STORED,
+ [DEVLINK_VERSION_RUNNING] = DEVLINK_ATTR_INFO_VERSION_RUNNING,
+ };
+ struct nlattr *nest;
+ int err;
+
+ if (type >= ARRAY_SIZE(type2attr) || !type2attr[type])
+ return -EINVAL;
+
+ nest = nla_nest_start(req->msg, type2attr[type]);
+ if (!nest)
+ return -EMSGSIZE;
+
+ err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
+ version_name);
+ if (err)
+ goto nla_put_failure;
+
+ err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
+ version_value);
+ if (err)
+ goto nla_put_failure;
+
+ nla_nest_end(req->msg, nest);
+
+ return 0;
+
+nla_put_failure:
+ nla_nest_cancel(req->msg, nest);
+ return err;
+}
+EXPORT_SYMBOL_GPL(devlink_info_report_version);
+
static int
devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
enum devlink_command cmd, u32 portid,
--
2.19.2
^ permalink raw reply related
* [PATCH net-next 1/7] devlink: add device information API
From: Jakub Kicinski @ 2019-01-29 3:34 UTC (permalink / raw)
To: davem
Cc: netdev, oss-drivers, jiri, andrew, f.fainelli, mkubecek, eugenem,
jonathan.lemon, Jakub Kicinski
In-Reply-To: <20190129033420.27235-1-jakub.kicinski@netronome.com>
ethtool -i has served us well for a long time, but its showing
its limitations more and more. The device information should
also be reported per device not per-netdev.
Lay foundation for a simple devlink-based way of reading device
info. Add driver name and device serial number as initial pieces
of information exposed via this new API.
RFC v2:
- wrap the skb into an opaque structure (Jiri);
- allow the serial number of be any length (Jiri & Andrew);
- add driver name (Jonathan).
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
include/net/devlink.h | 18 ++++++
include/uapi/linux/devlink.h | 5 ++
net/core/devlink.c | 114 +++++++++++++++++++++++++++++++++++
3 files changed, 137 insertions(+)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 67f4293bc970..d8d425028d55 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -420,6 +420,7 @@ enum devlink_param_generic_id {
}
struct devlink_region;
+struct devlink_info_req;
typedef void devlink_snapshot_data_dest_t(const void *data);
@@ -475,6 +476,8 @@ struct devlink_ops {
int (*eswitch_encap_mode_get)(struct devlink *devlink, u8 *p_encap_mode);
int (*eswitch_encap_mode_set)(struct devlink *devlink, u8 encap_mode,
struct netlink_ext_ack *extack);
+ int (*info_get)(struct devlink *devlink, struct devlink_info_req *req,
+ struct netlink_ext_ack *extack);
};
static inline void *devlink_priv(struct devlink *devlink)
@@ -583,6 +586,10 @@ u32 devlink_region_shapshot_id_get(struct devlink *devlink);
int devlink_region_snapshot_create(struct devlink_region *region, u64 data_len,
u8 *data, u32 snapshot_id,
devlink_snapshot_data_dest_t *data_destructor);
+int devlink_info_report_serial_number(struct devlink_info_req *req,
+ const char *sn);
+int devlink_info_report_driver_name(struct devlink_info_req *req,
+ const char *name);
#else
@@ -844,6 +851,17 @@ devlink_region_snapshot_create(struct devlink_region *region, u64 data_len,
return 0;
}
+static inline int
+devlink_info_report_driver_name(struct devlink_info_req *req, const char *name)
+{
+ return 0;
+}
+
+static inline int
+devlink_info_report_serial_number(struct devlink_info_req *req, const char *sn)
+{
+ return 0;
+}
#endif
#endif /* _NET_DEVLINK_H_ */
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 6e52d3660654..c4b5d923f59f 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -89,6 +89,8 @@ enum devlink_command {
DEVLINK_CMD_REGION_DEL,
DEVLINK_CMD_REGION_READ,
+ DEVLINK_CMD_INFO_GET,
+
/* add new commands above here */
__DEVLINK_CMD_MAX,
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
@@ -285,6 +287,9 @@ enum devlink_attr {
DEVLINK_ATTR_REGION_CHUNK_ADDR, /* u64 */
DEVLINK_ATTR_REGION_CHUNK_LEN, /* u64 */
+ DEVLINK_ATTR_INFO_DRV_NAME, /* string */
+ DEVLINK_ATTR_INFO_SERIAL_NUMBER, /* string */
+
/* 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 abb0da9d7b4b..844e086ff038 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -3597,6 +3597,112 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
return 0;
}
+struct devlink_info_req {
+ struct sk_buff *msg;
+};
+
+int devlink_info_report_driver_name(struct devlink_info_req *req,
+ const char *name)
+{
+ return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRV_NAME, name);
+}
+EXPORT_SYMBOL_GPL(devlink_info_report_driver_name);
+
+int devlink_info_report_serial_number(struct devlink_info_req *req,
+ const char *sn)
+{
+ return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
+}
+EXPORT_SYMBOL_GPL(devlink_info_report_serial_number);
+
+static int
+devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
+ enum devlink_command cmd, u32 portid,
+ u32 seq, int flags, struct netlink_ext_ack *extack)
+{
+ struct devlink_info_req req;
+ void *hdr;
+ int err;
+
+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ err = -EMSGSIZE;
+ if (devlink_nl_put_handle(msg, devlink))
+ goto err_cancel_msg;
+
+ req.msg = msg;
+ err = devlink->ops->info_get(devlink, &req, extack);
+ if (err)
+ goto err_cancel_msg;
+
+ genlmsg_end(msg, hdr);
+ return 0;
+
+err_cancel_msg:
+ genlmsg_cancel(msg, hdr);
+ return err;
+}
+
+static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct devlink *devlink = info->user_ptr[0];
+ struct sk_buff *msg;
+ int err;
+
+ if (!devlink->ops || !devlink->ops->info_get)
+ return -EOPNOTSUPP;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
+ info->snd_portid, info->snd_seq, 0,
+ info->extack);
+ if (err) {
+ nlmsg_free(msg);
+ return err;
+ }
+
+ return genlmsg_reply(msg, info);
+}
+
+static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
+ struct netlink_callback *cb)
+{
+ struct devlink *devlink;
+ int start = cb->args[0];
+ int idx = 0;
+ int err;
+
+ mutex_lock(&devlink_mutex);
+ list_for_each_entry(devlink, &devlink_list, list) {
+ if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
+ continue;
+ if (idx < start) {
+ idx++;
+ continue;
+ }
+
+ mutex_lock(&devlink->lock);
+ err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
+ NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq, NLM_F_MULTI,
+ cb->extack);
+ mutex_unlock(&devlink->lock);
+ if (err)
+ break;
+ idx++;
+ }
+ mutex_unlock(&devlink_mutex);
+
+ cb->args[0] = idx;
+ return msg->len;
+}
+
static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
@@ -3842,6 +3948,14 @@ static const struct genl_ops devlink_nl_ops[] = {
.flags = GENL_ADMIN_PERM,
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
},
+ {
+ .cmd = DEVLINK_CMD_INFO_GET,
+ .doit = devlink_nl_cmd_info_get_doit,
+ .dumpit = devlink_nl_cmd_info_get_dumpit,
+ .policy = devlink_nl_policy,
+ .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
+ /* can be retrieved by unprivileged users */
+ },
};
static struct genl_family devlink_nl_family __ro_after_init = {
--
2.19.2
^ permalink raw reply related
* [PATCH net-next 0/7] devlink: add device (driver) information API
From: Jakub Kicinski @ 2019-01-29 3:34 UTC (permalink / raw)
To: davem
Cc: netdev, oss-drivers, jiri, andrew, f.fainelli, mkubecek, eugenem,
jonathan.lemon, Jakub Kicinski
Hi!
fw_version field in ethtool -i does not suit modern needs with 31
characters being quite limiting on more complex systems. There is
also no distinction between the running and flashed versions of
the firmware.
Since the driver information pertains to the entire device, rather
than a particular netdev, it seems wise to move it do devlink, at
the same time fixing the aforementioned issues.
The new API allows exposing the device serial number and versions
of the components of the card - both hardware, firmware (running
and flashed). Driver authors can choose descriptive identifiers
for the version fields. A few version identifiers which seemed
relevant for most devices have been added to the global devlink
header.
Example:
$ devlink dev info pci/0000:05:00.0
pci/0000:05:00.0:
driver nfp
serial_number 16240145
versions:
fixed:
board.id AMDA0099-0001
board.rev 07
board.vendor SMA
board.model carbon
running:
fw.mgmt: 010156.010156.010156
fw.cpld: 0x44
fw.app: sriov-2.1.16
stored:
fw.mgmt: 010158.010158.010158
fw.cpld: 0x44
fw.app: sriov-2.1.20
Last patch also includes a compat code for ethtool. If driver
reports no fw_version via the traditional ethtool API, ethtool
can call into devlink and try to cram as many versions as possible
into the 31 characters.
this non-RFC, v3 some would say:
- add three more versions in the NFP patches;
- add last patch (ethool compat) - Andrew & Michal.
RFCv2:
- use one driver op;
- allow longer serial number;
- wrap the skb into an opaque request struct;
- add some common identifier into the devlink header.
Jakub Kicinski (7):
devlink: add device information API
devlink: add version reporting to devlink info API
nfp: devlink: report driver name and serial number
nfp: devlink: report fixed versions
nfp: nsp: add support for versions command
nfp: devlink: report the running and flashed versions
ethtool: add compat for devlink info
.../net/ethernet/netronome/nfp/nfp_devlink.c | 145 +++++++++++++
.../ethernet/netronome/nfp/nfpcore/nfp_nsp.c | 61 ++++++
.../ethernet/netronome/nfp/nfpcore/nfp_nsp.h | 20 ++
include/net/devlink.h | 59 +++++
include/uapi/linux/devlink.h | 10 +
net/core/devlink.c | 204 ++++++++++++++++++
net/core/ethtool.c | 7 +
7 files changed, 506 insertions(+)
--
2.19.2
^ permalink raw reply
* Re: [PATCH net-next] mdio_bus: Fix PTR_ERR() usage after initialization to constant
From: YueHaibing @ 2019-01-29 3:30 UTC (permalink / raw)
To: Andrew Lunn; +Cc: davem, f.fainelli, hkallweit1, linux-kernel, netdev
In-Reply-To: <20190128143634.GF4765@lunn.ch>
On 2019/1/28 22:36, Andrew Lunn wrote:
> On Mon, Jan 28, 2019 at 09:24:09PM +0800, YueHaibing wrote:
>> Fix coccinelle warning:
>>
>> ./drivers/net/phy/mdio_bus.c:51:5-12: ERROR: PTR_ERR applied after initialization to constant on line 44
>> ./drivers/net/phy/mdio_bus.c:52:5-12: ERROR: PTR_ERR applied after initialization to constant on line 44
>>
>> fix this by using IS_ERR before PTR_ERR
>>
>> Fixes: bafbdd527d56 ("phylib: Add device reset GPIO support")
>> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
>> ---
>> drivers/net/phy/mdio_bus.c | 13 ++++++++-----
>> 1 file changed, 8 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
>> index 3d31358..802716a 100644
>> --- a/drivers/net/phy/mdio_bus.c
>> +++ b/drivers/net/phy/mdio_bus.c
>> @@ -42,17 +42,20 @@
>> static int mdiobus_register_gpiod(struct mdio_device *mdiodev)
>> {
>> struct gpio_desc *gpiod = NULL;
>> + int ret;
>>
>
> Hi YueHaibing
>
> I think i prefer the simpler fix:
>
> static int mdiobus_register_gpiod(struct mdio_device *mdiodev)
> {
> - struct gpio_desc *gpiod = NULL;
> + struct gpio_desc *gpiod = ERR_PTR(-ENOENT);
>
But a56c69803f5a ("net: phy: Handle not having GPIO enabled in the kernel")
add a new check:
@@ -56,7 +56,8 @@ static int mdiobus_register_gpiod(struct mdio_device *mdiodev)
gpiod = fwnode_get_named_gpiod(&mdiodev->dev.of_node->fwnode,
"reset-gpios", 0, GPIOD_OUT_LOW,
"PHY reset");
- if (PTR_ERR(gpiod) == -ENOENT)
+ if (PTR_ERR(gpiod) == -ENOENT ||
+ PTR_ERR(gpiod) == -ENOSYS)
gpiod = NULL;
else if (IS_ERR(gpiod))
return PTR_ERR(gpiod);
> Totally untested...
>
> Andrew
>
>> /* Deassert the optional reset signal */
>> if (mdiodev->dev.of_node)
>> gpiod = fwnode_get_named_gpiod(&mdiodev->dev.of_node->fwnode,
>> "reset-gpios", 0, GPIOD_OUT_LOW,
>> "PHY reset");
>> - if (PTR_ERR(gpiod) == -ENOENT ||
>> - PTR_ERR(gpiod) == -ENOSYS)
>> - gpiod = NULL;
>> - else if (IS_ERR(gpiod))
>> - return PTR_ERR(gpiod);
>> + if (IS_ERR(gpiod)) {
>> + ret = PTR_ERR(gpiod);
>> + if (ret == -ENOENT || ret == -ENOSYS)
>> + gpiod = NULL;
>> + else
>> + return ret;
>> + }
>>
>> mdiodev->reset = gpiod;
>>
>> --
>> 2.7.4
>>
>>
>
> .
>
^ permalink raw reply
* [PATCH v2 2/2] iwlwifi: Use struct_size() in kzalloc
From: YueHaibing @ 2019-01-29 3:21 UTC (permalink / raw)
To: johannes.berg, emmanuel.grumbach, luciano.coelho, linuxwifi,
kvalo
Cc: linux-kernel, netdev, linux-wireless, YueHaibing
In-Reply-To: <20190129032144.18120-1-yuehaibing@huawei.com>
Use struct_size() in kzalloc instead of the 'regd_to_copy'
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 569cc50..2b87c7c 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -1093,7 +1093,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ?
iwl_ext_nvm_channels : iwl_nvm_channels;
struct ieee80211_regdomain *regd, *copy_rd;
- int size_of_regd, regd_to_copy;
struct ieee80211_reg_rule *rule;
struct regdb_ptrs *regdb_ptrs;
enum nl80211_band band;
@@ -1113,11 +1112,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
num_of_ch);
/* build a regdomain rule for every valid channel */
- size_of_regd =
- sizeof(struct ieee80211_regdomain) +
- num_of_ch * sizeof(struct ieee80211_reg_rule);
-
- regd = kzalloc(size_of_regd, GFP_KERNEL);
+ regd = kzalloc(struct_size(regd, reg_rules, num_of_ch), GFP_KERNEL);
if (!regd)
return ERR_PTR(-ENOMEM);
@@ -1193,10 +1188,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
* Narrow down regdom for unused regulatory rules to prevent hole
* between reg rules to wmm rules.
*/
- regd_to_copy = sizeof(struct ieee80211_regdomain) +
- valid_rules * sizeof(struct ieee80211_reg_rule);
-
- copy_rd = kmemdup(regd, regd_to_copy, GFP_KERNEL);
+ copy_rd = kmemdup(regd, struct_size(regd, reg_rules, valid_rules),
+ GFP_KERNEL);
if (!copy_rd)
copy_rd = ERR_PTR(-ENOMEM);
--
2.7.4
^ permalink raw reply related
* [PATCH v2 1/2] iwlwifi: Use kmemdup instead of duplicating its function
From: YueHaibing @ 2019-01-29 3:21 UTC (permalink / raw)
To: johannes.berg, emmanuel.grumbach, luciano.coelho, linuxwifi,
kvalo
Cc: linux-kernel, netdev, linux-wireless, YueHaibing
In-Reply-To: <20190129032144.18120-1-yuehaibing@huawei.com>
Use kmemdup rather than duplicating its implementation
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index d9afedc..569cc50 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -1196,13 +1196,9 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
regd_to_copy = sizeof(struct ieee80211_regdomain) +
valid_rules * sizeof(struct ieee80211_reg_rule);
- copy_rd = kzalloc(regd_to_copy, GFP_KERNEL);
- if (!copy_rd) {
+ copy_rd = kmemdup(regd, regd_to_copy, GFP_KERNEL);
+ if (!copy_rd)
copy_rd = ERR_PTR(-ENOMEM);
- goto out;
- }
-
- memcpy(copy_rd, regd, regd_to_copy);
out:
kfree(regdb_ptrs);
--
2.7.4
^ permalink raw reply related
* [PATCH v2 0/2] cleanup for iwlwifi
From: YueHaibing @ 2019-01-29 3:21 UTC (permalink / raw)
To: johannes.berg, emmanuel.grumbach, luciano.coelho, linuxwifi,
kvalo
Cc: linux-kernel, netdev, linux-wireless, YueHaibing
v2: Use struct_size in regd allocation
YueHaibing (2):
iwlwifi: Use kmemdup instead of duplicating its function
iwlwifi: Use struct_size() in kzalloc
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 19 ++++---------------
1 file changed, 4 insertions(+), 15 deletions(-)
--
2.7.4
^ permalink raw reply
* Re: [PATCH 2/2] iwlwifi: Use struct_size() in kzalloc
From: YueHaibing @ 2019-01-29 3:13 UTC (permalink / raw)
To: Joe Perches, johannes.berg, emmanuel.grumbach, luciano.coelho,
linuxwifi, kvalo
Cc: linux-kernel, netdev, linux-wireless
In-Reply-To: <9a66aa07870c729ad0e65ac26a2404fac879f290.camel@perches.com>
On 2019/1/29 5:57, Joe Perches wrote:
> On Mon, 2019-01-28 at 14:44 +0800, YueHaibing wrote:
>> Use struct_size() in kzalloc instead of the 'regd_to_copy'
>
> There is also the use above that in the same function
> that could also be converted.
>
> /* build a regdomain rule for every valid channel */
> size_of_regd =
> sizeof(struct ieee80211_regdomain) +
> num_of_ch * sizeof(struct ieee80211_reg_rule);
>
> regd = kzalloc(size_of_regd, GFP_KERNEL);
> if (!regd)
> return ERR_PTR(-ENOMEM);
Thank you, will post v2.
>
>> diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
> []
>> @@ -1093,7 +1093,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
>> const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ?
>> iwl_ext_nvm_channels : iwl_nvm_channels;
>> struct ieee80211_regdomain *regd, *copy_rd;
>> - int size_of_regd, regd_to_copy;
>> + int size_of_regd;
>> struct ieee80211_reg_rule *rule;
>> struct regdb_ptrs *regdb_ptrs;
>> enum nl80211_band band;
>> @@ -1193,10 +1193,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
>> * Narrow down regdom for unused regulatory rules to prevent hole
>> * between reg rules to wmm rules.
>> */
>> - regd_to_copy = sizeof(struct ieee80211_regdomain) +
>> - valid_rules * sizeof(struct ieee80211_reg_rule);
>> -
>> - copy_rd = kmemdup(regd, regd_to_copy, GFP_KERNEL);
>> + copy_rd = kmemdup(regd, struct_size(regd, reg_rules, valid_rules),
>> + GFP_KERNEL);
>> if (!copy_rd)
>> copy_rd = ERR_PTR(-ENOMEM);
>>
>
>
> .
>
^ permalink raw reply
* Re: [PATCH] bpf/core.c - silence warning messages
From: Song Liu @ 2019-01-29 3:12 UTC (permalink / raw)
To: Valdis Kletnieks
Cc: Alexei Starovoitov, Daniel Borkmann, Networking, open list
In-Reply-To: <9865.1548718516@turing-police.cc.vt.edu>
On Mon, Jan 28, 2019 at 3:35 PM <valdis.kletnieks@vt.edu> wrote:
>
> On Mon, 28 Jan 2019 09:18:45 -0800, Song Liu said:
> > On Sun, Jan 27, 2019 at 8:43 PM <valdis.kletnieks@vt.edu> wrote:
>
> > > The attached patch silences the warnings, because we *know* we're overwriting
> > > the default initializer. That leaves bpf/core.c with only 6 other warnings,
> > > which become more visible in comparison.
> >
> > My concern is that this will also mute the warning for other parts of
> > bpf/core.c.
>
> I checked and there weren't any warnings for other parts of the file. Also, this message
> doesn't even happen unless you build with W=1, which apparently happens so rarely
> that nobody else has submitted a patch.
>
> Is there a high likelihood that another overwrite of an initializer is going to
> be included in the source?
>
> > Maybe we should move bpf_opcode_in_insntable() to a separate file, and mute
> > warning for that file?
>
> Seems to be overkill - the intent of this patch was mostly to make the *other*
> warnings issued with W=1 more noticable.
Yeah, I also felt this might be overkill while asking initially.
Acked-by: Song Liu <songliubraving@fb.com>
^ permalink raw reply
* Re: [PATCH bpf] bpf, doc: add reviewers to maintainers entry
From: Song Liu @ 2019-01-29 3:08 UTC (permalink / raw)
To: Daniel Borkmann
Cc: Alexei Starovoitov, netdev@vger.kernel.org, Martin Lau,
Yonghong Song
In-Reply-To: <20190128225526.5340-1-daniel@iogearbox.net>
> On Jan 28, 2019, at 2:55 PM, Daniel Borkmann <daniel@iogearbox.net> wrote:
>
> In order to better scale BPF development on netdev, we've adopted a
> reviewer rotation for all BPF patches among the five of us for some
> time now. Lets give credit where credit is due, and add Martin, Song
> and Yonghong as official BPF reviewers to MAINTAINERS file. Also
> while at it, add regex matching for BPF such that we get properly
> Cc'ed for files not listed here.
>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Thanks!
Acked-by: Song Liu <songliubraving@fb.com>
> ---
> MAINTAINERS | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 51029a4..6e13378 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2848,6 +2848,9 @@ F: include/uapi/linux/if_bonding.h
> BPF (Safe dynamic programs and tools)
> M: Alexei Starovoitov <ast@kernel.org>
> M: Daniel Borkmann <daniel@iogearbox.net>
> +R: Martin KaFai Lau <kafai@fb.com>
> +R: Song Liu <songliubraving@fb.com>
> +R: Yonghong Song <yhs@fb.com>
> L: netdev@vger.kernel.org
> L: linux-kernel@vger.kernel.org
> T: git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git
> @@ -2873,6 +2876,8 @@ F: samples/bpf/
> F: tools/bpf/
> F: tools/lib/bpf/
> F: tools/testing/selftests/bpf/
> +K: bpf
> +N: bpf
>
> BPF JIT for ARM
> M: Shubham Bansal <illusionist.neo@gmail.com>
> --
> 2.9.5
>
^ permalink raw reply
* Re: [PATCH bpf] bpf, doc: add reviewers to maintainers entry
From: Yonghong Song @ 2019-01-29 3:05 UTC (permalink / raw)
To: Daniel Borkmann, ast@kernel.org
Cc: netdev@vger.kernel.org, Martin Lau, Song Liu
In-Reply-To: <20190128225526.5340-1-daniel@iogearbox.net>
On 1/28/19 2:55 PM, Daniel Borkmann wrote:
> In order to better scale BPF development on netdev, we've adopted a
> reviewer rotation for all BPF patches among the five of us for some
> time now. Lets give credit where credit is due, and add Martin, Song
> and Yonghong as official BPF reviewers to MAINTAINERS file. Also
> while at it, add regex matching for BPF such that we get properly
> Cc'ed for files not listed here.
>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Thanks!
Acked-by: Yonghong Song <yhs@fb.com>
> ---
> MAINTAINERS | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 51029a4..6e13378 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2848,6 +2848,9 @@ F: include/uapi/linux/if_bonding.h
> BPF (Safe dynamic programs and tools)
> M: Alexei Starovoitov <ast@kernel.org>
> M: Daniel Borkmann <daniel@iogearbox.net>
> +R: Martin KaFai Lau <kafai@fb.com>
> +R: Song Liu <songliubraving@fb.com>
> +R: Yonghong Song <yhs@fb.com>
> L: netdev@vger.kernel.org
> L: linux-kernel@vger.kernel.org
> T: git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git
> @@ -2873,6 +2876,8 @@ F: samples/bpf/
> F: tools/bpf/
> F: tools/lib/bpf/
> F: tools/testing/selftests/bpf/
> +K: bpf
> +N: bpf
>
> BPF JIT for ARM
> M: Shubham Bansal <illusionist.neo@gmail.com>
>
^ permalink raw reply
* Re: [PATCH net-next] net: udp Allow CHECKSUM_UNNECESSARY packets to do GRO.
From: maowenan @ 2019-01-29 3:00 UTC (permalink / raw)
To: netdev, davem, edumazet
In-Reply-To: <1548214428-114642-1-git-send-email-maowenan@huawei.com>
Hi all,
Do you have any comments about this change?
On 2019/1/23 11:33, Mao Wenan wrote:
> When udp4_gro_receive() get one packet that uh->check=0,
> skb_gro_checksum_validate_zero_check() will set the
> skb->ip_summed = CHECKSUM_UNNECESSARY;
> skb->csum_level = 0;
> Then udp_gro_receive() will flush the packet which is not CHECKSUM_PARTIAL,
> It is not our expect, because check=0 in udp header indicates this
> packet is no need to caculate checksum, we should go further to do GRO.
>
> This patch changes the value of csum_cnt according to skb->csum_level.
> ---
> include/linux/netdevice.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 1377d08..9c819f1 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -2764,6 +2764,7 @@ static inline void skb_gro_incr_csum_unnecessary(struct sk_buff *skb)
> * during GRO. This saves work if we fallback to normal path.
> */
> __skb_incr_checksum_unnecessary(skb);
> + NAPI_GRO_CB(skb)->csum_cnt = skb->csum_level + 1;
> }
> }
>
>
^ permalink raw reply
* Re: [PATCH v2 net 7/7] virtio_net: Differentiate sk_buff and xdp_frame on freeing
From: Jason Wang @ 2019-01-29 2:49 UTC (permalink / raw)
To: Toshiaki Makita, David S. Miller, Michael S. Tsirkin
Cc: netdev, virtualization
In-Reply-To: <5f114c25-1f42-996b-134c-962b64597e74@lab.ntt.co.jp>
On 2019/1/29 上午10:35, Toshiaki Makita wrote:
> On 2019/01/29 11:23, Jason Wang wrote:
>> On 2019/1/29 上午8:45, Toshiaki Makita wrote:
> ...
>>> @@ -2666,10 +2696,10 @@ static void free_unused_bufs(struct
>>> virtnet_info *vi)
>>> for (i = 0; i < vi->max_queue_pairs; i++) {
>>> struct virtqueue *vq = vi->sq[i].vq;
>>> while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
>>> - if (!is_xdp_raw_buffer_queue(vi, i))
>>> + if (!is_xdp_frame(buf))
>>
>> I believe this is the last user of is_xdp_raw_buffer_queue(), maybe you
>> can sent a patch on top to remove it.
> Actually patch2 added new users of it ;)
Right, I missed that.
Thanks
>
>>
>>> dev_kfree_skb(buf);
>>> else
>>> - xdp_return_frame(buf);
>>> + xdp_return_frame(ptr_to_xdp(buf));
>>> }
>>> }
>>>
>>
>> Acked-by: Jason Wang <jasowang@redhat.com>
>>
> Thanks!
>
^ permalink raw reply
* [PATCH bpf] bpf: run bpf programs with preemption disabled
From: Alexei Starovoitov @ 2019-01-29 2:43 UTC (permalink / raw)
To: davem
Cc: daniel, peterz, jannh, paulmck, will.deacon, mingo, netdev,
kernel-team
Disabled preemption is necessary for proper access to per-cpu maps
from BPF programs.
But the sender side of socket filters didn't have preemption disabled:
unix_dgram_sendmsg->sk_filter->sk_filter_trim_cap->bpf_prog_run_save_cb->BPF_PROG_RUN
and a combination of af_packet with tun device didn't disable either:
tpacket_snd->packet_direct_xmit->packet_pick_tx_queue->ndo_select_queue->
tun_select_queue->tun_ebpf_select_queue->bpf_prog_run_clear_cb->BPF_PROG_RUN
Disable preemption before executing BPF programs (both classic and extended).
Reported-by: Jann Horn <jannh@google.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
---
include/linux/filter.h | 21 ++++++++++++++++++---
kernel/bpf/cgroup.c | 2 +-
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/include/linux/filter.h b/include/linux/filter.h
index ad106d845b22..e532fcc6e4b5 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -591,8 +591,8 @@ static inline u8 *bpf_skb_cb(struct sk_buff *skb)
return qdisc_skb_cb(skb)->data;
}
-static inline u32 bpf_prog_run_save_cb(const struct bpf_prog *prog,
- struct sk_buff *skb)
+static inline u32 __bpf_prog_run_save_cb(const struct bpf_prog *prog,
+ struct sk_buff *skb)
{
u8 *cb_data = bpf_skb_cb(skb);
u8 cb_saved[BPF_SKB_CB_LEN];
@@ -611,15 +611,30 @@ static inline u32 bpf_prog_run_save_cb(const struct bpf_prog *prog,
return res;
}
+static inline u32 bpf_prog_run_save_cb(const struct bpf_prog *prog,
+ struct sk_buff *skb)
+{
+ u32 res;
+
+ preempt_disable();
+ res = __bpf_prog_run_save_cb(prog, skb);
+ preempt_enable();
+ return res;
+}
+
static inline u32 bpf_prog_run_clear_cb(const struct bpf_prog *prog,
struct sk_buff *skb)
{
u8 *cb_data = bpf_skb_cb(skb);
+ u32 res;
if (unlikely(prog->cb_access))
memset(cb_data, 0, BPF_SKB_CB_LEN);
- return BPF_PROG_RUN(prog, skb);
+ preempt_disable();
+ res = BPF_PROG_RUN(prog, skb);
+ preempt_enable();
+ return res;
}
static __always_inline u32 bpf_prog_run_xdp(const struct bpf_prog *prog,
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index ab612fe9862f..d17d05570a3f 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -572,7 +572,7 @@ int __cgroup_bpf_run_filter_skb(struct sock *sk,
bpf_compute_and_save_data_end(skb, &saved_data_end);
ret = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[type], skb,
- bpf_prog_run_save_cb);
+ __bpf_prog_run_save_cb);
bpf_restore_data_end(skb, saved_data_end);
__skb_pull(skb, offset);
skb->sk = save_sk;
--
2.20.0
^ permalink raw reply related
* Re: [RFC PATCH 1/3] riscv: set HAVE_EFFICIENT_UNALIGNED_ACCESS
From: Palmer Dabbelt @ 2019-01-29 2:43 UTC (permalink / raw)
To: Jim Wilson
Cc: bjorn.topel, Christoph Hellwig, linux-riscv, davidlee, daniel,
netdev
In-Reply-To: <CAFyWVaaAg9TuNVPbNmP0ongf6y2hmqFMiXJZHo8K84O4-BV0yw@mail.gmail.com>
On Fri, 25 Jan 2019 17:33:50 PST (-0800), Jim Wilson wrote:
> On Fri, Jan 25, 2019 at 12:21 PM Palmer Dabbelt <palmer@sifive.com> wrote:
>> Jim, would you be opposed to something like this?
>
> This looks OK to me.
OK, thanks. I'll send some patches around :)
>
>> + builtin_define_with_int_value ("__riscv_tune_misaligned_load_cost",
>> + riscv_tune_info->slow_unaligned_access ? 1024 : 1);
>> + builtin_define_with_int_value ("__riscv_tune_misaligned_store_cost",
>> + riscv_tune_info->slow_unaligned_access ? 1024 : 1);
>
> It would be nice to have a better way to compute these values, maybe
> an extra field in the tune structure, but we can always worry about
> that later when we need it.
I agree. I just went and designed the external interface first and hid the
ugliness here. The internal interfaces are easier to change :)
^ 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