* Re: [RESEND PATCH v2 0/5] net: phy: mscc: add support for VSC8584 and VSC8574 Microsemi quad-port PHYs
From: Paul Burton @ 2018-10-09 17:59 UTC (permalink / raw)
To: Quentin Schulz
Cc: alexandre.belloni@bootlin.com, ralf@linux-mips.org,
jhogan@kernel.org, robh+dt@kernel.org, mark.rutland@arm.com,
davem@davemloft.net, andrew@lunn.ch, f.fainelli@gmail.com,
allan.nielsen@microchip.com, linux-mips@linux-mips.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, thomas.petazzoni@bootlin.com,
antoine.tenart@bootlin.com
In-Reply-To: <20181008101445.25946-1-quentin.schulz@bootlin.com>
Hi Quentin,
On Mon, Oct 08, 2018 at 12:14:40PM +0200, Quentin Schulz wrote:
> RESEND: rebased on top of latest net-next and on top of latest version of
> "net: phy: mscc: various improvements to Microsemi PHY driver" patch
> series.
>
>%
>
> I suggest patches 1 to 3 go through net tree and patches 4 and 5 go
> through MIPS tree. Patches going through net tree and those going through
> MIPS tree do not depend on one another.
Patches 4 & 5 applied to mips-next for 4.20, thanks!
Paul
^ permalink raw reply
* Re: [PATCH v3 1/2] Driver core: add bus_find_device_by_fwnode
From: Mathieu Poirier @ 2018-10-09 17:48 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Silesh C V, Greg KH, Linux Kernel Mailing List, linux-arm-kernel,
linux-i2c, linux-rdma, netdev, devicetree, linux-spi,
Wolfram Sang, Lijun Ou, Wei Hu(Xavier), Yisen Zhuang, Salil Mehta,
Srinivas Kandagatla, Andrew Lunn, Florian Fainelli, Rob Herring,
Frank Rowand, Mark Brown, David Miller <davem@
In-Reply-To: <CAJZ5v0gckkg0jyTc7=JYPpUruQQXL_FhEjm03-0mrFcxH60cHA@mail.gmail.com>
On Tue, 9 Oct 2018 at 11:39, Rafael J. Wysocki <rafael@kernel.org> wrote:
>
> On Tue, Oct 9, 2018 at 7:27 PM Mathieu Poirier
> <mathieu.poirier@linaro.org> wrote:
> >
> > Hi Silesh,
> >
> > On Tue, Oct 09, 2018 at 03:47:24PM +0530, Silesh C V wrote:
> > > Some drivers need to find the device on a bus having a specific firmware
> > > node. Currently, such drivers have their own implementations to do this.
> > > Provide a helper similar to bus_find_device_by_name so that each driver
> > > does not have to reinvent this.
> > >
> > > Signed-off-by: Silesh C V <svellattu@mvista.com>
> > > ---
> > > Changes since v2:
> > > - make use of dev_fwnode in match_fwnode.
> > >
> > > drivers/base/bus.c | 20 ++++++++++++++++++++
> > > include/linux/device.h | 3 +++
> > > 2 files changed, 23 insertions(+)
> > >
> > > diff --git a/drivers/base/bus.c b/drivers/base/bus.c
> > > index 8bfd27e..a2f39db 100644
> > > --- a/drivers/base/bus.c
> > > +++ b/drivers/base/bus.c
> > > @@ -17,6 +17,7 @@
> > > #include <linux/string.h>
> > > #include <linux/mutex.h>
> > > #include <linux/sysfs.h>
> > > +#include <linux/property.h>
> > > #include "base.h"
> > > #include "power/power.h"
> > >
> > > @@ -373,6 +374,25 @@ struct device *bus_find_device_by_name(struct bus_type *bus,
> > > }
> > > EXPORT_SYMBOL_GPL(bus_find_device_by_name);
> > >
> > > +static int match_fwnode(struct device *dev, void *fwnode)
> > > +{
> > > + return dev_fwnode(dev) == fwnode;
> > > +}
> > > +
> > > +/**
> > > + * bus_find_device_by_fwnode - device iterator for locating a particular device
> > > + * having a specific firmware node
> > > + * @bus: bus type
> > > + * @start: Device to begin with
> > > + * @fwnode: firmware node of the device to match
> > > + */
> > > +struct device *bus_find_device_by_fwnode(struct bus_type *bus, struct device *start,
> > > + struct fwnode_handle *fwnode)
> >
> > I get the following when running checkpatch on your set:
> >
> > mpoirier@xps15:~/work/linaro/coresight/kernel-maint$ ./scripts/checkpatch.pl
> > 0001-Driver-core-add-bus_find_device_by_fwnode.patch
> > WARNING: line over 80 characters
>
> Lines longer than 80 chars often are legitimate. No need to send
> extra reports about those cases in general.
In this case I don't see a reason not to abide to the guideline.
Wrapping the function declaration to 80 characters would be easy
without effecting code readability.
Mathieu
>
> Thanks,
> Rafael
^ permalink raw reply
* [PATCH v2 1/2] net/ncsi: Add NCSI Broadcom OEM command
From: Vijay Khemka @ 2018-10-09 17:48 UTC (permalink / raw)
To: Samuel Mendoza-Jonas, David S. Miller, netdev, linux-kernel
Cc: vijaykhemka, openbmc @ lists . ozlabs . org, Justin.Lee1, joel,
linux-aspeed
This patch adds OEM Broadcom commands and response handling. It also
defines OEM Get MAC Address handler to get and configure the device.
ncsi_oem_gma_handler_bcm: This handler send NCSI broadcom command for
getting mac address.
ncsi_rsp_handler_oem_bcm: This handles response received for all
broadcom OEM commands.
ncsi_rsp_handler_oem_bcm_gma: This handles get mac address response and
set it to device.
Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
---
net/ncsi/Kconfig | 6 ++++
net/ncsi/internal.h | 8 +++++
net/ncsi/ncsi-manage.c | 70 +++++++++++++++++++++++++++++++++++++++++-
net/ncsi/ncsi-pkt.h | 8 +++++
net/ncsi/ncsi-rsp.c | 40 +++++++++++++++++++++++-
5 files changed, 130 insertions(+), 2 deletions(-)
diff --git a/net/ncsi/Kconfig b/net/ncsi/Kconfig
index 08a8a6031fd7..7f2b46108a24 100644
--- a/net/ncsi/Kconfig
+++ b/net/ncsi/Kconfig
@@ -10,3 +10,9 @@ config NET_NCSI
support. Enable this only if your system connects to a network
device via NCSI and the ethernet driver you're using supports
the protocol explicitly.
+config NCSI_OEM_CMD_GET_MAC
+ bool "Get NCSI OEM MAC Address"
+ depends on NET_NCSI
+ ---help---
+ This allows to get MAC address from NCSI firmware and set them back to
+ controller.
diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h
index 3d0a33b874f5..45883b32790e 100644
--- a/net/ncsi/internal.h
+++ b/net/ncsi/internal.h
@@ -71,6 +71,13 @@ enum {
/* OEM Vendor Manufacture ID */
#define NCSI_OEM_MFR_MLX_ID 0x8119
#define NCSI_OEM_MFR_BCM_ID 0x113d
+/* Broadcom specific OEM Command */
+#define NCSI_OEM_BCM_CMD_GMA 0x01 /* CMD ID for Get MAC */
+/* OEM Command payload lengths*/
+#define NCSI_OEM_BCM_CMD_GMA_LEN 12
+/* Mac address offset in OEM response */
+#define BCM_MAC_ADDR_OFFSET 28
+
struct ncsi_channel_version {
u32 version; /* Supported BCD encoded NCSI version */
@@ -240,6 +247,7 @@ enum {
ncsi_dev_state_probe_dp,
ncsi_dev_state_config_sp = 0x0301,
ncsi_dev_state_config_cis,
+ ncsi_dev_state_config_oem_gma,
ncsi_dev_state_config_clear_vids,
ncsi_dev_state_config_svf,
ncsi_dev_state_config_ev,
diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
index 091284760d21..e5bfd9245b5d 100644
--- a/net/ncsi/ncsi-manage.c
+++ b/net/ncsi/ncsi-manage.c
@@ -635,6 +635,39 @@ static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc,
return 0;
}
+#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC)
+
+/* NCSI OEM Command APIs */
+static void ncsi_oem_gma_handler_bcm(struct ncsi_cmd_arg *nca)
+{
+ int ret = 0;
+ unsigned char data[NCSI_OEM_BCM_CMD_GMA_LEN];
+
+ nca->payload = NCSI_OEM_BCM_CMD_GMA_LEN;
+
+ memset(data, 0, NCSI_OEM_BCM_CMD_GMA_LEN);
+ *(unsigned int *)data = ntohl(NCSI_OEM_MFR_BCM_ID);
+ data[5] = NCSI_OEM_BCM_CMD_GMA;
+
+ nca->data = data;
+
+ ret = ncsi_xmit_cmd(nca);
+ if (ret)
+ netdev_err(nca->ndp->ndev.dev,
+ "NCSI: Failed to transmit cmd 0x%x during configure\n",
+ nca->type);
+}
+
+/* OEM Command handlers initialization */
+static struct ncsi_oem_gma_handler {
+ unsigned int mfr_id;
+ void (*handler)(struct ncsi_cmd_arg *nca);
+} ncsi_oem_gma_handlers[] = {
+ { NCSI_OEM_MFR_BCM_ID, ncsi_oem_gma_handler_bcm }
+};
+
+#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */
+
static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
{
struct ncsi_dev *nd = &ndp->ndev;
@@ -643,9 +676,10 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
struct ncsi_channel *nc = ndp->active_channel;
struct ncsi_channel *hot_nc = NULL;
struct ncsi_cmd_arg nca;
+ struct ncsi_oem_gma_handler *nch = NULL;
unsigned char index;
unsigned long flags;
- int ret;
+ int ret, i;
nca.ndp = ndp;
nca.req_flags = NCSI_REQ_FLAG_EVENT_DRIVEN;
@@ -685,6 +719,40 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
goto error;
}
+#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC)
+ nd->state = ncsi_dev_state_config_oem_gma;
+ break;
+ case ncsi_dev_state_config_oem_gma:
+ nca.type = NCSI_PKT_CMD_OEM;
+ nca.package = np->id;
+ nca.channel = nc->id;
+ ndp->pending_req_num = 1;
+
+ /* Check for manufacturer id and Find the handler */
+ for (i = 0; i < ARRAY_SIZE(ncsi_oem_gma_handlers); i++) {
+ if (ncsi_oem_gma_handlers[i].mfr_id ==
+ nc->version.mf_id) {
+ if (ncsi_oem_gma_handlers[i].handler)
+ nch = &ncsi_oem_gma_handlers[i];
+ else
+ nch = NULL;
+
+ break;
+ }
+ }
+
+ if (!nch) {
+ netdev_err(ndp->ndev.dev, "No handler available for GMA with MFR-ID (0x%x)\n",
+ nc->version.mf_id);
+ nd->state = ncsi_dev_state_config_clear_vids;
+ schedule_work(&ndp->work);
+ break;
+ }
+
+ /* Get Mac address from NCSI device */
+ nch->handler(&nca);
+#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */
+
nd->state = ncsi_dev_state_config_clear_vids;
break;
case ncsi_dev_state_config_clear_vids:
diff --git a/net/ncsi/ncsi-pkt.h b/net/ncsi/ncsi-pkt.h
index 0f2087c8d42a..4d3f06be38bd 100644
--- a/net/ncsi/ncsi-pkt.h
+++ b/net/ncsi/ncsi-pkt.h
@@ -165,6 +165,14 @@ struct ncsi_rsp_oem_pkt {
unsigned char data[]; /* Payload data */
};
+/* Broadcom Response Data */
+struct ncsi_rsp_oem_bcm_pkt {
+ unsigned char ver; /* Payload Version */
+ unsigned char type; /* OEM Command type */
+ __be16 len; /* Payload Length */
+ unsigned char data[]; /* Cmd specific Data */
+};
+
/* Get Link Status */
struct ncsi_rsp_gls_pkt {
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
index d66b34749027..31672e967db2 100644
--- a/net/ncsi/ncsi-rsp.c
+++ b/net/ncsi/ncsi-rsp.c
@@ -596,12 +596,50 @@ static int ncsi_rsp_handler_snfc(struct ncsi_request *nr)
return 0;
}
+/* Response handler for Broadcom command Get Mac Address */
+static int ncsi_rsp_handler_oem_bcm_gma(struct ncsi_request *nr)
+{
+ struct ncsi_rsp_oem_pkt *rsp;
+ struct ncsi_dev_priv *ndp = nr->ndp;
+ struct net_device *ndev = ndp->ndev.dev;
+ int ret = 0;
+ const struct net_device_ops *ops = ndev->netdev_ops;
+ struct sockaddr saddr;
+
+ /* Get the response header */
+ rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
+
+ saddr.sa_family = ndev->type;
+ ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+ memcpy(saddr.sa_data, &rsp->data[BCM_MAC_ADDR_OFFSET], ETH_ALEN);
+ ret = ops->ndo_set_mac_address(ndev, &saddr);
+ if (ret < 0)
+ netdev_warn(ndev, "NCSI: Writing mac address to device failed\n");
+
+ return ret;
+}
+
+/* Response handler for Broadcom card */
+static int ncsi_rsp_handler_oem_bcm(struct ncsi_request *nr)
+{
+ struct ncsi_rsp_oem_pkt *rsp;
+ struct ncsi_rsp_oem_bcm_pkt *bcm;
+
+ /* Get the response header */
+ rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
+ bcm = (struct ncsi_rsp_oem_bcm_pkt *)(rsp->data);
+
+ if (bcm->type == NCSI_OEM_BCM_CMD_GMA)
+ return ncsi_rsp_handler_oem_bcm_gma(nr);
+ return 0;
+}
+
static struct ncsi_rsp_oem_handler {
unsigned int mfr_id;
int (*handler)(struct ncsi_request *nr);
} ncsi_rsp_oem_handlers[] = {
{ NCSI_OEM_MFR_MLX_ID, NULL },
- { NCSI_OEM_MFR_BCM_ID, NULL }
+ { NCSI_OEM_MFR_BCM_ID, ncsi_rsp_handler_oem_bcm }
};
/* Response handler for OEM command */
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v3 2/2] treewide: use bus_find_device_by_fwnode
From: Mathieu Poirier @ 2018-10-09 17:44 UTC (permalink / raw)
To: Silesh C V
Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel,
linux-arm-kernel, linux-i2c, linux-rdma, netdev, devicetree,
linux-spi, Wolfram Sang, Lijun Ou, Wei Hu(Xavier), Yisen Zhuang,
Salil Mehta, Srinivas Kandagatla, Andrew Lunn, Florian Fainelli,
Rob Herring, Frank Rowand, Mark Brown, David S. Miller
In-Reply-To: <1539080245-25818-2-git-send-email-svellattu@mvista.com>
On Tue, Oct 09, 2018 at 03:47:25PM +0530, Silesh C V wrote:
> Use bus_find_device_by_fwnode helper to find the device having a
> specific firmware node on a bus.
>
> Signed-off-by: Silesh C V <svellattu@mvista.com>
> Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> Reviewed-by: Rob Herring <robh@kernel.org>
> ---
> Changes since v2:
> - Add Reviewed-by tags
>
> drivers/hwtracing/coresight/of_coresight.c | 14 ++++----------
> drivers/i2c/i2c-core-of.c | 9 ++-------
> drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 8 +-------
> drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 8 +-------
> drivers/nvmem/core.c | 7 +------
> drivers/of/of_mdio.c | 8 +-------
> drivers/of/platform.c | 7 +------
> drivers/spi/spi.c | 10 +++-------
> 8 files changed, 14 insertions(+), 57 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
> index 6880bee..8193b50 100644
> --- a/drivers/hwtracing/coresight/of_coresight.c
> +++ b/drivers/hwtracing/coresight/of_coresight.c
> @@ -17,12 +17,6 @@
> #include <linux/cpumask.h>
> #include <asm/smp_plat.h>
>
> -
> -static int of_dev_node_match(struct device *dev, void *data)
> -{
> - return dev->of_node == data;
> -}
> -
> static struct device *
> of_coresight_get_endpoint_device(struct device_node *endpoint)
> {
> @@ -32,8 +26,8 @@ static int of_dev_node_match(struct device *dev, void *data)
> * If we have a non-configurable replicator, it will be found on the
> * platform bus.
> */
> - dev = bus_find_device(&platform_bus_type, NULL,
> - endpoint, of_dev_node_match);
> + dev = bus_find_device_by_fwnode(&platform_bus_type, NULL,
> + &endpoint->fwnode);
> if (dev)
> return dev;
>
> @@ -41,8 +35,8 @@ static int of_dev_node_match(struct device *dev, void *data)
> * We have a configurable component - circle through the AMBA bus
> * looking for the device that matches the endpoint node.
> */
> - return bus_find_device(&amba_bustype, NULL,
> - endpoint, of_dev_node_match);
> + return bus_find_device_by_fwnode(&amba_bustype, NULL,
> + &endpoint->fwnode);
This doesn't apply on linux-next. This late in the cycle you may want to rebase
your work on that tree.
Otherwise and for the coresight part:
Tested-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Mathieu
> }
>
> static void of_coresight_get_ports(const struct device_node *node,
> diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c
> index 6cb7ad6..2b8ef8d 100644
> --- a/drivers/i2c/i2c-core-of.c
> +++ b/drivers/i2c/i2c-core-of.c
> @@ -116,18 +116,13 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
> of_node_put(bus);
> }
>
> -static int of_dev_node_match(struct device *dev, void *data)
> -{
> - return dev->of_node == data;
> -}
> -
> /* must call put_device() when done with returned i2c_client device */
> struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
> {
> struct device *dev;
> struct i2c_client *client;
>
> - dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match);
> + dev = bus_find_device_by_fwnode(&i2c_bus_type, NULL, &node->fwnode);
> if (!dev)
> return NULL;
>
> @@ -145,7 +140,7 @@ struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
> struct device *dev;
> struct i2c_adapter *adapter;
>
> - dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match);
> + dev = bus_find_device_by_fwnode(&i2c_bus_type, NULL, &node->fwnode);
> if (!dev)
> return NULL;
>
> diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
> index 081aa91..b0d418e 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
> +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
> @@ -4832,19 +4832,13 @@ static void hns_roce_v1_cleanup_eq_table(struct hns_roce_dev *hr_dev)
> };
> MODULE_DEVICE_TABLE(acpi, hns_roce_acpi_match);
>
> -static int hns_roce_node_match(struct device *dev, void *fwnode)
> -{
> - return dev->fwnode == fwnode;
> -}
> -
> static struct
> platform_device *hns_roce_find_pdev(struct fwnode_handle *fwnode)
> {
> struct device *dev;
>
> /* get the 'device' corresponding to the matching 'fwnode' */
> - dev = bus_find_device(&platform_bus_type, NULL,
> - fwnode, hns_roce_node_match);
> + dev = bus_find_device_by_fwnode(&platform_bus_type, NULL, fwnode);
> /* get the platform device */
> return dev ? to_platform_device(dev) : NULL;
> }
> diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
> index 16294cd..d5d7c88 100644
> --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
> +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
> @@ -758,17 +758,11 @@ struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
> return (void *)misc_op;
> }
>
> -static int hns_dsaf_dev_match(struct device *dev, void *fwnode)
> -{
> - return dev->fwnode == fwnode;
> -}
> -
> struct
> platform_device *hns_dsaf_find_platform_device(struct fwnode_handle *fwnode)
> {
> struct device *dev;
>
> - dev = bus_find_device(&platform_bus_type, NULL,
> - fwnode, hns_dsaf_dev_match);
> + dev = bus_find_device_by_fwnode(&platform_bus_type, NULL, fwnode);
> return dev ? to_platform_device(dev) : NULL;
> }
> diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
> index aa16578..b62f236 100644
> --- a/drivers/nvmem/core.c
> +++ b/drivers/nvmem/core.c
> @@ -262,11 +262,6 @@ static void nvmem_release(struct device *dev)
> .name = "nvmem",
> };
>
> -static int of_nvmem_match(struct device *dev, void *nvmem_np)
> -{
> - return dev->of_node == nvmem_np;
> -}
> -
> static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np)
> {
> struct device *d;
> @@ -274,7 +269,7 @@ static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np)
> if (!nvmem_np)
> return NULL;
>
> - d = bus_find_device(&nvmem_bus_type, NULL, nvmem_np, of_nvmem_match);
> + d = bus_find_device_by_fwnode(&nvmem_bus_type, NULL, &nvmem_np->fwnode);
>
> if (!d)
> return NULL;
> diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
> index e92391d..2906a6b 100644
> --- a/drivers/of/of_mdio.c
> +++ b/drivers/of/of_mdio.c
> @@ -282,12 +282,6 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
> }
> EXPORT_SYMBOL(of_mdiobus_register);
>
> -/* Helper function for of_phy_find_device */
> -static int of_phy_match(struct device *dev, void *phy_np)
> -{
> - return dev->of_node == phy_np;
> -}
> -
> /**
> * of_phy_find_device - Give a PHY node, find the phy_device
> * @phy_np: Pointer to the phy's device tree node
> @@ -303,7 +297,7 @@ struct phy_device *of_phy_find_device(struct device_node *phy_np)
> if (!phy_np)
> return NULL;
>
> - d = bus_find_device(&mdio_bus_type, NULL, phy_np, of_phy_match);
> + d = bus_find_device_by_fwnode(&mdio_bus_type, NULL, &phy_np->fwnode);
> if (d) {
> mdiodev = to_mdio_device(d);
> if (mdiodev->flags & MDIO_DEVICE_FLAG_PHY)
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> index 6c59673..36dd58e 100644
> --- a/drivers/of/platform.c
> +++ b/drivers/of/platform.c
> @@ -37,11 +37,6 @@
> {} /* Empty terminated list */
> };
>
> -static int of_dev_node_match(struct device *dev, void *data)
> -{
> - return dev->of_node == data;
> -}
> -
> /**
> * of_find_device_by_node - Find the platform_device associated with a node
> * @np: Pointer to device tree node
> @@ -55,7 +50,7 @@ struct platform_device *of_find_device_by_node(struct device_node *np)
> {
> struct device *dev;
>
> - dev = bus_find_device(&platform_bus_type, NULL, np, of_dev_node_match);
> + dev = bus_find_device_by_fwnode(&platform_bus_type, NULL, &np->fwnode);
> return dev ? to_platform_device(dev) : NULL;
> }
> EXPORT_SYMBOL(of_find_device_by_node);
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index 9da0bc5..97128a5 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -3324,16 +3324,12 @@ int spi_write_then_read(struct spi_device *spi,
> /*-------------------------------------------------------------------------*/
>
> #if IS_ENABLED(CONFIG_OF_DYNAMIC)
> -static int __spi_of_device_match(struct device *dev, void *data)
> -{
> - return dev->of_node == data;
> -}
> -
> /* must call put_device() when done with returned spi_device device */
> static struct spi_device *of_find_spi_device_by_node(struct device_node *node)
> {
> - struct device *dev = bus_find_device(&spi_bus_type, NULL, node,
> - __spi_of_device_match);
> + struct device *dev = bus_find_device_by_fwnode(&spi_bus_type, NULL,
> + &node->fwnode);
> +
> return dev ? to_spi_device(dev) : NULL;
> }
>
> --
> 1.9.1
>
^ permalink raw reply
* Re: [PATCH v3 1/2] Driver core: add bus_find_device_by_fwnode
From: Rafael J. Wysocki @ 2018-10-09 17:39 UTC (permalink / raw)
To: Mathieu Poirier
Cc: svellattu, Greg Kroah-Hartman, Rafael J. Wysocki,
Linux Kernel Mailing List, Linux ARM, linux-i2c, linux-rdma,
netdev, devicetree@vger.kernel.org, linux-spi, Wolfram Sang,
oulijun, xavier.huwei, yisen.zhuang, salil.mehta,
Srini Kandagatla, Andrew Lunn, Florian Fainelli, Rob Herring,
Frank Rowand, Mark Brown <broonie
In-Reply-To: <20181009172726.GA2182@xps15>
On Tue, Oct 9, 2018 at 7:27 PM Mathieu Poirier
<mathieu.poirier@linaro.org> wrote:
>
> Hi Silesh,
>
> On Tue, Oct 09, 2018 at 03:47:24PM +0530, Silesh C V wrote:
> > Some drivers need to find the device on a bus having a specific firmware
> > node. Currently, such drivers have their own implementations to do this.
> > Provide a helper similar to bus_find_device_by_name so that each driver
> > does not have to reinvent this.
> >
> > Signed-off-by: Silesh C V <svellattu@mvista.com>
> > ---
> > Changes since v2:
> > - make use of dev_fwnode in match_fwnode.
> >
> > drivers/base/bus.c | 20 ++++++++++++++++++++
> > include/linux/device.h | 3 +++
> > 2 files changed, 23 insertions(+)
> >
> > diff --git a/drivers/base/bus.c b/drivers/base/bus.c
> > index 8bfd27e..a2f39db 100644
> > --- a/drivers/base/bus.c
> > +++ b/drivers/base/bus.c
> > @@ -17,6 +17,7 @@
> > #include <linux/string.h>
> > #include <linux/mutex.h>
> > #include <linux/sysfs.h>
> > +#include <linux/property.h>
> > #include "base.h"
> > #include "power/power.h"
> >
> > @@ -373,6 +374,25 @@ struct device *bus_find_device_by_name(struct bus_type *bus,
> > }
> > EXPORT_SYMBOL_GPL(bus_find_device_by_name);
> >
> > +static int match_fwnode(struct device *dev, void *fwnode)
> > +{
> > + return dev_fwnode(dev) == fwnode;
> > +}
> > +
> > +/**
> > + * bus_find_device_by_fwnode - device iterator for locating a particular device
> > + * having a specific firmware node
> > + * @bus: bus type
> > + * @start: Device to begin with
> > + * @fwnode: firmware node of the device to match
> > + */
> > +struct device *bus_find_device_by_fwnode(struct bus_type *bus, struct device *start,
> > + struct fwnode_handle *fwnode)
>
> I get the following when running checkpatch on your set:
>
> mpoirier@xps15:~/work/linaro/coresight/kernel-maint$ ./scripts/checkpatch.pl
> 0001-Driver-core-add-bus_find_device_by_fwnode.patch
> WARNING: line over 80 characters
Lines longer than 80 chars often are legitimate. No need to send
extra reports about those cases in general.
Thanks,
Rafael
^ permalink raw reply
* Re: [PATCH v3 1/2] Driver core: add bus_find_device_by_fwnode
From: Rafael J. Wysocki @ 2018-10-09 10:20 UTC (permalink / raw)
To: svellattu
Cc: Greg Kroah-Hartman, Rafael J. Wysocki, Linux Kernel Mailing List,
Linux ARM, linux-i2c, linux-rdma, netdev,
devicetree@vger.kernel.org, linux-spi, Mathieu Poirier,
Wolfram Sang, oulijun, xavier.huwei, yisen.zhuang, salil.mehta,
srinivas.kandagatla, Andrew Lunn, Florian Fainelli, Rob Herring,
Frank Rowand, Mark Brown
In-Reply-To: <1539080245-25818-1-git-send-email-svellattu@mvista.com>
On Tue, Oct 9, 2018 at 12:18 PM Silesh C V <svellattu@mvista.com> wrote:
>
> Some drivers need to find the device on a bus having a specific firmware
> node. Currently, such drivers have their own implementations to do this.
> Provide a helper similar to bus_find_device_by_name so that each driver
> does not have to reinvent this.
>
> Signed-off-by: Silesh C V <svellattu@mvista.com>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
> Changes since v2:
> - make use of dev_fwnode in match_fwnode.
>
> drivers/base/bus.c | 20 ++++++++++++++++++++
> include/linux/device.h | 3 +++
> 2 files changed, 23 insertions(+)
>
> diff --git a/drivers/base/bus.c b/drivers/base/bus.c
> index 8bfd27e..a2f39db 100644
> --- a/drivers/base/bus.c
> +++ b/drivers/base/bus.c
> @@ -17,6 +17,7 @@
> #include <linux/string.h>
> #include <linux/mutex.h>
> #include <linux/sysfs.h>
> +#include <linux/property.h>
> #include "base.h"
> #include "power/power.h"
>
> @@ -373,6 +374,25 @@ struct device *bus_find_device_by_name(struct bus_type *bus,
> }
> EXPORT_SYMBOL_GPL(bus_find_device_by_name);
>
> +static int match_fwnode(struct device *dev, void *fwnode)
> +{
> + return dev_fwnode(dev) == fwnode;
> +}
> +
> +/**
> + * bus_find_device_by_fwnode - device iterator for locating a particular device
> + * having a specific firmware node
> + * @bus: bus type
> + * @start: Device to begin with
> + * @fwnode: firmware node of the device to match
> + */
> +struct device *bus_find_device_by_fwnode(struct bus_type *bus, struct device *start,
> + struct fwnode_handle *fwnode)
> +{
> + return bus_find_device(bus, start, (void *)fwnode, match_fwnode);
> +}
> +EXPORT_SYMBOL_GPL(bus_find_device_by_fwnode);
> +
> /**
> * subsys_find_device_by_id - find a device with a specific enumeration number
> * @subsys: subsystem
> diff --git a/include/linux/device.h b/include/linux/device.h
> index 8f88254..09384f6 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -171,6 +171,9 @@ struct device *bus_find_device(struct bus_type *bus, struct device *start,
> struct device *bus_find_device_by_name(struct bus_type *bus,
> struct device *start,
> const char *name);
> +struct device *bus_find_device_by_fwnode(struct bus_type *bus,
> + struct device *start,
> + struct fwnode_handle *fwnode);
> struct device *subsys_find_device_by_id(struct bus_type *bus, unsigned int id,
> struct device *hint);
> int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
> --
> 1.9.1
>
^ permalink raw reply
* [PATCH v3 2/2] treewide: use bus_find_device_by_fwnode
From: Silesh C V @ 2018-10-09 10:17 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki
Cc: linux-kernel, linux-arm-kernel, linux-i2c, linux-rdma, netdev,
devicetree, linux-spi, Mathieu Poirier, Wolfram Sang, Lijun Ou,
Wei Hu(Xavier), Yisen Zhuang, Salil Mehta, Srinivas Kandagatla,
Andrew Lunn, Florian Fainelli, Rob Herring, Frank Rowand,
Mark Brown, David S. Miller, Silesh C V
In-Reply-To: <1539080245-25818-1-git-send-email-svellattu@mvista.com>
Use bus_find_device_by_fwnode helper to find the device having a
specific firmware node on a bus.
Signed-off-by: Silesh C V <svellattu@mvista.com>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Changes since v2:
- Add Reviewed-by tags
drivers/hwtracing/coresight/of_coresight.c | 14 ++++----------
drivers/i2c/i2c-core-of.c | 9 ++-------
drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 8 +-------
drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 8 +-------
drivers/nvmem/core.c | 7 +------
drivers/of/of_mdio.c | 8 +-------
drivers/of/platform.c | 7 +------
drivers/spi/spi.c | 10 +++-------
8 files changed, 14 insertions(+), 57 deletions(-)
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
index 6880bee..8193b50 100644
--- a/drivers/hwtracing/coresight/of_coresight.c
+++ b/drivers/hwtracing/coresight/of_coresight.c
@@ -17,12 +17,6 @@
#include <linux/cpumask.h>
#include <asm/smp_plat.h>
-
-static int of_dev_node_match(struct device *dev, void *data)
-{
- return dev->of_node == data;
-}
-
static struct device *
of_coresight_get_endpoint_device(struct device_node *endpoint)
{
@@ -32,8 +26,8 @@ static int of_dev_node_match(struct device *dev, void *data)
* If we have a non-configurable replicator, it will be found on the
* platform bus.
*/
- dev = bus_find_device(&platform_bus_type, NULL,
- endpoint, of_dev_node_match);
+ dev = bus_find_device_by_fwnode(&platform_bus_type, NULL,
+ &endpoint->fwnode);
if (dev)
return dev;
@@ -41,8 +35,8 @@ static int of_dev_node_match(struct device *dev, void *data)
* We have a configurable component - circle through the AMBA bus
* looking for the device that matches the endpoint node.
*/
- return bus_find_device(&amba_bustype, NULL,
- endpoint, of_dev_node_match);
+ return bus_find_device_by_fwnode(&amba_bustype, NULL,
+ &endpoint->fwnode);
}
static void of_coresight_get_ports(const struct device_node *node,
diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c
index 6cb7ad6..2b8ef8d 100644
--- a/drivers/i2c/i2c-core-of.c
+++ b/drivers/i2c/i2c-core-of.c
@@ -116,18 +116,13 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
of_node_put(bus);
}
-static int of_dev_node_match(struct device *dev, void *data)
-{
- return dev->of_node == data;
-}
-
/* must call put_device() when done with returned i2c_client device */
struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
{
struct device *dev;
struct i2c_client *client;
- dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match);
+ dev = bus_find_device_by_fwnode(&i2c_bus_type, NULL, &node->fwnode);
if (!dev)
return NULL;
@@ -145,7 +140,7 @@ struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
struct device *dev;
struct i2c_adapter *adapter;
- dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match);
+ dev = bus_find_device_by_fwnode(&i2c_bus_type, NULL, &node->fwnode);
if (!dev)
return NULL;
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 081aa91..b0d418e 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -4832,19 +4832,13 @@ static void hns_roce_v1_cleanup_eq_table(struct hns_roce_dev *hr_dev)
};
MODULE_DEVICE_TABLE(acpi, hns_roce_acpi_match);
-static int hns_roce_node_match(struct device *dev, void *fwnode)
-{
- return dev->fwnode == fwnode;
-}
-
static struct
platform_device *hns_roce_find_pdev(struct fwnode_handle *fwnode)
{
struct device *dev;
/* get the 'device' corresponding to the matching 'fwnode' */
- dev = bus_find_device(&platform_bus_type, NULL,
- fwnode, hns_roce_node_match);
+ dev = bus_find_device_by_fwnode(&platform_bus_type, NULL, fwnode);
/* get the platform device */
return dev ? to_platform_device(dev) : NULL;
}
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
index 16294cd..d5d7c88 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
@@ -758,17 +758,11 @@ struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
return (void *)misc_op;
}
-static int hns_dsaf_dev_match(struct device *dev, void *fwnode)
-{
- return dev->fwnode == fwnode;
-}
-
struct
platform_device *hns_dsaf_find_platform_device(struct fwnode_handle *fwnode)
{
struct device *dev;
- dev = bus_find_device(&platform_bus_type, NULL,
- fwnode, hns_dsaf_dev_match);
+ dev = bus_find_device_by_fwnode(&platform_bus_type, NULL, fwnode);
return dev ? to_platform_device(dev) : NULL;
}
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index aa16578..b62f236 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -262,11 +262,6 @@ static void nvmem_release(struct device *dev)
.name = "nvmem",
};
-static int of_nvmem_match(struct device *dev, void *nvmem_np)
-{
- return dev->of_node == nvmem_np;
-}
-
static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np)
{
struct device *d;
@@ -274,7 +269,7 @@ static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np)
if (!nvmem_np)
return NULL;
- d = bus_find_device(&nvmem_bus_type, NULL, nvmem_np, of_nvmem_match);
+ d = bus_find_device_by_fwnode(&nvmem_bus_type, NULL, &nvmem_np->fwnode);
if (!d)
return NULL;
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index e92391d..2906a6b 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -282,12 +282,6 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
}
EXPORT_SYMBOL(of_mdiobus_register);
-/* Helper function for of_phy_find_device */
-static int of_phy_match(struct device *dev, void *phy_np)
-{
- return dev->of_node == phy_np;
-}
-
/**
* of_phy_find_device - Give a PHY node, find the phy_device
* @phy_np: Pointer to the phy's device tree node
@@ -303,7 +297,7 @@ struct phy_device *of_phy_find_device(struct device_node *phy_np)
if (!phy_np)
return NULL;
- d = bus_find_device(&mdio_bus_type, NULL, phy_np, of_phy_match);
+ d = bus_find_device_by_fwnode(&mdio_bus_type, NULL, &phy_np->fwnode);
if (d) {
mdiodev = to_mdio_device(d);
if (mdiodev->flags & MDIO_DEVICE_FLAG_PHY)
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 6c59673..36dd58e 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -37,11 +37,6 @@
{} /* Empty terminated list */
};
-static int of_dev_node_match(struct device *dev, void *data)
-{
- return dev->of_node == data;
-}
-
/**
* of_find_device_by_node - Find the platform_device associated with a node
* @np: Pointer to device tree node
@@ -55,7 +50,7 @@ struct platform_device *of_find_device_by_node(struct device_node *np)
{
struct device *dev;
- dev = bus_find_device(&platform_bus_type, NULL, np, of_dev_node_match);
+ dev = bus_find_device_by_fwnode(&platform_bus_type, NULL, &np->fwnode);
return dev ? to_platform_device(dev) : NULL;
}
EXPORT_SYMBOL(of_find_device_by_node);
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 9da0bc5..97128a5 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -3324,16 +3324,12 @@ int spi_write_then_read(struct spi_device *spi,
/*-------------------------------------------------------------------------*/
#if IS_ENABLED(CONFIG_OF_DYNAMIC)
-static int __spi_of_device_match(struct device *dev, void *data)
-{
- return dev->of_node == data;
-}
-
/* must call put_device() when done with returned spi_device device */
static struct spi_device *of_find_spi_device_by_node(struct device_node *node)
{
- struct device *dev = bus_find_device(&spi_bus_type, NULL, node,
- __spi_of_device_match);
+ struct device *dev = bus_find_device_by_fwnode(&spi_bus_type, NULL,
+ &node->fwnode);
+
return dev ? to_spi_device(dev) : NULL;
}
--
1.9.1
^ permalink raw reply related
* [PATCH v3 1/2] Driver core: add bus_find_device_by_fwnode
From: Silesh C V @ 2018-10-09 10:17 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki
Cc: linux-kernel, linux-arm-kernel, linux-i2c, linux-rdma, netdev,
devicetree, linux-spi, Mathieu Poirier, Wolfram Sang, Lijun Ou,
Wei Hu(Xavier), Yisen Zhuang, Salil Mehta, Srinivas Kandagatla,
Andrew Lunn, Florian Fainelli, Rob Herring, Frank Rowand,
Mark Brown, David S. Miller, Silesh C V
Some drivers need to find the device on a bus having a specific firmware
node. Currently, such drivers have their own implementations to do this.
Provide a helper similar to bus_find_device_by_name so that each driver
does not have to reinvent this.
Signed-off-by: Silesh C V <svellattu@mvista.com>
---
Changes since v2:
- make use of dev_fwnode in match_fwnode.
drivers/base/bus.c | 20 ++++++++++++++++++++
include/linux/device.h | 3 +++
2 files changed, 23 insertions(+)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 8bfd27e..a2f39db 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -17,6 +17,7 @@
#include <linux/string.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
+#include <linux/property.h>
#include "base.h"
#include "power/power.h"
@@ -373,6 +374,25 @@ struct device *bus_find_device_by_name(struct bus_type *bus,
}
EXPORT_SYMBOL_GPL(bus_find_device_by_name);
+static int match_fwnode(struct device *dev, void *fwnode)
+{
+ return dev_fwnode(dev) == fwnode;
+}
+
+/**
+ * bus_find_device_by_fwnode - device iterator for locating a particular device
+ * having a specific firmware node
+ * @bus: bus type
+ * @start: Device to begin with
+ * @fwnode: firmware node of the device to match
+ */
+struct device *bus_find_device_by_fwnode(struct bus_type *bus, struct device *start,
+ struct fwnode_handle *fwnode)
+{
+ return bus_find_device(bus, start, (void *)fwnode, match_fwnode);
+}
+EXPORT_SYMBOL_GPL(bus_find_device_by_fwnode);
+
/**
* subsys_find_device_by_id - find a device with a specific enumeration number
* @subsys: subsystem
diff --git a/include/linux/device.h b/include/linux/device.h
index 8f88254..09384f6 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -171,6 +171,9 @@ struct device *bus_find_device(struct bus_type *bus, struct device *start,
struct device *bus_find_device_by_name(struct bus_type *bus,
struct device *start,
const char *name);
+struct device *bus_find_device_by_fwnode(struct bus_type *bus,
+ struct device *start,
+ struct fwnode_handle *fwnode);
struct device *subsys_find_device_by_id(struct bus_type *bus, unsigned int id,
struct device *hint);
int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
--
1.9.1
^ permalink raw reply related
* Re: [PATCH net-next] rxrpc: Remove set but not used variable 'ioc'
From: David Howells @ 2018-10-09 10:13 UTC (permalink / raw)
To: YueHaibing; +Cc: dhowells, davem, linux-afs, netdev, kernel-janitors
In-Reply-To: <1539052273-34824-1-git-send-email-yuehaibing@huawei.com>
YueHaibing <yuehaibing@huawei.com> wrote:
> net/rxrpc/output.c: In function 'rxrpc_reject_packets':
> net/rxrpc/output.c:527:11: warning:
> variable 'ioc' set but not used [-Wunused-but-set-variable]
>
> It never used since introduction in
I wonder why my compiler doesn't show this warning.
Anyway, NAK: just removing the variable is the wrong fix - you need to look at
the code more closely. The actual fix is to pass it to kernel_sendmsg()
instead of 2.
But thanks anyway! Do you want to respin your patch?
> commit ece64fec164f ("rxrpc: Emit BUSY packets when supposed to rather than ABORTs")
Btw, this should be a 'Fixes: <commit> ("subject")' line and the patch needs
to go to net, not net-next.
David
^ permalink raw reply
* Re: [PATCH v3 1/2] Driver core: add bus_find_device_by_fwnode
From: Mathieu Poirier @ 2018-10-09 17:27 UTC (permalink / raw)
To: Silesh C V
Cc: Greg Kroah-Hartman, Rafael J. Wysocki, linux-kernel,
linux-arm-kernel, linux-i2c, linux-rdma, netdev, devicetree,
linux-spi, Wolfram Sang, Lijun Ou, Wei Hu(Xavier), Yisen Zhuang,
Salil Mehta, Srinivas Kandagatla, Andrew Lunn, Florian Fainelli,
Rob Herring, Frank Rowand, Mark Brown, David S. Miller
In-Reply-To: <1539080245-25818-1-git-send-email-svellattu@mvista.com>
Hi Silesh,
On Tue, Oct 09, 2018 at 03:47:24PM +0530, Silesh C V wrote:
> Some drivers need to find the device on a bus having a specific firmware
> node. Currently, such drivers have their own implementations to do this.
> Provide a helper similar to bus_find_device_by_name so that each driver
> does not have to reinvent this.
>
> Signed-off-by: Silesh C V <svellattu@mvista.com>
> ---
> Changes since v2:
> - make use of dev_fwnode in match_fwnode.
>
> drivers/base/bus.c | 20 ++++++++++++++++++++
> include/linux/device.h | 3 +++
> 2 files changed, 23 insertions(+)
>
> diff --git a/drivers/base/bus.c b/drivers/base/bus.c
> index 8bfd27e..a2f39db 100644
> --- a/drivers/base/bus.c
> +++ b/drivers/base/bus.c
> @@ -17,6 +17,7 @@
> #include <linux/string.h>
> #include <linux/mutex.h>
> #include <linux/sysfs.h>
> +#include <linux/property.h>
> #include "base.h"
> #include "power/power.h"
>
> @@ -373,6 +374,25 @@ struct device *bus_find_device_by_name(struct bus_type *bus,
> }
> EXPORT_SYMBOL_GPL(bus_find_device_by_name);
>
> +static int match_fwnode(struct device *dev, void *fwnode)
> +{
> + return dev_fwnode(dev) == fwnode;
> +}
> +
> +/**
> + * bus_find_device_by_fwnode - device iterator for locating a particular device
> + * having a specific firmware node
> + * @bus: bus type
> + * @start: Device to begin with
> + * @fwnode: firmware node of the device to match
> + */
> +struct device *bus_find_device_by_fwnode(struct bus_type *bus, struct device *start,
> + struct fwnode_handle *fwnode)
I get the following when running checkpatch on your set:
mpoirier@xps15:~/work/linaro/coresight/kernel-maint$ ./scripts/checkpatch.pl
0001-Driver-core-add-bus_find_device_by_fwnode.patch
WARNING: line over 80 characters
#45: FILE: drivers/base/bus.c:389:
+struct device *bus_find_device_by_fwnode(struct bus_type *bus, struct device
*start,
total: 0 errors, 1 warnings, 41 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
0001-Driver-core-add-bus_find_device_by_fwnode.patch has style problems, please
review.
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
Regards,
Mathieu
> +{
> + return bus_find_device(bus, start, (void *)fwnode, match_fwnode);
> +}
> +EXPORT_SYMBOL_GPL(bus_find_device_by_fwnode);
> +
> /**
> * subsys_find_device_by_id - find a device with a specific enumeration number
> * @subsys: subsystem
> diff --git a/include/linux/device.h b/include/linux/device.h
> index 8f88254..09384f6 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -171,6 +171,9 @@ struct device *bus_find_device(struct bus_type *bus, struct device *start,
> struct device *bus_find_device_by_name(struct bus_type *bus,
> struct device *start,
> const char *name);
> +struct device *bus_find_device_by_fwnode(struct bus_type *bus,
> + struct device *start,
> + struct fwnode_handle *fwnode);
> struct device *subsys_find_device_by_id(struct bus_type *bus, unsigned int id,
> struct device *hint);
> int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
> --
> 1.9.1
>
^ permalink raw reply
* [bpf-next V2 PATCH 3/3] selftests/bpf: add XDP selftests for modifying and popping VLAN headers
From: Jesper Dangaard Brouer @ 2018-10-09 10:04 UTC (permalink / raw)
To: netdev, Jesper Dangaard Brouer
Cc: liu.song.a23, Daniel Borkmann, yoel, Alexei Starovoitov,
John Fastabend
In-Reply-To: <153907945478.9484.16223890803803124822.stgit@firesoul>
This XDP selftest also contain a small TC-bpf component. It provoke
the generic-XDP bug fixed in previous commit.
The selftest itself shows how to do VLAN manipulation from XDP and TC.
The test demonstrate how XDP ingress can remove a VLAN tag, and how TC
egress can add back a VLAN tag.
This use-case originates from a production need by ISP (kviknet.dk),
who gets DSL-lines terminated as VLAN Q-in-Q tagged packets, and want
to avoid having an net_device for every end-customer on the box doing
the L2 to L3 termination.
The test-setup is done via a veth-pair and creating two network
namespaces (ns1 and ns2). The 'ns1' simulate the ISP network that are
loading the BPF-progs stripping and adding VLAN IDs. The 'ns2'
simulate the DSL-customer that are using VLAN tagged packets.
Running the script with --interactive, will simply not call the
cleanup function. This gives the effect of creating a testlab, that
the users can inspect and play with. The --verbose option will simply
request that the shell will print input lines as they are read, this
include comments, which in effect make the comments visible docs.
Reported-by: Yoel Caspersen <yoel@kviknet.dk>
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
tools/testing/selftests/bpf/Makefile | 6 -
tools/testing/selftests/bpf/test_xdp_vlan.c | 292 ++++++++++++++++++++++++++
tools/testing/selftests/bpf/test_xdp_vlan.sh | 195 +++++++++++++++++
3 files changed, 491 insertions(+), 2 deletions(-)
create mode 100644 tools/testing/selftests/bpf/test_xdp_vlan.c
create mode 100755 tools/testing/selftests/bpf/test_xdp_vlan.sh
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 1381ab81099c..d24afe8b821d 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -36,7 +36,8 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
test_get_stack_rawtp.o test_sockmap_kern.o test_sockhash_kern.o \
test_lwt_seg6local.o sendmsg4_prog.o sendmsg6_prog.o test_lirc_mode2_kern.o \
get_cgroup_id_kern.o socket_cookie_prog.o test_select_reuseport_kern.o \
- test_skb_cgroup_id_kern.o bpf_flow.o netcnt_prog.o test_sk_lookup_kern.o
+ test_skb_cgroup_id_kern.o bpf_flow.o netcnt_prog.o \
+ test_sk_lookup_kern.o test_xdp_vlan.o
# Order correspond to 'make run_tests' order
TEST_PROGS := test_kmod.sh \
@@ -49,7 +50,8 @@ TEST_PROGS := test_kmod.sh \
test_lwt_seg6local.sh \
test_lirc_mode2.sh \
test_skb_cgroup_id.sh \
- test_flow_dissector.sh
+ test_flow_dissector.sh \
+ test_xdp_vlan.sh
# Compile but not part of 'make run_tests'
TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr test_skb_cgroup_id_user \
diff --git a/tools/testing/selftests/bpf/test_xdp_vlan.c b/tools/testing/selftests/bpf/test_xdp_vlan.c
new file mode 100644
index 000000000000..365a7d2d9f5c
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_xdp_vlan.c
@@ -0,0 +1,292 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright(c) 2018 Jesper Dangaard Brouer.
+ *
+ * XDP/TC VLAN manipulation example
+ *
+ * GOTCHA: Remember to disable NIC hardware offloading of VLANs,
+ * else the VLAN tags are NOT inlined in the packet payload:
+ *
+ * # ethtool -K ixgbe2 rxvlan off
+ *
+ * Verify setting:
+ * # ethtool -k ixgbe2 | grep rx-vlan-offload
+ * rx-vlan-offload: off
+ *
+ */
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#include <linux/bpf.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/in.h>
+#include <linux/pkt_cls.h>
+
+#include "bpf_helpers.h"
+#include "bpf_endian.h"
+
+/* linux/if_vlan.h have not exposed this as UAPI, thus mirror some here
+ *
+ * struct vlan_hdr - vlan header
+ * @h_vlan_TCI: priority and VLAN ID
+ * @h_vlan_encapsulated_proto: packet type ID or len
+ */
+struct _vlan_hdr {
+ __be16 h_vlan_TCI;
+ __be16 h_vlan_encapsulated_proto;
+};
+#define VLAN_PRIO_MASK 0xe000 /* Priority Code Point */
+#define VLAN_PRIO_SHIFT 13
+#define VLAN_CFI_MASK 0x1000 /* Canonical Format Indicator */
+#define VLAN_TAG_PRESENT VLAN_CFI_MASK
+#define VLAN_VID_MASK 0x0fff /* VLAN Identifier */
+#define VLAN_N_VID 4096
+
+struct parse_pkt {
+ __u16 l3_proto;
+ __u16 l3_offset;
+ __u16 vlan_outer;
+ __u16 vlan_inner;
+ __u8 vlan_outer_offset;
+ __u8 vlan_inner_offset;
+};
+
+char _license[] SEC("license") = "GPL";
+
+static __always_inline
+bool parse_eth_frame(struct ethhdr *eth, void *data_end, struct parse_pkt *pkt)
+{
+ __u16 eth_type;
+ __u8 offset;
+
+ offset = sizeof(*eth);
+ /* Make sure packet is large enough for parsing eth + 2 VLAN headers */
+ if ((void *)eth + offset + (2*sizeof(struct _vlan_hdr)) > data_end)
+ return false;
+
+ eth_type = eth->h_proto;
+
+ /* Handle outer VLAN tag */
+ if (eth_type == bpf_htons(ETH_P_8021Q)
+ || eth_type == bpf_htons(ETH_P_8021AD)) {
+ struct _vlan_hdr *vlan_hdr;
+
+ vlan_hdr = (void *)eth + offset;
+ pkt->vlan_outer_offset = offset;
+ pkt->vlan_outer = bpf_ntohs(vlan_hdr->h_vlan_TCI)
+ & VLAN_VID_MASK;
+ eth_type = vlan_hdr->h_vlan_encapsulated_proto;
+ offset += sizeof(*vlan_hdr);
+ }
+
+ /* Handle inner (double) VLAN tag */
+ if (eth_type == bpf_htons(ETH_P_8021Q)
+ || eth_type == bpf_htons(ETH_P_8021AD)) {
+ struct _vlan_hdr *vlan_hdr;
+
+ vlan_hdr = (void *)eth + offset;
+ pkt->vlan_inner_offset = offset;
+ pkt->vlan_inner = bpf_ntohs(vlan_hdr->h_vlan_TCI)
+ & VLAN_VID_MASK;
+ eth_type = vlan_hdr->h_vlan_encapsulated_proto;
+ offset += sizeof(*vlan_hdr);
+ }
+
+ pkt->l3_proto = bpf_ntohs(eth_type); /* Convert to host-byte-order */
+ pkt->l3_offset = offset;
+
+ return true;
+}
+
+/* Hint, VLANs are choosen to hit network-byte-order issues */
+#define TESTVLAN 4011 /* 0xFAB */
+// #define TO_VLAN 4000 /* 0xFA0 (hint 0xOA0 = 160) */
+
+SEC("xdp_drop_vlan_4011")
+int xdp_prognum0(struct xdp_md *ctx)
+{
+ void *data_end = (void *)(long)ctx->data_end;
+ void *data = (void *)(long)ctx->data;
+ struct parse_pkt pkt = { 0 };
+
+ if (!parse_eth_frame(data, data_end, &pkt))
+ return XDP_ABORTED;
+
+ /* Drop specific VLAN ID example */
+ if (pkt.vlan_outer == TESTVLAN)
+ return XDP_ABORTED;
+ /*
+ * Using XDP_ABORTED makes it possible to record this event,
+ * via tracepoint xdp:xdp_exception like:
+ * # perf record -a -e xdp:xdp_exception
+ * # perf script
+ */
+ return XDP_PASS;
+}
+/*
+Commands to setup VLAN on Linux to test packets gets dropped:
+
+ export ROOTDEV=ixgbe2
+ export VLANID=4011
+ ip link add link $ROOTDEV name $ROOTDEV.$VLANID type vlan id $VLANID
+ ip link set dev $ROOTDEV.$VLANID up
+
+ ip link set dev $ROOTDEV mtu 1508
+ ip addr add 100.64.40.11/24 dev $ROOTDEV.$VLANID
+
+Load prog with ip tool:
+
+ ip link set $ROOTDEV xdp off
+ ip link set $ROOTDEV xdp object xdp_vlan01_kern.o section xdp_drop_vlan_4011
+
+*/
+
+/* Changing VLAN to zero, have same practical effect as removing the VLAN. */
+#define TO_VLAN 0
+
+SEC("xdp_vlan_change")
+int xdp_prognum1(struct xdp_md *ctx)
+{
+ void *data_end = (void *)(long)ctx->data_end;
+ void *data = (void *)(long)ctx->data;
+ struct parse_pkt pkt = { 0 };
+
+ if (!parse_eth_frame(data, data_end, &pkt))
+ return XDP_ABORTED;
+
+ /* Change specific VLAN ID */
+ if (pkt.vlan_outer == TESTVLAN) {
+ struct _vlan_hdr *vlan_hdr = data + pkt.vlan_outer_offset;
+
+ /* Modifying VLAN, preserve top 4 bits */
+ vlan_hdr->h_vlan_TCI =
+ bpf_htons((bpf_ntohs(vlan_hdr->h_vlan_TCI) & 0xf000)
+ | TO_VLAN);
+ }
+
+ return XDP_PASS;
+}
+
+/*
+ * Show XDP+TC can cooperate, on creating a VLAN rewriter.
+ * 1. Create a XDP prog that can "pop"/remove a VLAN header.
+ * 2. Create a TC-bpf prog that egress can add a VLAN header.
+ */
+
+#ifndef ETH_ALEN /* Ethernet MAC address length */
+#define ETH_ALEN 6 /* bytes */
+#endif
+#define VLAN_HDR_SZ 4 /* bytes */
+
+SEC("xdp_vlan_remove_outer")
+int xdp_prognum2(struct xdp_md *ctx)
+{
+ void *data_end = (void *)(long)ctx->data_end;
+ void *data = (void *)(long)ctx->data;
+ struct parse_pkt pkt = { 0 };
+ char *dest;
+
+ if (!parse_eth_frame(data, data_end, &pkt))
+ return XDP_ABORTED;
+
+ /* Skip packet if no outer VLAN was detected */
+ if (pkt.vlan_outer_offset == 0)
+ return XDP_PASS;
+
+ /* Moving Ethernet header, dest overlap with src, memmove handle this */
+ dest = data;
+ dest+= VLAN_HDR_SZ;
+ /*
+ * Notice: Taking over vlan_hdr->h_vlan_encapsulated_proto, by
+ * only moving two MAC addrs (12 bytes), not overwriting last 2 bytes
+ */
+ __builtin_memmove(dest, data, ETH_ALEN * 2);
+ /* Note: LLVM built-in memmove inlining require size to be constant */
+
+ /* Move start of packet header seen by Linux kernel stack */
+ bpf_xdp_adjust_head(ctx, VLAN_HDR_SZ);
+
+ return XDP_PASS;
+}
+
+static __always_inline
+void shift_mac_4bytes_16bit(void *data)
+{
+ __u16 *p = data;
+
+ p[7] = p[5]; /* delete p[7] was vlan_hdr->h_vlan_TCI */
+ p[6] = p[4]; /* delete p[6] was ethhdr->h_proto */
+ p[5] = p[3];
+ p[4] = p[2];
+ p[3] = p[1];
+ p[2] = p[0];
+}
+
+static __always_inline
+void shift_mac_4bytes_32bit(void *data)
+{
+ __u32 *p = data;
+
+ /* Assuming VLAN hdr present. The 4 bytes in p[3] that gets
+ * overwritten, is ethhdr->h_proto and vlan_hdr->h_vlan_TCI.
+ * The vlan_hdr->h_vlan_encapsulated_proto take over role as
+ * ethhdr->h_proto.
+ */
+ p[3] = p[2];
+ p[2] = p[1];
+ p[1] = p[0];
+}
+
+SEC("xdp_vlan_remove_outer2")
+int xdp_prognum3(struct xdp_md *ctx)
+{
+ void *data_end = (void *)(long)ctx->data_end;
+ void *data = (void *)(long)ctx->data;
+ struct ethhdr *orig_eth = data;
+ struct parse_pkt pkt = { 0 };
+
+ if (!parse_eth_frame(orig_eth, data_end, &pkt))
+ return XDP_ABORTED;
+
+ /* Skip packet if no outer VLAN was detected */
+ if (pkt.vlan_outer_offset == 0)
+ return XDP_PASS;
+
+ /* Simply shift down MAC addrs 4 bytes, overwrite h_proto + TCI */
+ shift_mac_4bytes_32bit(data);
+
+ /* Move start of packet header seen by Linux kernel stack */
+ bpf_xdp_adjust_head(ctx, VLAN_HDR_SZ);
+
+ return XDP_PASS;
+}
+
+/*=====================================
+ * BELOW: TC-hook based ebpf programs
+ * ====================================
+ * The TC-clsact eBPF programs (currently) need to be attach via TC commands
+ */
+
+SEC("tc_vlan_push")
+int _tc_progA(struct __sk_buff *ctx)
+{
+ bpf_skb_vlan_push(ctx, bpf_htons(ETH_P_8021Q), TESTVLAN);
+
+ return TC_ACT_OK;
+}
+/*
+Commands to setup TC to use above bpf prog:
+
+export ROOTDEV=ixgbe2
+export FILE=xdp_vlan01_kern.o
+
+# Re-attach clsact to clear/flush existing role
+tc qdisc del dev $ROOTDEV clsact 2> /dev/null ;\
+tc qdisc add dev $ROOTDEV clsact
+
+# Attach BPF prog EGRESS
+tc filter add dev $ROOTDEV egress \
+ prio 1 handle 1 bpf da obj $FILE sec tc_vlan_push
+
+tc filter show dev $ROOTDEV egress
+*/
diff --git a/tools/testing/selftests/bpf/test_xdp_vlan.sh b/tools/testing/selftests/bpf/test_xdp_vlan.sh
new file mode 100755
index 000000000000..51a3a31d1aac
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_xdp_vlan.sh
@@ -0,0 +1,195 @@
+#!/bin/bash
+
+TESTNAME=xdp_vlan
+
+usage() {
+ echo "Testing XDP + TC eBPF VLAN manipulations: $TESTNAME"
+ echo ""
+ echo "Usage: $0 [-vfh]"
+ echo " -v | --verbose : Verbose"
+ echo " --flush : Flush before starting (e.g. after --interactive)"
+ echo " --interactive : Keep netns setup running after test-run"
+ echo ""
+}
+
+cleanup()
+{
+ local status=$?
+
+ if [ "$status" = "0" ]; then
+ echo "selftests: $TESTNAME [PASS]";
+ else
+ echo "selftests: $TESTNAME [FAILED]";
+ fi
+
+ if [ -n "$INTERACTIVE" ]; then
+ echo "Namespace setup still active explore with:"
+ echo " ip netns exec ns1 bash"
+ echo " ip netns exec ns2 bash"
+ exit $status
+ fi
+
+ set +e
+ ip link del veth1 2> /dev/null
+ ip netns del ns1 2> /dev/null
+ ip netns del ns2 2> /dev/null
+}
+
+# Using external program "getopt" to get --long-options
+OPTIONS=$(getopt -o hvfi: \
+ --long verbose,flush,help,interactive,debug -- "$@")
+if (( $? != 0 )); then
+ usage
+ echo "selftests: $TESTNAME [FAILED] Error calling getopt, unknown option?"
+ exit 2
+fi
+eval set -- "$OPTIONS"
+
+## --- Parse command line arguments / parameters ---
+while true; do
+ case "$1" in
+ -v | --verbose)
+ export VERBOSE=yes
+ shift
+ ;;
+ -i | --interactive | --debug )
+ INTERACTIVE=yes
+ shift
+ ;;
+ -f | --flush )
+ cleanup
+ shift
+ ;;
+ -- )
+ shift
+ break
+ ;;
+ -h | --help )
+ usage;
+ echo "selftests: $TESTNAME [SKIP] usage help info requested"
+ exit 0
+ ;;
+ * )
+ shift
+ break
+ ;;
+ esac
+done
+
+if [ "$EUID" -ne 0 ]; then
+ echo "selftests: $TESTNAME [FAILED] need root privileges"
+ exit 1
+fi
+
+ip link set dev lo xdp off 2>/dev/null > /dev/null
+if [ $? -ne 0 ];then
+ echo "selftests: $TESTNAME [SKIP] need ip xdp support"
+ exit 0
+fi
+
+# Interactive mode likely require us to cleanup netns
+if [ -n "$INTERACTIVE" ]; then
+ ip link del veth1 2> /dev/null
+ ip netns del ns1 2> /dev/null
+ ip netns del ns2 2> /dev/null
+fi
+
+# Exit on failure
+set -e
+
+# Some shell-tools dependencies
+which ip > /dev/null
+which tc > /dev/null
+which ethtool > /dev/null
+
+# Make rest of shell verbose, showing comments as doc/info
+if [ -n "$VERBOSE" ]; then
+ set -v
+fi
+
+# Create two namespaces
+ip netns add ns1
+ip netns add ns2
+
+# Run cleanup if failing or on kill
+trap cleanup 0 2 3 6 9
+
+# Create veth pair
+ip link add veth1 type veth peer name veth2
+
+# Move veth1 and veth2 into the respective namespaces
+ip link set veth1 netns ns1
+ip link set veth2 netns ns2
+
+# NOTICE: XDP require VLAN header inside packet payload
+# - Thus, disable VLAN offloading driver features
+# - For veth REMEMBER TX side VLAN-offload
+#
+# Disable rx-vlan-offload (mostly needed on ns1)
+ip netns exec ns1 ethtool -K veth1 rxvlan off
+ip netns exec ns2 ethtool -K veth2 rxvlan off
+#
+# Disable tx-vlan-offload (mostly needed on ns2)
+ip netns exec ns2 ethtool -K veth2 txvlan off
+ip netns exec ns1 ethtool -K veth1 txvlan off
+
+export IPADDR1=100.64.41.1
+export IPADDR2=100.64.41.2
+
+# In ns1/veth1 add IP-addr on plain net_device
+ip netns exec ns1 ip addr add ${IPADDR1}/24 dev veth1
+ip netns exec ns1 ip link set veth1 up
+
+# In ns2/veth2 create VLAN device
+export VLAN=4011
+export DEVNS2=veth2
+ip netns exec ns2 ip link add link $DEVNS2 name $DEVNS2.$VLAN type vlan id $VLAN
+ip netns exec ns2 ip addr add ${IPADDR2}/24 dev $DEVNS2.$VLAN
+ip netns exec ns2 ip link set $DEVNS2 up
+ip netns exec ns2 ip link set $DEVNS2.$VLAN up
+
+# Bringup lo in netns (to avoids confusing people using --interactive)
+ip netns exec ns1 ip link set lo up
+ip netns exec ns2 ip link set lo up
+
+# At this point, the hosts cannot reach each-other,
+# because ns2 are using VLAN tags on the packets.
+
+ip netns exec ns2 sh -c 'ping -W 1 -c 1 100.64.41.1 || echo "Okay ping fails"'
+
+
+# Now we can use the test_xdp_vlan.c program to pop/push these VLAN tags
+# ----------------------------------------------------------------------
+# In ns1: ingress use XDP to remove VLAN tags
+export DEVNS1=veth1
+export FILE=test_xdp_vlan.o
+
+# First test: Remove VLAN by setting VLAN ID 0, using "xdp_vlan_change"
+export XDP_PROG=xdp_vlan_change
+ip netns exec ns1 ip link set $DEVNS1 xdp object $FILE section $XDP_PROG
+
+# In ns1: egress use TC to add back VLAN tag 4011
+# (del cmd)
+# tc qdisc del dev $DEVNS1 clsact 2> /dev/null
+#
+ip netns exec ns1 tc qdisc add dev $DEVNS1 clsact
+ip netns exec ns1 tc filter add dev $DEVNS1 egress \
+ prio 1 handle 1 bpf da obj $FILE sec tc_vlan_push
+
+# Now the namespaces can reach each-other, test with ping:
+ip netns exec ns2 ping -W 2 -c 3 $IPADDR1
+ip netns exec ns1 ping -W 2 -c 3 $IPADDR2
+
+# Second test: Replace xdp prog, that fully remove vlan header
+#
+# Catch kernel bug for generic-XDP, that does didn't allow us to
+# remove a VLAN header, because skb->protocol still contain VLAN
+# ETH_P_8021Q indication, and this cause overwriting of our changes.
+#
+export XDP_PROG=xdp_vlan_remove_outer2
+ip netns exec ns1 ip link set $DEVNS1 xdp off
+ip netns exec ns1 ip link set $DEVNS1 xdp object $FILE section $XDP_PROG
+
+# Now the namespaces should still be able reach each-other, test with ping:
+ip netns exec ns2 ping -W 2 -c 3 $IPADDR1
+ip netns exec ns1 ping -W 2 -c 3 $IPADDR2
^ permalink raw reply related
* [bpf-next V2 PATCH 2/3] bpf: make TC vlan bpf_helpers avail to selftests
From: Jesper Dangaard Brouer @ 2018-10-09 10:04 UTC (permalink / raw)
To: netdev, Jesper Dangaard Brouer
Cc: liu.song.a23, Daniel Borkmann, yoel, Alexei Starovoitov,
John Fastabend
In-Reply-To: <153907945478.9484.16223890803803124822.stgit@firesoul>
The helper bpf_skb_vlan_push is needed by next patch, and the helper
bpf_skb_vlan_pop is added for completeness, regarding VLAN helpers.
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
tools/testing/selftests/bpf/bpf_helpers.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 1d407b3494f9..fda8c162d0df 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -155,6 +155,10 @@ static struct bpf_sock *(*bpf_sk_lookup_udp)(void *ctx,
(void *) BPF_FUNC_sk_lookup_udp;
static int (*bpf_sk_release)(struct bpf_sock *sk) =
(void *) BPF_FUNC_sk_release;
+static int (*bpf_skb_vlan_push)(void *ctx, __be16 vlan_proto, __u16 vlan_tci) =
+ (void *) BPF_FUNC_skb_vlan_push;
+static int (*bpf_skb_vlan_pop)(void *ctx) =
+ (void *) BPF_FUNC_skb_vlan_pop;
/* llvm builtin functions that eBPF C program may use to
* emit BPF_LD_ABS and BPF_LD_IND instructions
^ permalink raw reply related
* [bpf-next V2 PATCH 1/3] net: fix generic XDP to handle if eth header was mangled
From: Jesper Dangaard Brouer @ 2018-10-09 10:04 UTC (permalink / raw)
To: netdev, Jesper Dangaard Brouer
Cc: liu.song.a23, Daniel Borkmann, yoel, Alexei Starovoitov,
John Fastabend
In-Reply-To: <153907945478.9484.16223890803803124822.stgit@firesoul>
XDP can modify (and resize) the Ethernet header in the packet.
There is a bug in generic-XDP, because skb->protocol and skb->pkt_type
are setup before reaching (netif_receive_)generic_xdp.
This bug was hit when XDP were popping VLAN headers (changing
eth->h_proto), as skb->protocol still contains VLAN-indication
(ETH_P_8021Q) causing invocation of skb_vlan_untag(skb), which corrupt
the packet (basically popping the VLAN again).
This patch catch if XDP changed eth header in such a way, that SKB
fields needs to be updated.
V2: on request from Song Liu, use ETH_HLEN instead of mac_len,
in __skb_push() as eth_type_trans() use ETH_HLEN in paired skb_pull_inline().
Fixes: d445516966dc ("net: xdp: support xdp generic on virtual devices")
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
net/core/dev.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/net/core/dev.c b/net/core/dev.c
index 0b2d777e5b9e..ec96f50b0782 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4258,6 +4258,9 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
struct netdev_rx_queue *rxqueue;
void *orig_data, *orig_data_end;
u32 metalen, act = XDP_DROP;
+ __be16 orig_eth_type;
+ struct ethhdr *eth;
+ bool orig_bcast;
int hlen, off;
u32 mac_len;
@@ -4298,6 +4301,9 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
xdp->data_hard_start = skb->data - skb_headroom(skb);
orig_data_end = xdp->data_end;
orig_data = xdp->data;
+ eth = (struct ethhdr *)xdp->data;
+ orig_bcast = is_multicast_ether_addr_64bits(eth->h_dest);
+ orig_eth_type = eth->h_proto;
rxqueue = netif_get_rxqueue(skb);
xdp->rxq = &rxqueue->xdp_rxq;
@@ -4321,6 +4327,14 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
}
+ /* check if XDP changed eth hdr such SKB needs update */
+ eth = (struct ethhdr *)xdp->data;
+ if ((orig_eth_type != eth->h_proto) ||
+ (orig_bcast != is_multicast_ether_addr_64bits(eth->h_dest))) {
+ __skb_push(skb, ETH_HLEN);
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ }
+
switch (act) {
case XDP_REDIRECT:
case XDP_TX:
^ permalink raw reply related
* [bpf-next V2 PATCH 0/3] bpf/xdp: fix generic-XDP and demonstrate VLAN manipulation
From: Jesper Dangaard Brouer @ 2018-10-09 10:04 UTC (permalink / raw)
To: netdev, Jesper Dangaard Brouer
Cc: liu.song.a23, Daniel Borkmann, yoel, Alexei Starovoitov,
John Fastabend
While implementing PoC building blocks for eBPF code XDP+TC that can
manipulate VLANs headers, I discovered a bug in generic-XDP.
The fix should be backported to stable kernels. Even-though
generic-XDP was introduced in v4.12, I think the bug is not exposed
until v4.14 in the mentined fixes commit.
---
Jesper Dangaard Brouer (3):
net: fix generic XDP to handle if eth header was mangled
bpf: make TC vlan bpf_helpers avail to selftests
selftests/bpf: add XDP selftests for modifying and popping VLAN headers
net/core/dev.c | 14 +
tools/testing/selftests/bpf/Makefile | 6 -
tools/testing/selftests/bpf/bpf_helpers.h | 4
tools/testing/selftests/bpf/test_xdp_vlan.c | 292 ++++++++++++++++++++++++++
tools/testing/selftests/bpf/test_xdp_vlan.sh | 195 +++++++++++++++++
5 files changed, 509 insertions(+), 2 deletions(-)
create mode 100644 tools/testing/selftests/bpf/test_xdp_vlan.c
create mode 100755 tools/testing/selftests/bpf/test_xdp_vlan.sh
^ permalink raw reply
* Re: linux-next: manual merge of the net-next tree with the net tree
From: Jamal Hadi Salim @ 2018-10-09 10:02 UTC (permalink / raw)
To: Stephen Rothwell, David Miller, Networking
Cc: Linux-Next Mailing List, Linux Kernel Mailing List, Al Viro
In-Reply-To: <20181009122113.05fbf12a@canb.auug.org.au>
[-- Attachment #1: Type: text/plain, Size: 945 bytes --]
On 2018-10-08 9:21 p.m., Stephen Rothwell wrote:
> Hi all,
>
> Today's linux-next merge of the net-next tree got a conflict in:
>
> net/sched/cls_u32.c
>
> between commit:
>
> 6d4c407744dd ("net: sched: cls_u32: fix hnode refcounting")
>
> from the net tree and commit:
>
> a030598690c6 ("net: sched: cls_u32: simplify the hell out u32_delete() emptiness check")
>
> from the net-next tree.
>
> I fixed it up (I reverted the net tree commit as I could not tell
> wich parts of it, if any, are still needed) and can carry the fix as
> necessary. This is now fixed as far as linux-next is concerned, but any
> non trivial conflicts should be mentioned to your upstream maintainer
> when your tree is submitted for merging. You may also want to consider
> cooperating with the maintainer of the conflicting tree to minimise any
> particularly complex conflicts.
>
Attached should fix it. Al, please double check.
cheers,
jamal
[-- Attachment #2: al-merge-diff-net-next --]
[-- Type: text/plain, Size: 1165 bytes --]
--- a/net-next/net/sched/cls_u32.c 2018-10-09 05:18:04.046642676 -0400
+++ b/net/sched/cls_u32.c 2018-10-09 05:29:51.965528032 -0400
@@ -391,6 +391,7 @@
RCU_INIT_POINTER(root_ht->next, tp_c->hlist);
rcu_assign_pointer(tp_c->hlist, root_ht);
+ root_ht->refcnt++;
rcu_assign_pointer(tp->root, root_ht);
tp->data = tp_c;
return 0;
@@ -606,7 +607,7 @@
struct tc_u_hnode __rcu **hn;
struct tc_u_hnode *phn;
- WARN_ON(ht->refcnt);
+ WARN_ON(--ht->refcnt);
u32_clear_hnode(tp, ht, extack);
@@ -634,7 +635,7 @@
WARN_ON(root_ht == NULL);
- if (root_ht && --root_ht->refcnt == 0)
+ if (root_ht && --root_ht->refcnt == 1)
u32_destroy_hnode(tp, root_ht, extack);
if (--tp_c->refcnt == 0) {
@@ -679,7 +680,6 @@
}
if (ht->refcnt == 1) {
- ht->refcnt--;
u32_destroy_hnode(tp, ht, extack);
} else {
NL_SET_ERR_MSG_MOD(extack, "Can not delete in-use filter");
@@ -1079,8 +1079,7 @@
}
#endif
- err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], ovr,
- extack);
+ err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], ovr, extack);
if (err == 0) {
struct tc_u_knode __rcu **ins;
struct tc_u_knode *pins;
^ permalink raw reply
* Re: [PATCH v3 net-next] ravb: do not write 1 to reserved bits
From: Geert Uytterhoeven @ 2018-10-09 9:28 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: Simon Horman, David S. Miller, Magnus Damm, netdev, Linux-Renesas
In-Reply-To: <5bddb393-3060-6d74-4cf1-3547cb87924e@cogentembedded.com>
Hi Sergei,
On Tue, Sep 18, 2018 at 6:55 PM Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> On 09/18/2018 01:22 PM, Simon Horman wrote:
> > From: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
> > EtherAVB hardware requires 0 to be written to status register bits in
> > order to clear them, however, care must be taken not to:
> >
> > 1. Clear other bits, by writing zero to them
> > 2. Write one to reserved bits
> >
> > This patch corrects the ravb driver with respect to the second point above.
> > This is done by defining reserved bit masks for the affected registers and,
> > after auditing the code, ensure all sites that may write a one to a
> > reserved bit use are suitably masked.
> >
> > Signed-off-by: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
> > Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
> [...]
>
> Reviewed-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>
> > diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
> > index 1470fc12282b..9b6bf557a2f5 100644
> > --- a/drivers/net/ethernet/renesas/ravb.h
> > +++ b/drivers/net/ethernet/renesas/ravb.h
> > @@ -428,6 +428,7 @@ enum EIS_BIT {
> > EIS_CULF1 = 0x00000080,
> > EIS_TFFF = 0x00000100,
> > EIS_QFS = 0x00010000,
> > + EIS_RESERVED = (GENMASK(31, 17) | GENMASK(15, 11)),
>
> Well, I'm not a big fan of BIT() and GENMASK() -- they still lack a macro
> to #define a bit/field value. But if you prefer to use them, OK, let's be so...
FIELD_PREP()?
Perhaps the other bit definitions should be converted to BIT()?
That way it becomes much easier to match valid EIS_* bits with EIS_RESERVED.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v8 10/15] octeontx2-af: Reconfig MSIX base with IOVA
From: Sunil Kovvuri @ 2018-10-09 9:20 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Linux Netdev List, David S. Miller, linux-soc, Geetha sowjanya,
Sunil Goutham
In-Reply-To: <CAK8P3a01YPk6Bpn4o10za8pebAHA8sfXAEEBAidfgcvbWwzFpA@mail.gmail.com>
On Tue, Oct 9, 2018 at 1:27 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Tue, Oct 9, 2018 at 9:03 AM Sunil Kovvuri <sunil.kovvuri@gmail.com> wrote:
> > On Mon, Oct 8, 2018 at 5:38 PM Arnd Bergmann <arnd@arndb.de> wrote:
> > > On Sun, Oct 7, 2018 at 5:01 PM <sunil.kovvuri@gmail.com> wrote:
> > >
> > > >
> > > > + /* HW interprets RVU_AF_MSIXTR_BASE address as an IOVA, hence
> > > > + * create a IOMMU mapping for the physcial address configured by
> > > > + * firmware and reconfig RVU_AF_MSIXTR_BASE with IOVA.
> > > > + */
> > > > + cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_CONST);
> > > > + max_msix = cfg & 0xFFFFF;
> > > > + phy_addr = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_MSIXTR_BASE);
> > > > + iova = dma_map_single(rvu->dev, (void *)phy_addr,
> > > > + max_msix * PCI_MSIX_ENTRY_SIZE,
> > > > + DMA_BIDIRECTIONAL);
> > > > + if (dma_mapping_error(rvu->dev, iova))
> > > > + return -ENOMEM;
> > > > +
> > > > + rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_MSIXTR_BASE, (u64)iova);
> > > > + rvu->msix_base_iova = iova;
> > > > +
> > >
> > > I'm a bit puzzled by how this works. Does this rely on a specific iommu
> > > driver implementation? Normally a physical address makes no sense to the
> > > implementation backing dma_map_single() that tries to convert a
> > > linear kernel virtual address into a physical address.
> > >
> > > Arnd
> >
> > I understand what you are pointing at, but we did test this.
> > IOMMU on this silicon is standard ARM64 SMMUv3.
>
> I didn't doubt that you get the right results, I just couldn't see how ;-)
>
> > All dma_map_single does is virt_to_page and iommu_dma_map_page
> > converts it back i.e page_to_phys.
> > So the IOMMU driver gets the same physical address passed above and
> > creates a iova translation mapping.
> >
> > For reference below is the captured debug info for the same
> > =====
> > [ 19.435968] rvu_setup_msix_resources: phy_addr 0x3200000 iova 0xfff80000
> > [ 19.436967] rvu_setup_msix_resources: virt_to_page(phy_addr)
> > 0xffff7fe00000c800 page_to_phys(page) 0x3200000
> > offset_in_page(phy_addr) 0x00
> > =====
>
> I think if you enable CONFIG_DEBUG_VIRTUAL, the virt_to_page()
> above should trigger a warning in
>
> phys_addr_t __virt_to_phys(unsigned long x)
> {
> WARN(!__is_lm_address(x),
> "virt_to_phys used for non-linear address: %pK (%pS)\n",
> (void *)x,
> (void *)x);
>
> return __virt_to_phys_nodebug(x);
> }
>
> Can you verify that?
>
> Arnd
No, it isn't, as for 64bit systems CONFIG_SPARSEMEM_VMEMMAP is enabled.
But is there any alternative to what is being done ?
Thanks,
Sunil.
^ permalink raw reply
* [PATCH net-next] net/mlx4_en: Use minimal rx and tx ring sizes on kdump kernel
From: Tariq Toukan @ 2018-10-09 9:06 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Alaa Hleihel, Tariq Toukan
From: Alaa Hleihel <alaa@mellanox.com>
When memory is limited (on kdump kernel), reduce size of rx and tx rings.
Also reduce the number of rx rings.
Signed-off-by: Alaa Hleihel <alaa@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx4/en_main.c | 9 +++++++--
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 2 +-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c
index d25e16d2c319..109472d6b61f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
@@ -167,8 +167,13 @@ static void mlx4_en_get_profile(struct mlx4_en_dev *mdev)
params->prof[i].rx_ppp = pfcrx;
params->prof[i].tx_pause = !(pfcrx || pfctx);
params->prof[i].tx_ppp = pfctx;
- params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
- params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
+ if (mlx4_low_memory_profile()) {
+ params->prof[i].tx_ring_size = MLX4_EN_MIN_TX_SIZE;
+ params->prof[i].rx_ring_size = MLX4_EN_MIN_RX_SIZE;
+ } else {
+ params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
+ params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
+ }
params->prof[i].num_up = MLX4_EN_NUM_UP_LOW;
params->prof[i].num_tx_rings_p_up = params->max_num_tx_rings_p_up;
params->prof[i].tx_ring_num[TX] = params->max_num_tx_rings_p_up *
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index c3228b89df46..485d856546c6 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -72,7 +72,7 @@
#define MLX4_EN_PAGE_SIZE (1 << MLX4_EN_PAGE_SHIFT)
#define DEF_RX_RINGS 16
#define MAX_RX_RINGS 128
-#define MIN_RX_RINGS 4
+#define MIN_RX_RINGS 1
#define LOG_TXBB_SIZE 6
#define TXBB_SIZE BIT(LOG_TXBB_SIZE)
#define HEADROOM (2048 / TXBB_SIZE + 1)
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH net-next] rtnetlink: mpls: ip_valid_fib_dump_req() requires CONFIG_INET
From: David Ahern @ 2018-10-09 16:21 UTC (permalink / raw)
To: Arnd Bergmann, David S. Miller
Cc: Kirill Tkhai, Christian Brauner, netdev, linux-kernel
In-Reply-To: <20181009161031.1003047-1-arnd@arndb.de>
On 10/9/18 10:10 AM, Arnd Bergmann wrote:
> The newly added call to ip_valid_fib_dump_req() causes a link error
> in configurations that enable MPLS but not IPv4:
>
> net/mpls/af_mpls.o: In function `mpls_dump_routes':
> af_mpls.c:(.text+0xed0): undefined reference to `ip_valid_fib_dump_req'
>
> With the added IS_ENABLED() check we get the previous behavior
> back in that configuration, and skip the check.
>
> Fixes: e8ba330ac0c5 ("rtnetlink: Update fib dumps for strict data checking")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> net/mpls/af_mpls.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
> index 7f891ffffc05..99ff6114d513 100644
> --- a/net/mpls/af_mpls.c
> +++ b/net/mpls/af_mpls.c
> @@ -2041,7 +2041,7 @@ static int mpls_dump_routes(struct sk_buff *skb, struct netlink_callback *cb)
>
> ASSERT_RTNL();
>
> - if (cb->strict_check) {
> + if (IS_ENABLED(CONFIG_INET) && cb->strict_check) {
> int err = ip_valid_fib_dump_req(nlh, cb->extack);
>
> if (err < 0)
>
If INET is not defined then mpls will need its own valid_dump_req
function to ensure strict_check semantics are managed. I'll send a patch.
^ permalink raw reply
* [PATCH rdma-next v1 4/4] IB/mlx5: Allow scatter to CQE without global signaled WRs
From: Leon Romanovsky @ 2018-10-09 9:05 UTC (permalink / raw)
To: Doug Ledford, Jason Gunthorpe
Cc: Leon Romanovsky, RDMA mailing list, Guy Levi, Yonatan Cohen,
Saeed Mahameed, linux-netdev
In-Reply-To: <20181009090515.25223-1-leon@kernel.org>
From: Yonatan Cohen <yonatanc@mellanox.com>
Requester scatter to CQE is restricted to QPs configured to signal
all WRs.
This patch adds ability to enable scatter to cqe (force enable)
in the requester without sig_all, for users who do not want all WRs
signaled but rather just the ones whose data found in the CQE.
Signed-off-by: Yonatan Cohen <yonatanc@mellanox.com>
Reviewed-by: Guy Levi <guyle@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
drivers/infiniband/hw/mlx5/qp.c | 14 +++++++++++---
include/uapi/rdma/mlx5-abi.h | 1 +
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 73a53a8da9b6..1a6f34ea2f5d 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -1706,15 +1706,20 @@ static void configure_responder_scat_cqe(struct ib_qp_init_attr *init_attr,
static void configure_requester_scat_cqe(struct mlx5_ib_dev *dev,
struct ib_qp_init_attr *init_attr,
+ struct mlx5_ib_create_qp *ucmd,
void *qpc)
{
enum ib_qp_type qpt = init_attr->qp_type;
int scqe_sz;
+ bool allow_scat_cqe = 0;
if (qpt == IB_QPT_UC || qpt == IB_QPT_UD)
return;
- if (init_attr->sq_sig_type != IB_SIGNAL_ALL_WR)
+ if (ucmd)
+ allow_scat_cqe = ucmd->flags & MLX5_QP_FLAG_ALLOW_SCATTER_CQE;
+
+ if (!allow_scat_cqe && init_attr->sq_sig_type != IB_SIGNAL_ALL_WR)
return;
scqe_sz = mlx5_ib_get_cqe_size(init_attr->send_cq);
@@ -1836,7 +1841,8 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
MLX5_QP_FLAG_TUNNEL_OFFLOADS |
MLX5_QP_FLAG_BFREG_INDEX |
MLX5_QP_FLAG_TYPE_DCT |
- MLX5_QP_FLAG_TYPE_DCI))
+ MLX5_QP_FLAG_TYPE_DCI |
+ MLX5_QP_FLAG_ALLOW_SCATTER_CQE))
return -EINVAL;
err = get_qp_user_index(to_mucontext(pd->uobject->context),
@@ -1971,7 +1977,9 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
if (qp->scat_cqe && is_connected(init_attr->qp_type)) {
configure_responder_scat_cqe(init_attr, qpc);
- configure_requester_scat_cqe(dev, init_attr, qpc);
+ configure_requester_scat_cqe(dev, init_attr,
+ (pd && pd->uobject) ? &ucmd : NULL,
+ qpc);
}
if (qp->rq.wqe_cnt) {
diff --git a/include/uapi/rdma/mlx5-abi.h b/include/uapi/rdma/mlx5-abi.h
index 6056625237cf..8fa9f90e2bb1 100644
--- a/include/uapi/rdma/mlx5-abi.h
+++ b/include/uapi/rdma/mlx5-abi.h
@@ -47,6 +47,7 @@ enum {
MLX5_QP_FLAG_TYPE_DCI = 1 << 5,
MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_UC = 1 << 6,
MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_MC = 1 << 7,
+ MLX5_QP_FLAG_ALLOW_SCATTER_CQE = 1 << 8,
};
enum {
--
2.14.4
^ permalink raw reply related
* [PATCH rdma-next v1 3/4] IB/mlx5: Verify that driver supports user flags
From: Leon Romanovsky @ 2018-10-09 9:05 UTC (permalink / raw)
To: Doug Ledford, Jason Gunthorpe
Cc: Leon Romanovsky, RDMA mailing list, Guy Levi, Yonatan Cohen,
Saeed Mahameed, linux-netdev
In-Reply-To: <20181009090515.25223-1-leon@kernel.org>
From: Yonatan Cohen <yonatanc@mellanox.com>
Flags sent down from user might not be supported by
running driver.
This might lead to unwanted bugs.
To solve this, added macro to test for unsupported flags.
Signed-off-by: Yonatan Cohen <yonatanc@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
drivers/infiniband/hw/mlx5/qp.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index bae48bdf281c..73a53a8da9b6 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -1728,6 +1728,11 @@ static void configure_requester_scat_cqe(struct mlx5_ib_dev *dev,
MLX5_SET(qpc, qpc, cs_req, MLX5_REQ_SCAT_DATA32_CQE);
}
+static inline bool check_flags_mask(uint64_t input, uint64_t supported)
+{
+ return (input & ~supported) == 0;
+}
+
static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
struct ib_qp_init_attr *init_attr,
struct ib_udata *udata, struct mlx5_ib_qp *qp)
@@ -1825,6 +1830,15 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
return -EFAULT;
}
+ if (!check_flags_mask(ucmd.flags,
+ MLX5_QP_FLAG_SIGNATURE |
+ MLX5_QP_FLAG_SCATTER_CQE |
+ MLX5_QP_FLAG_TUNNEL_OFFLOADS |
+ MLX5_QP_FLAG_BFREG_INDEX |
+ MLX5_QP_FLAG_TYPE_DCT |
+ MLX5_QP_FLAG_TYPE_DCI))
+ return -EINVAL;
+
err = get_qp_user_index(to_mucontext(pd->uobject->context),
&ucmd, udata->inlen, &uidx);
if (err)
--
2.14.4
^ permalink raw reply related
* [PATCH rdma-next v1 2/4] IB/mlx5: Support scatter to CQE for DC transport type
From: Leon Romanovsky @ 2018-10-09 9:05 UTC (permalink / raw)
To: Doug Ledford, Jason Gunthorpe
Cc: Leon Romanovsky, RDMA mailing list, Guy Levi, Yonatan Cohen,
Saeed Mahameed, linux-netdev
In-Reply-To: <20181009090515.25223-1-leon@kernel.org>
From: Yonatan Cohen <yonatanc@mellanox.com>
Scatter to CQE is a HW offload that saves PCI writes by scattering the
payload to the CQE.
This patch extends already existing functionality to support DC
transport type.
Signed-off-by: Yonatan Cohen <yonatanc@mellanox.com>
Reviewed-by: Guy Levi <guyle@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
drivers/infiniband/hw/mlx5/cq.c | 2 +-
drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +-
drivers/infiniband/hw/mlx5/qp.c | 71 ++++++++++++++++++++++++++----------
3 files changed, 54 insertions(+), 21 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index dae30b6478bf..a41519dc8d3a 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -1460,7 +1460,7 @@ int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
return err;
}
-int mlx5_ib_get_cqe_size(struct mlx5_ib_dev *dev, struct ib_cq *ibcq)
+int mlx5_ib_get_cqe_size(struct ib_cq *ibcq)
{
struct mlx5_ib_cq *cq;
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index e5ec3fdaa4d5..f52dfed1395d 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -1127,7 +1127,7 @@ void __mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem,
void mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem,
int page_shift, __be64 *pas, int access_flags);
void mlx5_ib_copy_pas(u64 *old, u64 *new, int step, int num);
-int mlx5_ib_get_cqe_size(struct mlx5_ib_dev *dev, struct ib_cq *ibcq);
+int mlx5_ib_get_cqe_size(struct ib_cq *ibcq);
int mlx5_mr_cache_init(struct mlx5_ib_dev *dev);
int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev);
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index fa8e5dc65cb4..bae48bdf281c 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -1053,7 +1053,8 @@ static u32 get_rx_type(struct mlx5_ib_qp *qp, struct ib_qp_init_attr *attr)
static int is_connected(enum ib_qp_type qp_type)
{
- if (qp_type == IB_QPT_RC || qp_type == IB_QPT_UC)
+ if (qp_type == IB_QPT_RC || qp_type == IB_QPT_UC ||
+ qp_type == MLX5_IB_QPT_DCI)
return 1;
return 0;
@@ -1684,6 +1685,49 @@ static int create_rss_raw_qp_tir(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
return err;
}
+static void configure_responder_scat_cqe(struct ib_qp_init_attr *init_attr,
+ void *qpc)
+{
+ int rcqe_sz;
+
+ if (init_attr->qp_type == MLX5_IB_QPT_DCI)
+ return;
+
+ rcqe_sz = mlx5_ib_get_cqe_size(init_attr->recv_cq);
+
+ if (rcqe_sz == 128) {
+ MLX5_SET(qpc, qpc, cs_res, MLX5_RES_SCAT_DATA64_CQE);
+ return;
+ }
+
+ if (init_attr->qp_type != MLX5_IB_QPT_DCT)
+ MLX5_SET(qpc, qpc, cs_res, MLX5_RES_SCAT_DATA32_CQE);
+}
+
+static void configure_requester_scat_cqe(struct mlx5_ib_dev *dev,
+ struct ib_qp_init_attr *init_attr,
+ void *qpc)
+{
+ enum ib_qp_type qpt = init_attr->qp_type;
+ int scqe_sz;
+
+ if (qpt == IB_QPT_UC || qpt == IB_QPT_UD)
+ return;
+
+ if (init_attr->sq_sig_type != IB_SIGNAL_ALL_WR)
+ return;
+
+ scqe_sz = mlx5_ib_get_cqe_size(init_attr->send_cq);
+ if (scqe_sz == 128) {
+ MLX5_SET(qpc, qpc, cs_req, MLX5_REQ_SCAT_DATA64_CQE);
+ return;
+ }
+
+ if (init_attr->qp_type != MLX5_IB_QPT_DCI ||
+ MLX5_CAP_GEN(dev->mdev, dc_req_scat_data_cqe))
+ MLX5_SET(qpc, qpc, cs_req, MLX5_REQ_SCAT_DATA32_CQE);
+}
+
static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
struct ib_qp_init_attr *init_attr,
struct ib_udata *udata, struct mlx5_ib_qp *qp)
@@ -1787,7 +1831,8 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
return err;
qp->wq_sig = !!(ucmd.flags & MLX5_QP_FLAG_SIGNATURE);
- qp->scat_cqe = !!(ucmd.flags & MLX5_QP_FLAG_SCATTER_CQE);
+ if (MLX5_CAP_GEN(dev->mdev, sctr_data_cqe))
+ qp->scat_cqe = !!(ucmd.flags & MLX5_QP_FLAG_SCATTER_CQE);
if (ucmd.flags & MLX5_QP_FLAG_TUNNEL_OFFLOADS) {
if (init_attr->qp_type != IB_QPT_RAW_PACKET ||
!tunnel_offload_supported(mdev)) {
@@ -1911,23 +1956,8 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
MLX5_SET(qpc, qpc, cd_slave_receive, 1);
if (qp->scat_cqe && is_connected(init_attr->qp_type)) {
- int rcqe_sz;
- int scqe_sz;
-
- rcqe_sz = mlx5_ib_get_cqe_size(dev, init_attr->recv_cq);
- scqe_sz = mlx5_ib_get_cqe_size(dev, init_attr->send_cq);
-
- if (rcqe_sz == 128)
- MLX5_SET(qpc, qpc, cs_res, MLX5_RES_SCAT_DATA64_CQE);
- else
- MLX5_SET(qpc, qpc, cs_res, MLX5_RES_SCAT_DATA32_CQE);
-
- if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) {
- if (scqe_sz == 128)
- MLX5_SET(qpc, qpc, cs_req, MLX5_REQ_SCAT_DATA64_CQE);
- else
- MLX5_SET(qpc, qpc, cs_req, MLX5_REQ_SCAT_DATA32_CQE);
- }
+ configure_responder_scat_cqe(init_attr, qpc);
+ configure_requester_scat_cqe(dev, init_attr, qpc);
}
if (qp->rq.wqe_cnt) {
@@ -2302,6 +2332,9 @@ static struct ib_qp *mlx5_ib_create_dct(struct ib_pd *pd,
MLX5_SET64(dctc, dctc, dc_access_key, ucmd->access_key);
MLX5_SET(dctc, dctc, user_index, uidx);
+ if (ucmd->flags & MLX5_QP_FLAG_SCATTER_CQE)
+ configure_responder_scat_cqe(attr, dctc);
+
qp->state = IB_QPS_RESET;
return &qp->ibqp;
--
2.14.4
^ permalink raw reply related
* [PATCH mlx5-next v1 1/4] net/mlx5: Expose DC scatter to CQE capability bit
From: Leon Romanovsky @ 2018-10-09 9:05 UTC (permalink / raw)
To: Doug Ledford, Jason Gunthorpe
Cc: Leon Romanovsky, RDMA mailing list, Guy Levi, Yonatan Cohen,
Saeed Mahameed, linux-netdev
In-Reply-To: <20181009090515.25223-1-leon@kernel.org>
From: Yonatan Cohen <yonatanc@mellanox.com>
dc_req_scat_data_cqe capability bit determines
if requester scatter to cqe is available for 64 bytes CQE over
DC transport type.
Signed-off-by: Yonatan Cohen <yonatanc@mellanox.com>
Reviewed-by: Guy Levi <guyle@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
include/linux/mlx5/mlx5_ifc.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 68f4d5f9d929..0f460fb22c31 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -1005,7 +1005,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 umr_modify_atomic_disabled[0x1];
u8 umr_indirect_mkey_disabled[0x1];
u8 umr_fence[0x2];
- u8 reserved_at_20c[0x3];
+ u8 dc_req_scat_data_cqe[0x1];
+ u8 reserved_at_20d[0x2];
u8 drain_sigerr[0x1];
u8 cmdif_checksum[0x2];
u8 sigerr_cqe[0x1];
--
2.14.4
^ permalink raw reply related
* [PATCH rdma-next v1 0/4] Scatter to CQE
From: Leon Romanovsky @ 2018-10-09 9:05 UTC (permalink / raw)
To: Doug Ledford, Jason Gunthorpe
Cc: Leon Romanovsky, RDMA mailing list, Guy Levi, Yonatan Cohen,
Saeed Mahameed, linux-netdev
From: Leon Romanovsky <leonro@mellanox.com>
Changelog v0->v1:
* Changed patch #3 to use check_mask function from rdma-core instead define.
--------------------------------------------------------------------------
>From Yonatan,
Scatter to CQE is a HW offload feature that saves PCI writes by
scattering the payload to the CQE.
The feature depends on the CQE size and if the CQE size is 64B, it will
work for payload smaller than 32. If the CQE size is 128B, it will work for
payload smaller than 64.
The feature works for responder and requestor:
1. For responder, if the payload is small as required above, the data
will be part of the CQE, and thus we save another PCI transaction the recv buffers.
2. For requestor, this can be used to get the RDMA_READ response and
RDMA_ATOMIC response in the CQE. This feature is already supported in upstream.
As part of this series, we are adding support for DC transport type and
ability to enable the feature (force enable) in the requestor when SQ
is not configured to signal all WRs.
Thanks
Yonatan Cohen (4):
net/mlx5: Expose DC scatter to CQE capability bit
IB/mlx5: Support scatter to CQE for DC transport type
IB/mlx5: Verify that driver supports user flags
IB/mlx5: Allow scatter to CQE without global signaled WRs
drivers/infiniband/hw/mlx5/cq.c | 2 +-
drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +-
drivers/infiniband/hw/mlx5/qp.c | 93 ++++++++++++++++++++++++++++--------
include/linux/mlx5/mlx5_ifc.h | 3 +-
include/uapi/rdma/mlx5-abi.h | 1 +
5 files changed, 79 insertions(+), 22 deletions(-)
^ permalink raw reply
* [PATCH net-next] rtnetlink: mpls: ip_valid_fib_dump_req() requires CONFIG_INET
From: Arnd Bergmann @ 2018-10-09 16:10 UTC (permalink / raw)
To: David S. Miller, David Ahern
Cc: Arnd Bergmann, Kirill Tkhai, Christian Brauner, netdev,
linux-kernel
The newly added call to ip_valid_fib_dump_req() causes a link error
in configurations that enable MPLS but not IPv4:
net/mpls/af_mpls.o: In function `mpls_dump_routes':
af_mpls.c:(.text+0xed0): undefined reference to `ip_valid_fib_dump_req'
With the added IS_ENABLED() check we get the previous behavior
back in that configuration, and skip the check.
Fixes: e8ba330ac0c5 ("rtnetlink: Update fib dumps for strict data checking")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
net/mpls/af_mpls.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 7f891ffffc05..99ff6114d513 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -2041,7 +2041,7 @@ static int mpls_dump_routes(struct sk_buff *skb, struct netlink_callback *cb)
ASSERT_RTNL();
- if (cb->strict_check) {
+ if (IS_ENABLED(CONFIG_INET) && cb->strict_check) {
int err = ip_valid_fib_dump_req(nlh, cb->extack);
if (err < 0)
--
2.18.0
^ permalink raw reply related
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