* [PATCH v3 0/5] can: sja1000: cleanups and new OF property
From: Florian Vaussard @ 2014-01-31 13:34 UTC (permalink / raw)
To: Wolfgang Grandegger, Marc Kleine-Budde
Cc: Andreas Larsson, linux-can, netdev, sparclinux, linux-kernel,
florian.vaussard
Hello,
(could someone with a SJA1000 on SPARC perform a functional test
to see if interrupts are working? it would be great :-)
Changes since v2:
- Dropped patch 1 "can: sja1000: remove unused defines"
- Addressed Marc's comments on patch 4 and 6 (now 3 and 5)
Changes since v1:
- Merge sja1000_of_platform.c into sja1000_platform.c (patch 4)
The first part of this series performs serveral small cleanups
(patches 1 and 2).
Patch 3 merges sja1000_of_platform.c into sja1000_platform.c.
Changes are pretty conservatives (mostly copy/paste/move). IRQ
is treated differently in the OF and non-OF versions, thus this
is where the fused version differs the most.
The final part introduces the 'reg-io-width' binding (already used
by some other drivers) to perform a similar job as what was done
with IORESOURCE_MEM_XXBIT. This is needed on my system to correctly
take into account the aliasing of the address bus.
All patches were tested using OF boot on my OMAP3 system with a
memory-mapped SJA1000. Thus, the non-OF path is not tested, as
I do not have a platform data at hand.
Regards,
Florian
v1: http://thread.gmane.org/gmane.linux.kernel/1637835
v2: http://thread.gmane.org/gmane.linux.can/4831
Florian Vaussard (5):
can: sja1000: convert printk to use netdev API
can: sja1000: platform: use devm_* APIs
can: sja1000: fuse of_platform into platform
Documentation: devicetree: sja1000: add reg-io-width binding
can: sja1000: of: add reg-io-width property for 8, 16 and 32-bit
register access
.../devicetree/bindings/net/can/sja1000.txt | 4 +
drivers/net/can/sja1000/Kconfig | 13 +-
drivers/net/can/sja1000/Makefile | 1 -
drivers/net/can/sja1000/sja1000.c | 3 +-
drivers/net/can/sja1000/sja1000_of_platform.c | 221 ---------------------
drivers/net/can/sja1000/sja1000_platform.c | 190 ++++++++++++------
6 files changed, 137 insertions(+), 295 deletions(-)
delete mode 100644 drivers/net/can/sja1000/sja1000_of_platform.c
--
1.8.1.2
^ permalink raw reply
* [PATCH v3 1/5] can: sja1000: convert printk to use netdev API
From: Florian Vaussard @ 2014-01-31 13:34 UTC (permalink / raw)
To: Wolfgang Grandegger, Marc Kleine-Budde
Cc: Andreas Larsson, linux-can, netdev, sparclinux, linux-kernel,
florian.vaussard
In-Reply-To: <1391175277-19833-1-git-send-email-florian.vaussard@epfl.ch>
Use netdev_* where applicable.
Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
---
drivers/net/can/sja1000/sja1000.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index f17c301..55cce47 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -106,8 +106,7 @@ static int sja1000_probe_chip(struct net_device *dev)
struct sja1000_priv *priv = netdev_priv(dev);
if (priv->reg_base && sja1000_is_absent(priv)) {
- printk(KERN_INFO "%s: probing @0x%lX failed\n",
- DRV_NAME, dev->base_addr);
+ netdev_err(dev, "probing failed\n");
return 0;
}
return -1;
--
1.8.1.2
^ permalink raw reply related
* [PATCH v3 2/5] can: sja1000: platform: use devm_* APIs
From: Florian Vaussard @ 2014-01-31 13:34 UTC (permalink / raw)
To: Wolfgang Grandegger, Marc Kleine-Budde
Cc: Andreas Larsson, linux-can, netdev, sparclinux, linux-kernel,
florian.vaussard
In-Reply-To: <1391175277-19833-1-git-send-email-florian.vaussard@epfl.ch>
Simplify probe and remove functions by converting most of the resources
to use devm_* APIs.
Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
---
drivers/net/can/sja1000/sja1000_platform.c | 46 ++++++++----------------------
1 file changed, 12 insertions(+), 34 deletions(-)
diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c
index 29f9b63..779679a 100644
--- a/drivers/net/can/sja1000/sja1000_platform.c
+++ b/drivers/net/can/sja1000/sja1000_platform.c
@@ -79,34 +79,26 @@ static int sp_probe(struct platform_device *pdev)
pdata = dev_get_platdata(&pdev->dev);
if (!pdata) {
dev_err(&pdev->dev, "No platform data provided!\n");
- err = -ENODEV;
- goto exit;
+ return -ENODEV;
}
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res_mem || !res_irq) {
- err = -ENODEV;
- goto exit;
- }
+ if (!res_mem || !res_irq)
+ return -ENODEV;
- if (!request_mem_region(res_mem->start, resource_size(res_mem),
- DRV_NAME)) {
- err = -EBUSY;
- goto exit;
- }
+ if (!devm_request_mem_region(&pdev->dev, res_mem->start,
+ resource_size(res_mem), DRV_NAME))
+ return -EBUSY;
- addr = ioremap_nocache(res_mem->start, resource_size(res_mem));
- if (!addr) {
- err = -ENOMEM;
- goto exit_release;
- }
+ addr = devm_ioremap_nocache(&pdev->dev, res_mem->start,
+ resource_size(res_mem));
+ if (!addr)
+ return -ENOMEM;
dev = alloc_sja1000dev(0);
- if (!dev) {
- err = -ENOMEM;
- goto exit_iounmap;
- }
+ if (!dev)
+ return -ENOMEM;
priv = netdev_priv(dev);
dev->irq = res_irq->start;
@@ -151,28 +143,14 @@ static int sp_probe(struct platform_device *pdev)
exit_free:
free_sja1000dev(dev);
- exit_iounmap:
- iounmap(addr);
- exit_release:
- release_mem_region(res_mem->start, resource_size(res_mem));
- exit:
return err;
}
static int sp_remove(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
- struct sja1000_priv *priv = netdev_priv(dev);
- struct resource *res;
unregister_sja1000dev(dev);
-
- if (priv->reg_base)
- iounmap(priv->reg_base);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
-
free_sja1000dev(dev);
return 0;
--
1.8.1.2
^ permalink raw reply related
* [PATCH v3 3/5] can: sja1000: fuse of_platform into platform
From: Florian Vaussard @ 2014-01-31 13:34 UTC (permalink / raw)
To: Wolfgang Grandegger, Marc Kleine-Budde
Cc: Andreas Larsson, linux-can, netdev, sparclinux, linux-kernel,
florian.vaussard
In-Reply-To: <1391175277-19833-1-git-send-email-florian.vaussard@epfl.ch>
The OpenFirmware probe can be merged into the standard platform
probe to leverage common code.
Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
---
drivers/net/can/sja1000/Kconfig | 13 +-
drivers/net/can/sja1000/Makefile | 1 -
drivers/net/can/sja1000/sja1000_of_platform.c | 221 --------------------------
drivers/net/can/sja1000/sja1000_platform.c | 134 ++++++++++++----
4 files changed, 109 insertions(+), 260 deletions(-)
delete mode 100644 drivers/net/can/sja1000/sja1000_of_platform.c
diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig
index ff2ba86..4b18b87 100644
--- a/drivers/net/can/sja1000/Kconfig
+++ b/drivers/net/can/sja1000/Kconfig
@@ -17,16 +17,9 @@ config CAN_SJA1000_PLATFORM
the "platform bus" (Linux abstraction for directly to the
processor attached devices). Which can be found on various
boards from Phytec (http://www.phytec.de) like the PCM027,
- PCM038.
-
-config CAN_SJA1000_OF_PLATFORM
- tristate "Generic OF Platform Bus based SJA1000 driver"
- depends on OF
- ---help---
- This driver adds support for the SJA1000 chips connected to
- the OpenFirmware "platform bus" found on embedded systems with
- OpenFirmware bindings, e.g. if you have a PowerPC based system
- you may want to enable this option.
+ PCM038. It also provides the OpenFirmware "platform bus" found
+ on embedded systems with OpenFirmware bindings, e.g. if you
+ have a PowerPC based system you may want to enable this option.
config CAN_EMS_PCMCIA
tristate "EMS CPC-CARD Card"
diff --git a/drivers/net/can/sja1000/Makefile b/drivers/net/can/sja1000/Makefile
index b3d05cb..531d5fc 100644
--- a/drivers/net/can/sja1000/Makefile
+++ b/drivers/net/can/sja1000/Makefile
@@ -5,7 +5,6 @@
obj-$(CONFIG_CAN_SJA1000) += sja1000.o
obj-$(CONFIG_CAN_SJA1000_ISA) += sja1000_isa.o
obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o
-obj-$(CONFIG_CAN_SJA1000_OF_PLATFORM) += sja1000_of_platform.o
obj-$(CONFIG_CAN_EMS_PCMCIA) += ems_pcmcia.o
obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o
obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o
diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c
deleted file mode 100644
index 047accd..0000000
--- a/drivers/net/can/sja1000/sja1000_of_platform.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Driver for SJA1000 CAN controllers on the OpenFirmware platform bus
- *
- * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the version 2 of the GNU General Public License
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/* This is a generic driver for SJA1000 chips on the OpenFirmware platform
- * bus found on embedded PowerPC systems. You need a SJA1000 CAN node
- * definition in your flattened device tree source (DTS) file similar to:
- *
- * can@3,100 {
- * compatible = "nxp,sja1000";
- * reg = <3 0x100 0x80>;
- * interrupts = <2 0>;
- * interrupt-parent = <&mpic>;
- * nxp,external-clock-frequency = <16000000>;
- * };
- *
- * See "Documentation/devicetree/bindings/net/can/sja1000.txt" for further
- * information.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/can/dev.h>
-
-#include <linux/of_platform.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-
-#include "sja1000.h"
-
-#define DRV_NAME "sja1000_of_platform"
-
-MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
-MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the OF platform bus");
-MODULE_LICENSE("GPL v2");
-
-#define SJA1000_OFP_CAN_CLOCK (16000000 / 2)
-
-#define SJA1000_OFP_OCR OCR_TX0_PULLDOWN
-#define SJA1000_OFP_CDR (CDR_CBP | CDR_CLK_OFF)
-
-static u8 sja1000_ofp_read_reg(const struct sja1000_priv *priv, int reg)
-{
- return ioread8(priv->reg_base + reg);
-}
-
-static void sja1000_ofp_write_reg(const struct sja1000_priv *priv,
- int reg, u8 val)
-{
- iowrite8(val, priv->reg_base + reg);
-}
-
-static int sja1000_ofp_remove(struct platform_device *ofdev)
-{
- struct net_device *dev = platform_get_drvdata(ofdev);
- struct sja1000_priv *priv = netdev_priv(dev);
- struct device_node *np = ofdev->dev.of_node;
- struct resource res;
-
- unregister_sja1000dev(dev);
- free_sja1000dev(dev);
- iounmap(priv->reg_base);
- irq_dispose_mapping(dev->irq);
-
- of_address_to_resource(np, 0, &res);
- release_mem_region(res.start, resource_size(&res));
-
- return 0;
-}
-
-static int sja1000_ofp_probe(struct platform_device *ofdev)
-{
- struct device_node *np = ofdev->dev.of_node;
- struct net_device *dev;
- struct sja1000_priv *priv;
- struct resource res;
- u32 prop;
- int err, irq, res_size;
- void __iomem *base;
-
- err = of_address_to_resource(np, 0, &res);
- if (err) {
- dev_err(&ofdev->dev, "invalid address\n");
- return err;
- }
-
- res_size = resource_size(&res);
-
- if (!request_mem_region(res.start, res_size, DRV_NAME)) {
- dev_err(&ofdev->dev, "couldn't request %pR\n", &res);
- return -EBUSY;
- }
-
- base = ioremap_nocache(res.start, res_size);
- if (!base) {
- dev_err(&ofdev->dev, "couldn't ioremap %pR\n", &res);
- err = -ENOMEM;
- goto exit_release_mem;
- }
-
- irq = irq_of_parse_and_map(np, 0);
- if (irq == 0) {
- dev_err(&ofdev->dev, "no irq found\n");
- err = -ENODEV;
- goto exit_unmap_mem;
- }
-
- dev = alloc_sja1000dev(0);
- if (!dev) {
- err = -ENOMEM;
- goto exit_dispose_irq;
- }
-
- priv = netdev_priv(dev);
-
- priv->read_reg = sja1000_ofp_read_reg;
- priv->write_reg = sja1000_ofp_write_reg;
-
- err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop);
- if (!err)
- priv->can.clock.freq = prop / 2;
- else
- priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */
-
- err = of_property_read_u32(np, "nxp,tx-output-mode", &prop);
- if (!err)
- priv->ocr |= prop & OCR_MODE_MASK;
- else
- priv->ocr |= OCR_MODE_NORMAL; /* default */
-
- err = of_property_read_u32(np, "nxp,tx-output-config", &prop);
- if (!err)
- priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK;
- else
- priv->ocr |= OCR_TX0_PULLDOWN; /* default */
-
- err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop);
- if (!err && prop) {
- u32 divider = priv->can.clock.freq * 2 / prop;
-
- if (divider > 1)
- priv->cdr |= divider / 2 - 1;
- else
- priv->cdr |= CDR_CLKOUT_MASK;
- } else {
- priv->cdr |= CDR_CLK_OFF; /* default */
- }
-
- if (!of_property_read_bool(np, "nxp,no-comparator-bypass"))
- priv->cdr |= CDR_CBP; /* default */
-
- priv->irq_flags = IRQF_SHARED;
- priv->reg_base = base;
-
- dev->irq = irq;
-
- dev_info(&ofdev->dev,
- "reg_base=0x%p irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n",
- priv->reg_base, dev->irq, priv->can.clock.freq,
- priv->ocr, priv->cdr);
-
- platform_set_drvdata(ofdev, dev);
- SET_NETDEV_DEV(dev, &ofdev->dev);
-
- err = register_sja1000dev(dev);
- if (err) {
- dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
- DRV_NAME, err);
- goto exit_free_sja1000;
- }
-
- return 0;
-
-exit_free_sja1000:
- free_sja1000dev(dev);
-exit_dispose_irq:
- irq_dispose_mapping(irq);
-exit_unmap_mem:
- iounmap(base);
-exit_release_mem:
- release_mem_region(res.start, res_size);
-
- return err;
-}
-
-static struct of_device_id sja1000_ofp_table[] = {
- {.compatible = "nxp,sja1000"},
- {},
-};
-MODULE_DEVICE_TABLE(of, sja1000_ofp_table);
-
-static struct platform_driver sja1000_ofp_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = DRV_NAME,
- .of_match_table = sja1000_ofp_table,
- },
- .probe = sja1000_ofp_probe,
- .remove = sja1000_ofp_remove,
-};
-
-module_platform_driver(sja1000_ofp_driver);
diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c
index 779679a..50dece8 100644
--- a/drivers/net/can/sja1000/sja1000_platform.c
+++ b/drivers/net/can/sja1000/sja1000_platform.c
@@ -27,12 +27,16 @@
#include <linux/can/dev.h>
#include <linux/can/platform/sja1000.h>
#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
#include "sja1000.h"
#define DRV_NAME "sja1000_platform"
+#define SP_CAN_CLOCK (16000000 / 2)
MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus");
MODULE_ALIAS("platform:" DRV_NAME);
MODULE_LICENSE("GPL v2");
@@ -67,24 +71,92 @@ static void sp_write_reg32(const struct sja1000_priv *priv, int reg, u8 val)
iowrite8(val, priv->reg_base + reg * 4);
}
-static int sp_probe(struct platform_device *pdev)
+static void sp_populate(struct sja1000_priv *priv,
+ struct sja1000_platform_data *pdata,
+ unsigned long resource_mem_flags)
+{
+ /* The CAN clock frequency is half the oscillator clock frequency */
+ priv->can.clock.freq = pdata->osc_freq / 2;
+ priv->ocr = pdata->ocr;
+ priv->cdr = pdata->cdr;
+
+ switch (resource_mem_flags & IORESOURCE_MEM_TYPE_MASK) {
+ case IORESOURCE_MEM_32BIT:
+ priv->read_reg = sp_read_reg32;
+ priv->write_reg = sp_write_reg32;
+ break;
+ case IORESOURCE_MEM_16BIT:
+ priv->read_reg = sp_read_reg16;
+ priv->write_reg = sp_write_reg16;
+ break;
+ case IORESOURCE_MEM_8BIT:
+ default:
+ priv->read_reg = sp_read_reg8;
+ priv->write_reg = sp_write_reg8;
+ break;
+ }
+}
+
+static void sp_populate_of(struct sja1000_priv *priv, struct device_node *of)
{
int err;
+ u32 prop;
+
+ priv->read_reg = sp_read_reg8;
+ priv->write_reg = sp_write_reg8;
+
+ err = of_property_read_u32(of, "nxp,external-clock-frequency", &prop);
+ if (!err)
+ priv->can.clock.freq = prop / 2;
+ else
+ priv->can.clock.freq = SP_CAN_CLOCK; /* default */
+
+ err = of_property_read_u32(of, "nxp,tx-output-mode", &prop);
+ if (!err)
+ priv->ocr |= prop & OCR_MODE_MASK;
+ else
+ priv->ocr |= OCR_MODE_NORMAL; /* default */
+
+ err = of_property_read_u32(of, "nxp,tx-output-config", &prop);
+ if (!err)
+ priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK;
+ else
+ priv->ocr |= OCR_TX0_PULLDOWN; /* default */
+
+ err = of_property_read_u32(of, "nxp,clock-out-frequency", &prop);
+ if (!err && prop) {
+ u32 divider = priv->can.clock.freq * 2 / prop;
+
+ if (divider > 1)
+ priv->cdr |= divider / 2 - 1;
+ else
+ priv->cdr |= CDR_CLKOUT_MASK;
+ } else {
+ priv->cdr |= CDR_CLK_OFF; /* default */
+ }
+
+ if (!of_property_read_bool(of, "nxp,no-comparator-bypass"))
+ priv->cdr |= CDR_CBP; /* default */
+}
+
+static int sp_probe(struct platform_device *pdev)
+{
+ int err, irq = 0;
void __iomem *addr;
struct net_device *dev;
struct sja1000_priv *priv;
- struct resource *res_mem, *res_irq;
+ struct resource *res_mem, *res_irq = NULL;
struct sja1000_platform_data *pdata;
+ struct device_node *of = pdev->dev.of_node;
pdata = dev_get_platdata(&pdev->dev);
- if (!pdata) {
+ if (!pdata && !of) {
dev_err(&pdev->dev, "No platform data provided!\n");
return -ENODEV;
}
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res_mem || !res_irq)
+ if (!res_mem)
return -ENODEV;
if (!devm_request_mem_region(&pdev->dev, res_mem->start,
@@ -96,36 +168,35 @@ static int sp_probe(struct platform_device *pdev)
if (!addr)
return -ENOMEM;
+ if (of)
+ irq = irq_of_parse_and_map(of, 0);
+ else
+ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+ if (!irq && !res_irq)
+ return -ENODEV;
+
dev = alloc_sja1000dev(0);
if (!dev)
return -ENOMEM;
priv = netdev_priv(dev);
- dev->irq = res_irq->start;
- priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK;
- if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE)
- priv->irq_flags |= IRQF_SHARED;
+ if (res_irq) {
+ irq = res_irq->start;
+ priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK;
+ if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE)
+ priv->irq_flags |= IRQF_SHARED;
+ } else {
+ priv->irq_flags = IRQF_SHARED;
+ }
+
+ dev->irq = irq;
priv->reg_base = addr;
- /* The CAN clock frequency is half the oscillator clock frequency */
- priv->can.clock.freq = pdata->osc_freq / 2;
- priv->ocr = pdata->ocr;
- priv->cdr = pdata->cdr;
- switch (res_mem->flags & IORESOURCE_MEM_TYPE_MASK) {
- case IORESOURCE_MEM_32BIT:
- priv->read_reg = sp_read_reg32;
- priv->write_reg = sp_write_reg32;
- break;
- case IORESOURCE_MEM_16BIT:
- priv->read_reg = sp_read_reg16;
- priv->write_reg = sp_write_reg16;
- break;
- case IORESOURCE_MEM_8BIT:
- default:
- priv->read_reg = sp_read_reg8;
- priv->write_reg = sp_write_reg8;
- break;
- }
+ if (of)
+ sp_populate_of(priv, of);
+ else
+ sp_populate(priv, pdata, res_mem->flags);
platform_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -156,12 +227,19 @@ static int sp_remove(struct platform_device *pdev)
return 0;
}
+static struct of_device_id sp_of_table[] = {
+ {.compatible = "nxp,sja1000"},
+ {},
+};
+MODULE_DEVICE_TABLE(of, sp_of_table);
+
static struct platform_driver sp_driver = {
.probe = sp_probe,
.remove = sp_remove,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+ .of_match_table = sp_of_table,
},
};
--
1.8.1.2
^ permalink raw reply related
* [PATCH v3 4/5] Documentation: devicetree: sja1000: add reg-io-width binding
From: Florian Vaussard @ 2014-01-31 13:34 UTC (permalink / raw)
To: Wolfgang Grandegger, Marc Kleine-Budde
Cc: Andreas Larsson, linux-can, netdev, sparclinux, linux-kernel,
florian.vaussard, Grant Likely, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, devicetree
In-Reply-To: <1391175277-19833-1-git-send-email-florian.vaussard@epfl.ch>
Add the reg-io-width property to describe the width of the memory
accesses.
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: devicetree@vger.kernel.org
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
---
Documentation/devicetree/bindings/net/can/sja1000.txt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/can/sja1000.txt b/Documentation/devicetree/bindings/net/can/sja1000.txt
index f2105a4..b4a6d53 100644
--- a/Documentation/devicetree/bindings/net/can/sja1000.txt
+++ b/Documentation/devicetree/bindings/net/can/sja1000.txt
@@ -12,6 +12,10 @@ Required properties:
Optional properties:
+- reg-io-width : Specify the size (in bytes) of the IO accesses that
+ should be performed on the device. Valid value is 1, 2 or 4.
+ Default to 1 (8 bits).
+
- nxp,external-clock-frequency : Frequency of the external oscillator
clock in Hz. Note that the internal clock frequency used by the
SJA1000 is half of that value. If not specified, a default value
--
1.8.1.2
^ permalink raw reply related
* [PATCH v3 5/5] can: sja1000: of: add reg-io-width property for 8, 16 and 32-bit register access
From: Florian Vaussard @ 2014-01-31 13:34 UTC (permalink / raw)
To: Wolfgang Grandegger, Marc Kleine-Budde
Cc: Andreas Larsson, linux-can, netdev, sparclinux, linux-kernel,
florian.vaussard
In-Reply-To: <1391175277-19833-1-git-send-email-florian.vaussard@epfl.ch>
Add the 'reg-io-width' property for 8, 16 and 32-bit access, like
what is currently done with IORESOURCE_MEM_{8,16,32}BIT for non-OF
boot.
Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
---
drivers/net/can/sja1000/sja1000_platform.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c
index 50dece8..25122bf 100644
--- a/drivers/net/can/sja1000/sja1000_platform.c
+++ b/drivers/net/can/sja1000/sja1000_platform.c
@@ -102,8 +102,20 @@ static void sp_populate_of(struct sja1000_priv *priv, struct device_node *of)
int err;
u32 prop;
- priv->read_reg = sp_read_reg8;
- priv->write_reg = sp_write_reg8;
+ err = of_property_read_u32(of, "reg-io-width", &prop);
+ if (err)
+ prop = 1;
+
+ if (prop == 4) {
+ priv->read_reg = sp_read_reg32;
+ priv->write_reg = sp_write_reg32;
+ } else if (prop == 2) {
+ priv->read_reg = sp_read_reg16;
+ priv->write_reg = sp_write_reg16;
+ } else {
+ priv->read_reg = sp_read_reg8;
+ priv->write_reg = sp_write_reg8;
+ }
err = of_property_read_u32(of, "nxp,external-clock-frequency", &prop);
if (!err)
--
1.8.1.2
^ permalink raw reply related
* Re: [RFC PATCH] net: wireless: move regulatory timeout work to power efficient workqueue
From: Johannes Berg @ 2014-01-31 13:38 UTC (permalink / raw)
To: Zoran Markovic
Cc: linux-kernel, linux-wireless, netdev, Shaibal Dutta,
John W. Linville, David S. Miller
In-Reply-To: <1391123310-6425-1-git-send-email-zoran.markovic@linaro.org>
On Thu, 2014-01-30 at 15:08 -0800, Zoran Markovic wrote:
> From: Shaibal Dutta <shaibal.dutta@broadcom.com>
>
> For better use of CPU idle time, allow the scheduler to select the CPU
> on which the timeout work of regulatory settings would be executed.
> This extends CPU idle residency time and saves power.
>
> This functionality is enabled when CONFIG_WQ_POWER_EFFICIENT is selected.
Applied.
johannes
^ permalink raw reply
* Re: [RFC PATCH] net: rfkill: move poll work to power efficient workqueue
From: Johannes Berg @ 2014-01-31 13:39 UTC (permalink / raw)
To: Zoran Markovic
Cc: linux-kernel, linux-wireless, netdev, Shaibal Dutta,
John W. Linville, David S. Miller
In-Reply-To: <1391121814-6026-1-git-send-email-zoran.markovic@linaro.org>
On Thu, 2014-01-30 at 14:43 -0800, Zoran Markovic wrote:
> From: Shaibal Dutta <shaibal.dutta@broadcom.com>
>
> This patch moves the rfkill poll_work to the power efficient workqueue.
> This work does not have to be bound to the CPU that scheduled it, hence
> the selection of CPU that executes it would be left to the scheduler.
> Net result is that CPU idle times would be extended, resulting in power
> savings.
>
> This behaviour is enabled when CONFIG_WQ_POWER_EFFICIENT is selected.
Applied.
johannes
^ permalink raw reply
* Re: [PATCH v3 0/5] can: sja1000: cleanups and new OF property
From: Marc Kleine-Budde @ 2014-01-31 13:40 UTC (permalink / raw)
To: Florian Vaussard, Wolfgang Grandegger
Cc: Andreas Larsson, linux-can, netdev, sparclinux, linux-kernel
In-Reply-To: <1391175277-19833-1-git-send-email-florian.vaussard@epfl.ch>
[-- Attachment #1: Type: text/plain, Size: 1610 bytes --]
On 01/31/2014 02:34 PM, Florian Vaussard wrote:
> Hello,
>
> (could someone with a SJA1000 on SPARC perform a functional test
> to see if interrupts are working? it would be great :-)
>
> Changes since v2:
> - Dropped patch 1 "can: sja1000: remove unused defines"
> - Addressed Marc's comments on patch 4 and 6 (now 3 and 5)
>
> Changes since v1:
> - Merge sja1000_of_platform.c into sja1000_platform.c (patch 4)
>
> The first part of this series performs serveral small cleanups
> (patches 1 and 2).
>
> Patch 3 merges sja1000_of_platform.c into sja1000_platform.c.
> Changes are pretty conservatives (mostly copy/paste/move). IRQ
> is treated differently in the OF and non-OF versions, thus this
> is where the fused version differs the most.
>
> The final part introduces the 'reg-io-width' binding (already used
> by some other drivers) to perform a similar job as what was done
> with IORESOURCE_MEM_XXBIT. This is needed on my system to correctly
> take into account the aliasing of the address bus.
>
> All patches were tested using OF boot on my OMAP3 system with a
> memory-mapped SJA1000. Thus, the non-OF path is not tested, as
> I do not have a platform data at hand.
Nice, looks good now. I'll give Andreas some time to test on sparc and
then apply the patches.
regards,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 242 bytes --]
^ permalink raw reply
* Re: [PATCH v3 0/5] can: sja1000: cleanups and new OF property
From: Andreas Larsson @ 2014-01-31 13:50 UTC (permalink / raw)
To: Marc Kleine-Budde, Florian Vaussard, Wolfgang Grandegger
Cc: linux-can, netdev, sparclinux, linux-kernel
In-Reply-To: <52EBA7E2.6090007@pengutronix.de>
On 2014-01-31 14:40, Marc Kleine-Budde wrote:
> On 01/31/2014 02:34 PM, Florian Vaussard wrote:
>> Hello,
>>
>> (could someone with a SJA1000 on SPARC perform a functional test
>> to see if interrupts are working? it would be great :-)
>>
>> Changes since v2:
>> - Dropped patch 1 "can: sja1000: remove unused defines"
>> - Addressed Marc's comments on patch 4 and 6 (now 3 and 5)
>>
>> Changes since v1:
>> - Merge sja1000_of_platform.c into sja1000_platform.c (patch 4)
>>
>> The first part of this series performs serveral small cleanups
>> (patches 1 and 2).
>>
>> Patch 3 merges sja1000_of_platform.c into sja1000_platform.c.
>> Changes are pretty conservatives (mostly copy/paste/move). IRQ
>> is treated differently in the OF and non-OF versions, thus this
>> is where the fused version differs the most.
>>
>> The final part introduces the 'reg-io-width' binding (already used
>> by some other drivers) to perform a similar job as what was done
>> with IORESOURCE_MEM_XXBIT. This is needed on my system to correctly
>> take into account the aliasing of the address bus.
>>
>> All patches were tested using OF boot on my OMAP3 system with a
>> memory-mapped SJA1000. Thus, the non-OF path is not tested, as
>> I do not have a platform data at hand.
>
> Nice, looks good now. I'll give Andreas some time to test on sparc and
> then apply the patches.
I am on it. I will dig up some hardware for this on Monday to test it.
Best regards,
Andreas
^ permalink raw reply
* Re: [PATCH v3 0/5] can: sja1000: cleanups and new OF property
From: Marc Kleine-Budde @ 2014-01-31 13:51 UTC (permalink / raw)
To: Andreas Larsson, Florian Vaussard, Wolfgang Grandegger
Cc: linux-can, netdev, sparclinux, linux-kernel
In-Reply-To: <52EBAA28.1070307@gaisler.com>
[-- Attachment #1: Type: text/plain, Size: 1838 bytes --]
On 01/31/2014 02:50 PM, Andreas Larsson wrote:
> On 2014-01-31 14:40, Marc Kleine-Budde wrote:
>> On 01/31/2014 02:34 PM, Florian Vaussard wrote:
>>> Hello,
>>>
>>> (could someone with a SJA1000 on SPARC perform a functional test
>>> to see if interrupts are working? it would be great :-)
>>>
>>> Changes since v2:
>>> - Dropped patch 1 "can: sja1000: remove unused defines"
>>> - Addressed Marc's comments on patch 4 and 6 (now 3 and 5)
>>>
>>> Changes since v1:
>>> - Merge sja1000_of_platform.c into sja1000_platform.c (patch 4)
>>>
>>> The first part of this series performs serveral small cleanups
>>> (patches 1 and 2).
>>>
>>> Patch 3 merges sja1000_of_platform.c into sja1000_platform.c.
>>> Changes are pretty conservatives (mostly copy/paste/move). IRQ
>>> is treated differently in the OF and non-OF versions, thus this
>>> is where the fused version differs the most.
>>>
>>> The final part introduces the 'reg-io-width' binding (already used
>>> by some other drivers) to perform a similar job as what was done
>>> with IORESOURCE_MEM_XXBIT. This is needed on my system to correctly
>>> take into account the aliasing of the address bus.
>>>
>>> All patches were tested using OF boot on my OMAP3 system with a
>>> memory-mapped SJA1000. Thus, the non-OF path is not tested, as
>>> I do not have a platform data at hand.
>>
>> Nice, looks good now. I'll give Andreas some time to test on sparc and
>> then apply the patches.
>
>
> I am on it. I will dig up some hardware for this on Monday to test it.
\o/
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 242 bytes --]
^ permalink raw reply
* RE: [PATCH RFC 1/1] usb: Tell xhci when usb data might be misaligned
From: David Laight @ 2014-01-31 13:52 UTC (permalink / raw)
To: 'Peter Stuge'
Cc: 'Sarah Sharp', linux-usb@vger.kernel.org,
netdev@vger.kernel.org, Greg Kroah-Hartman, David Miller,
Dan Williams, Nyman, Mathias, Mark Lord, Alan Stern, Freddy Xin
In-Reply-To: <20140131132146.2833.qmail@stuge.se>
From: Peter Stuge [mailto:peter@stuge.se]
> > Userspace doesn't care since everything gets copied into aligned
> > kernel fragments - otherwise the other usb controllers wouldn't work.
>
> OK, but not so great if someone wants to squeeze the most performance
> possible out of USB also from userspace.
>
> I'm going off on a tangent now but would it make sense to allow
> userspace to do alignment if it wants to, and have a way to tell
> the kernel when urb buffers are pre-aligned?
I can only see that mattering if either:
1) The userspace buffers are (say) 4n+1 aligned and the kernel
decides to align the copy_from_user().
2) The code is doing buffer-loaning.
Personally I'm not at all sure how often buffer-loaning helps
(given the cost of the TLB shootdowns that it often implies).
I guess it might be ok if the memory doesn't have to be given
a KVA and the user program avoids any COW.
In any case and such code could be limited to page-aligned transfers.
And/or the user code would have to know at least some of the constraints.
The other usb controllers only support 'message' aligned transfers
(512 bytes for USB2). All the code I've found achieves this by using
page aligned (maybe 4k aligned) fragments. xhci trivially supports this
(it has since the 'ring expansion' code was added).
xhci can also easily support:
1) Arbitrary fragmentation for a limited number of fragments
(by constraining the fragments to a single ring segment).
2) Arbitrary fragmentation provided all the fragments (except the
last) exceed some minimal length (by splitting the current or
previous fragment at the appropriate boundary).
The code for the second is probably worth adding just in case
a 4k fragment crosses a 64k boundary.
Since arbitrarily fragmented packets can't be sent to other controllers
it does seem sensible for the code generating the urb so say that
it is (or might be) fragmented like that.
David
^ permalink raw reply
* Re: [PATCH v3 5/5] can: sja1000: of: add reg-io-width property for 8, 16 and 32-bit register access
From: Sergei Shtylyov @ 2014-01-31 14:08 UTC (permalink / raw)
To: Florian Vaussard, Wolfgang Grandegger, Marc Kleine-Budde
Cc: Andreas Larsson, linux-can, netdev, sparclinux, linux-kernel
In-Reply-To: <1391175277-19833-6-git-send-email-florian.vaussard@epfl.ch>
Hello.
On 31-01-2014 17:34, Florian Vaussard wrote:
> Add the 'reg-io-width' property for 8, 16 and 32-bit access, like
> what is currently done with IORESOURCE_MEM_{8,16,32}BIT for non-OF
> boot.
> Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
> ---
> drivers/net/can/sja1000/sja1000_platform.c | 16 ++++++++++++++--
> 1 file changed, 14 insertions(+), 2 deletions(-)
> diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c
> index 50dece8..25122bf 100644
> --- a/drivers/net/can/sja1000/sja1000_platform.c
> +++ b/drivers/net/can/sja1000/sja1000_platform.c
> @@ -102,8 +102,20 @@ static void sp_populate_of(struct sja1000_priv *priv, struct device_node *of)
> int err;
> u32 prop;
>
> - priv->read_reg = sp_read_reg8;
> - priv->write_reg = sp_write_reg8;
> + err = of_property_read_u32(of, "reg-io-width", &prop);
> + if (err)
> + prop = 1;
> +
> + if (prop == 4) {
This is asking to be a *switch* statement instead.
> + priv->read_reg = sp_read_reg32;
> + priv->write_reg = sp_write_reg32;
> + } else if (prop == 2) {
> + priv->read_reg = sp_read_reg16;
> + priv->write_reg = sp_write_reg16;
> + } else {
> + priv->read_reg = sp_read_reg8;
> + priv->write_reg = sp_write_reg8;
> + }
WBR, Sergei
^ permalink raw reply
* Re: [PATCH v3 0/5] can: sja1000: cleanups and new OF property
From: Florian Vaussard @ 2014-01-31 14:08 UTC (permalink / raw)
To: Andreas Larsson, Marc Kleine-Budde, Wolfgang Grandegger
Cc: linux-can, netdev, sparclinux, linux-kernel
In-Reply-To: <52EBAA28.1070307@gaisler.com>
On 01/31/2014 02:50 PM, Andreas Larsson wrote:
> On 2014-01-31 14:40, Marc Kleine-Budde wrote:
>> On 01/31/2014 02:34 PM, Florian Vaussard wrote:
>>> Hello,
>>>
>>> (could someone with a SJA1000 on SPARC perform a functional test
>>> to see if interrupts are working? it would be great :-)
>>>
>>> Changes since v2:
>>> - Dropped patch 1 "can: sja1000: remove unused defines"
>>> - Addressed Marc's comments on patch 4 and 6 (now 3 and 5)
>>>
>>> Changes since v1:
>>> - Merge sja1000_of_platform.c into sja1000_platform.c (patch 4)
>>>
>>> The first part of this series performs serveral small cleanups
>>> (patches 1 and 2).
>>>
>>> Patch 3 merges sja1000_of_platform.c into sja1000_platform.c.
>>> Changes are pretty conservatives (mostly copy/paste/move). IRQ
>>> is treated differently in the OF and non-OF versions, thus this
>>> is where the fused version differs the most.
>>>
>>> The final part introduces the 'reg-io-width' binding (already used
>>> by some other drivers) to perform a similar job as what was done
>>> with IORESOURCE_MEM_XXBIT. This is needed on my system to correctly
>>> take into account the aliasing of the address bus.
>>>
>>> All patches were tested using OF boot on my OMAP3 system with a
>>> memory-mapped SJA1000. Thus, the non-OF path is not tested, as
>>> I do not have a platform data at hand.
>>
>> Nice, looks good now. I'll give Andreas some time to test on sparc and
>> then apply the patches.
>
>
> I am on it. I will dig up some hardware for this on Monday to test it.
>
Many thanks :o)
(be careful to enable CAN_SJA1000_PLATFORM, as I removed
CAN_SJA1000_PLATFORM_OF)
Regards,
Florian
^ permalink raw reply
* Re: [PATCH 3/3] net: via-rhine: add OF bus binding
From: Ben Hutchings @ 2014-01-31 14:24 UTC (permalink / raw)
To: Alexey Charkov
Cc: netdev, Tony Prisk,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Roger Luethi,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <CABjd4Yx5HtbGjo_ZsOJ5SvqFQZey1fv5K36PD=D9fUUn0SanVQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 2176 bytes --]
On Tue, 2014-01-28 at 22:31 +0400, Alexey Charkov wrote:
> 2014/1/28 Ben Hutchings <ben-/+tVBieCtBitmTQ+vhA3Yw@public.gmane.org>:
> > On Mon, 2014-01-27 at 19:34 +0400, Alexey Charkov wrote:
> >> 2014/1/27 Ben Hutchings <ben-/+tVBieCtBitmTQ+vhA3Yw@public.gmane.org>:
> >> > On Mon, 2014-01-27 at 15:51 +0400, Alexey Charkov wrote:
> >> >> This should make the driver usable with VIA/WonderMedia ARM-based
> >> >> Systems-on-Chip integrated Rhine III adapters. Note that these
> >> >> are always in MMIO mode, and don't have any known EEPROM.
> >> > [...]
> >> >> --- a/drivers/net/ethernet/via/Kconfig
> >> >> +++ b/drivers/net/ethernet/via/Kconfig
> >> >> @@ -19,7 +19,7 @@ if NET_VENDOR_VIA
> >> >>
> >> >> config VIA_RHINE
> >> >> tristate "VIA Rhine support"
> >> >> - depends on PCI
> >> >> + depends on (PCI || USE_OF)
> >> >> select CRC32
> >> >> select MII
> >> >> ---help---
> >> >
> >> > This seems like the right thing to do, but it means you need to add
> >> > #ifdef CONFIG_PCI and #ifdef CONFIG_USE_OF around the driver structures
> >> > and related functions.
> >>
> >> Frankly, I would like to avoid that if possible (as pointed out in the
> >> cover email), as I believe we would get a cleaner driver without
> >> #ifdef. This is also the way it was done in via-velocity, and it works
> >> just fine.
> >
> > OK, I'm surprised that all the PCI functions have dummy definitions.
> >
> >> > You should compile-test in configurations that have just one of those
> >> > dependencies enabled.
> >>
> >> This has been compile-tested and runtime-tested in OF-only
> >> configuration on WM8950, and Roger also tested it in PCI-only
> >> configuration, so it seems to work fine.
> > [...]
> >
> > Good, then I have no objection.
>
> Thanks Ben! Would it be fine to add your Reviewed-by at the next
> iteration, once I fix indentation of function arguments and
> dev_is_pci()?
Sorry, I don't think I know enough to claim that I've reviewed the whole
thing properly.
Ben.
--
Ben Hutchings
It is easier to write an incorrect program than to understand a correct one.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* Re: [BUG] at include/linux/page-flags.h:415 (PageTransHuge)
From: Vlastimil Babka @ 2014-01-31 14:40 UTC (permalink / raw)
To: Daniel Borkmann
Cc: Andrew Morton, linux-kernel, Michel Lespinasse, linux-mm,
Jared Hulbert, netdev, Thomas Hellstrom, John David Anglin,
HATAYAMA Daisuke, Konstantin Khlebnikov, Carsten Otte,
Peter Zijlstra
In-Reply-To: <52D6B213.4020602@iogearbox.net>
On 01/15/2014 05:06 PM, Daniel Borkmann wrote:
> [keeping netdev in loop as well]
>
> On 01/15/2014 03:27 PM, Vlastimil Babka wrote:
>> On 01/13/2014 12:39 PM, Daniel Borkmann wrote:
>>> On 01/13/2014 11:16 AM, Vlastimil Babka wrote:
>>>> On 01/11/2014 02:32 PM, Daniel Borkmann wrote:
>>>>> On 01/11/2014 07:22 AM, Andrew Morton wrote:
>>>>>> On Fri, 10 Jan 2014 19:23:26 +0100 Daniel Borkmann <borkmann@iogearbox.net> wrote:
>>>>>>
>>>>>>> This is being reliably triggered for each mmaped() packet(7)
>>>>>>> socket from user space, basically during unmapping resp.
>>>>>>> closing the TX socket.
>>>>>>>
>>>>>>> I believe due to some change in transparent hugepages code ?
>>>>>>>
>>>>>>> When I disable transparent hugepages, everything works fine,
>>>>>>> no BUG triggered.
>>>>>>>
>>>>>>> I'd be happy to test patches.
>>>>>>
>>>>>> Did the inclusion of c424be1cbbf852e46acc8 ("mm: munlock: fix a bug
>>>>>> where THP tail page is encountered") in current mainline fix this?
>>>>>
>>>>> Thanks for your answer Andrew!
>>>>>
>>>>> Hm, I just cherry-picked that onto current net-next as I have some work
>>>>> there, and this time I got ...
>>>>>
>>>>> (User space uses packet mmap() and mlockall(MCL_CURRENT | MCL_FUTURE)
>>>>> and on shutdown munlockall() ...)
>>>>>
>>>>> [ 63.863672] ------------[ cut here ]------------
>>>>> [ 63.863702] kernel BUG at mm/mlock.c:507!
>>>>> [ 63.863721] invalid opcode: 0000 [#1] SMP
>>>>> [ 63.863743] Modules linked in: fuse ebtable_nat xt_CHECKSUM nf_conntrack_netbios_ns nf_conntrack_broadcast ipt_MASQUERADE ip6table_nat nf_nat_ipv6 ip6table_mangle ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 iptable_nat nf_nat_ipv4 nf_nat iptable_mangle nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack bridge ebtable_filter ebtables stp llc ip6table_filter ip6_tables rfcomm bnep snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_intel snd_hda_codec iwlwifi cfg80211 snd_hwdep btusb snd_seq bluetooth sdhci_pci snd_seq_device e1000e tpm_tis snd_pcm thinkpad_acpi sdhci ptp tpm uvcvideo pps_core snd_page_alloc snd_timer snd rfkill mmc_core iTCO_wdt iTCO_vendor_support lpc_ich mfd_core soundcore joydev wmi videobuf2_vmalloc videobuf2_memops videobuf2_core i2c_i801 pcspkr videodev
media uinput i915
>>>>> [ 63.864152] i2c_algo_bit drm_kms_helper drm i2c_core video
>>>>> [ 63.864181] CPU: 1 PID: 1617 Comm: trafgen Not tainted 3.13.0-rc6+ #15
>>>>> [ 63.864209] Hardware name: LENOVO 2429BP3/2429BP3, BIOS G4ET37WW (1.12 ) 05/29/2012
>>>>> [ 63.864242] task: ffff8801ee060000 ti: ffff8800b5954000 task.ti: ffff8800b5954000
>>>>> [ 63.864274] RIP: 0010:[<ffffffff8116fa9a>] [<ffffffff8116fa9a>] munlock_vma_pages_range+0x2ea/0x2f0
>>>>> [ 63.864318] RSP: 0018:ffff8800b5955e08 EFLAGS: 00010202
>>>>> [ 63.864341] RAX: 00000000000001ff RBX: ffff8800b58f7508 RCX: 0000000000000034
>>>>> [ 63.864372] RDX: 00000007f0708992 RSI: ffffea0002c3e700 RDI: ffffea0002c3e700
>>>>> [ 63.864402] RBP: ffff8800b5955ee0 R08: 3800000000000000 R09: a8000b0f9c000000
>>>>> [ 63.864432] R10: 57ffdef066c3e700 R11: ffffff5cfb00c14a R12: ffffea0002c3e700
>>>>> [ 63.864462] R13: ffff8800b5955f48 R14: 00007f0708992000 R15: 00007f0708992000
>>>>> [ 63.864492] FS: 00007f0708b92740(0000) GS:ffff88021e240000(0000) knlGS:0000000000000000
>>>>> [ 63.864526] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>> [ 63.864551] CR2: 00007f33bb373000 CR3: 00000000b2a2c000 CR4: 00000000001407e0
>>>>> [ 63.864581] Stack:
>>>>> [ 63.864593] ffff8800b5955ed0 00007f0708b91fff 00007f0708b92000 ffff8800b5955e48
>>>>> [ 63.864632] 000001ff810c864b ffff8801ee060000 0000000000000000 0000000000000000
>>>>> [ 63.864669] ffff8800b5955e58 ffff8801ee060000 0000000700000086 ffff8801ee060000
>>>>> [ 63.864708] Call Trace:
>>>>> [ 63.864724] [<ffffffff816956bc>] ? _raw_spin_unlock_irq+0x2c/0x30
>>>>> [ 63.864754] [<ffffffff81171b52>] ? vma_merge+0xc2/0x330
>>>>> [ 63.864786] [<ffffffff8116fb9c>] mlock_fixup+0xfc/0x190
>>>>> [ 63.864812] [<ffffffff8116fde7>] do_mlockall+0x87/0xc0
>>>>> [ 63.864836] [<ffffffff811702df>] sys_munlockall+0x2f/0x50
>>>>> [ 63.864873] [<ffffffff8169e192>] system_call_fastpath+0x16/0x1b
>>>>> [ 63.864898] Code: d7 48 89 95 28 ff ff ff e8 a4 04 fe ff 84 c0 48 8b 95 28 ff ff ff 0f 85 5a ff ff ff e9 46 ff ff ff e8 3f ac 51 00 e8 34 ac 51 00 <0f> 0b 0f 1f 40 00 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55
>>>>> [ 63.865114] RIP [<ffffffff8116fa9a>] munlock_vma_pages_range+0x2ea/0x2f0
>>>>> [ 63.865148] RSP <ffff8800b5955e08>
>>>>> [ 63.874968] ------------[ cut here ]------------
>>>>>
>>>>> ... when I find some time, I'll try with normal torvalds' tree, maybe some
>>>>> other patches are missing as well, not sure right now.
>>>>
>>>> Uh so the triggered assertion is the one added by this very patch, and there are no more changes wrt this in mainline.
>>>>
>>>> If you can still try debug patches, please try this. Thanks.
>>>
>>> Yes, thanks, I'll come back to you some time by today.
>>
>> Daniel sent me (off-list) instructions to reproduce:
>>
>>> Then in the kernel source tree, you'll find:
>>>
>>> tools/testing/selftests/net/
>>>
>>> There, just do a 'make' and run ./psock_tpacket
>>
>> It reproduces deterministically in mainline since 3.12, i.e. my munlock
>> performance series. Based on the initial debug output, I've expanded the
>> debug patch below a bit:
>>
>>>> From: Vlastimil Babka <vbabka@suse.cz>
>>>> Date: Mon, 13 Jan 2014 11:13:53 +0100
>>>> Subject: [PATCH] debug munlock_vma_pages_range
>>>>
>>>> ---
>>>> mm/mlock.c | 22 ++++++++++++++++++++--
>>>> 1 file changed, 20 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/mm/mlock.c b/mm/mlock.c
>>>> index c59c420..7d0e29a 100644
>>>> --- a/mm/mlock.c
>>>> +++ b/mm/mlock.c
>>>> @@ -448,12 +448,14 @@ static unsigned long __munlock_pagevec_fill(struct pagevec *pvec,
>>>> void munlock_vma_pages_range(struct vm_area_struct *vma,
>>>> unsigned long start, unsigned long end)
>>>> {
>>>> + unsigned long orig_start = start;
>>>> + unsigned long page_increm = 0;
>>>> +
>>>> vma->vm_flags &= ~VM_LOCKED;
>>>>
>>>> while (start < end) {
>>>> struct page *page = NULL;
>>>> unsigned int page_mask;
>>>> - unsigned long page_increm;
>>>> struct pagevec pvec;
>>>> struct zone *zone;
>>>> int zoneid;
>>>> @@ -504,7 +506,23 @@ void munlock_vma_pages_range(struct vm_area_struct *vma,
>>>> }
>>>> }
>>>> /* It's a bug to munlock in the middle of a THP page */
>>>> - VM_BUG_ON((start >> PAGE_SHIFT) & page_mask);
>>>> + if ((start >> PAGE_SHIFT) & page_mask) {
>>>> + dump_page(page);
>>>> + printk("start=%lu pfn=%lu orig_start=%lu "
>>>> + "prev_page_increm=%lu page_mask=%u "
>>>> + "vm_start=%lu vm_end=%lu vm_flags=%lu\n",
>>>> + start, page_to_pfn(page), orig_start,
>>>> + page_increm, page_mask,
>>>> + vma->vm_start, vma->vm_end,
>>>> + vma->vm_flags);
>> + printk("vm_ops=%pF, open=%pF, fault=%pF, remap_pages=%pF\n", vma->vm_ops,
>> + vma->vm_ops->open, vma->vm_ops->fault, vma->vm_ops->remap_pages);
>> + if (PageCompound(page)) {
>> + printk("page is compound with order=%d\n", compound_order(page));
>> + }
>>>> + if (PageTail(page)) {
>>>> + struct page *first_page = page->first_page;
>>>> + printk("first_page pfn=%lu\n",
>>>> + page_to_pfn(first_page));
>>>> + dump_page(first_page);
>>>> + }
>>>> + VM_BUG_ON(true);
>>>> + }
>>>> page_increm = 1 + page_mask;
>>>> start += page_increm * PAGE_SIZE;
>>>> next:
>>>>
>>
>> And got output like this:
>>
>> page:ffffea0002474a40 count:5 mapcount:1 mapping: (null) index:0x0
>> page flags: 0x100000000004004(referenced|head)
>> start=140242647736320 pfn=682616 orig_start=140242647736320 prev_page_increm=0 page_mask=511 vm_start=140242647736320 vm_end=140242651930624 vm_flags=268435707
>> vm_ops=packet_mmap_ops+0x0/0xfffffffffffff8e0 [af_packet], open=packet_mm_open+0x0/0x30 [af_packet], fault= (null), remap_pages= (null)
>> page is compound with order=2
>>
>> Observations:
>> - address 140242647736320 is where the vma starts, and is not aligned to 512 pages
>> (so it cannot be a THP head which the munlock expects). Yet there is a head page
>> that triggers the PageTransHuge() and consequently hpage_nr_pages() in munlock_vma_page()
>> That's why page_mask is determined to be 511 and the code thinks it's in the
>> middle of a THP page.
>> - in fact, the page is a compound page with order=2
>> - the VM flags (except (may)read/write) are VM_SHARED and VM_MIXEDMAP
>> - the vma was mmapped by packet_mmap() (net/packet/af_packet.c) which uses
>> vm_insert_page(), which adds the VM_MIXEDMAP flag
>> - the buffers that are mapped were allocated by alloc_one_pg_vec_page()
>> where flags indeed include __GFP_COMP
>>
>> So clearly there is a way to have mlock/munlock operate on a vma that contains
>> compound pages and confuse the checks for PageTransHuge().
>>
>> The checks for THP in munlock came with commit ff6a6da60b89 ("mm: accelerate munlock()
>> treatment of THP pages"), i.e. since 3.9, but did not trigger a bug. It however
>> makes munlock_vma_pages_range() skip pages until the next 512-pages-aligned page,
>> when it encounters a head page. If the head page is of smaller order and is followed
>> by normal LRU pages (theoretically, I'm not sure if that's possible, or done anywhere),
>> they wouldn't get munlocked.
>>
>> My commit 7225522bb429 ("mm: munlock: batch non-THP page isolation and
>> munlock+putback using pagevec") (since 3.12) has added a new PageTransHuge() check
>> that can trigger on tail pages of the compound page here. Commit c424be1cbbf852e46acc8
>> ("mm: munlock: fix a bug where THP tail page is encountered") in current rc's removes
>> one class of bugs here, but still non-THP compound pages are not expected in mlock/munlock,
>> which leads to this assertion failing.
>>
>> The question is what is the correct fix, and I'm not that familiar with VM_MIXEDMAP
>> to decide.
>>
>> Option 1: mlocking VM_MIXEDMAP vma's has no sense. They should be treated like VM_PFNMAP
>> and added to VM_SPECIAL, which makes m(un)lock skip them completely.
>>
>> Option 2: if indeed VM_MIXEDMAP can contain PageLRU pages for which mlocking is useful,
>> VM_NO_THP should be checked in munlock before attempting PageTransHuge() and
>> friends. VM_NO_THP already contains VM_MIXEDMAP, so knowing that there can be
>> no THP means we don't try optimize for it and no unexpected head pages trip us.
>>
>> Thoughts?
OK, here's a RFC patch to hopefully help get us somewhere. I went for
Option1, as I didn't see anyone using VM_MIXEDMAP also for LRU pages,
and Option2 was ugly to implement and also seemed quite arbitrary. I'm
not sure if making VM_MIXEDMAP also non-mergeable this way is an issue
though.
Actually a nice third option would be that the vma in question would
include also another flag (other than VM_MIXEDMAP) that would declare it
can contain compound pages. But I didn't find any such rule documented,
perhaps VM_IO would be a candidate?
I added people that touched VM_MIXEDMAP in the past to CC.
-------8<-------
From: Vlastimil Babka <vbabka@suse.cz>
Date: Fri, 31 Jan 2014 11:50:21 +0100
Subject: [PATCH] mm: include VM_MIXEDMAP flag in the VM_SPECIAL list to avoid
m(un)locking
Daniel Borkmann reported a bug with VM_BUG_ON assertions failing where
munlock_vma_pages_range() thinks it's unexpectedly in the middle of a THP page.
This can be reproduced in tools/testing/selftests/net/ by running make and
then ./psock_tpacket.
The problem is that an order=2 compound page (allocated by
alloc_one_pg_vec_page() is part of the munlocked VM_MIXEDMAP vma (mapped by
packet_mmap()) and mistaken for a THP page and assumed to be order=9.
The checks for THP in munlock came with commit ff6a6da60b89 ("mm: accelerate
munlock() treatment of THP pages"), i.e. since 3.9, but did not trigger a bug.
It just makes munlock_vma_pages_range() skip such compound pages until the next
512-pages-aligned page, when it encounters a head page. This is however not a
problem for vma's where mlocking has no effect anyway, but it can distort the
accounting.
Since commit 7225522bb ("mm: munlock: batch non-THP page isolation and
munlock+putback using pagevec") this can trigger a VM_BUG_ON in PageTransHuge()
check.
This patch fixes the issue by adding VM_MIXEDMAP flag to VM_SPECIAL - a list of
flags that make vma's non-mlockable and non-mergeable. The reasoning is that
VM_MIXEDMAP vma's are similar to VM_PFNMAP, which is already on the VM_SPECIAL
list, and both are intended for non-LRU pages where mlocking makes no sense
anyway.
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Reported-by: Daniel Borkmann <borkmann@iogearbox.net>
Cc: Thomas Hellstrom <thellstrom@vmware.com>
Cc: John David Anglin <dave.anglin@bell.net>
Cc: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
Cc: Konstantin Khlebnikov <khlebnikov@openvz.org>
Cc: Carsten Otte <cotte@de.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jared Hulbert <jaredeh@gmail.com>
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
---
include/linux/mm.h | 2 +-
mm/huge_memory.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index f28f46e..f9b04ac 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -175,7 +175,7 @@ extern unsigned int kobjsize(const void *objp);
* Special vmas that are non-mergable, non-mlock()able.
* Note: mm/huge_memory.c VM_NO_THP depends on this definition.
*/
-#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP)
+#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP)
/*
* mapping from the currently active vm_flags protection bits (the
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 82166bf..f32fffb 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1963,7 +1963,7 @@ out:
return ret;
}
-#define VM_NO_THP (VM_SPECIAL|VM_MIXEDMAP|VM_HUGETLB|VM_SHARED|VM_MAYSHARE)
+#define VM_NO_THP (VM_SPECIAL|VM_HUGETLB|VM_SHARED|VM_MAYSHARE)
int hugepage_madvise(struct vm_area_struct *vma,
unsigned long *vm_flags, int advice)
--
1.8.4.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* Re: [BUG] at include/linux/page-flags.h:415 (PageTransHuge)
From: Thomas Hellstrom @ 2014-01-31 14:58 UTC (permalink / raw)
To: Vlastimil Babka
Cc: Daniel Borkmann, Andrew Morton, linux-kernel, Michel Lespinasse,
linux-mm, Jared Hulbert, netdev, John David Anglin,
HATAYAMA Daisuke, Konstantin Khlebnikov, Carsten Otte,
Peter Zijlstra
In-Reply-To: <52EBB5E6.8010007@suse.cz>
On 01/31/2014 03:40 PM, Vlastimil Babka wrote:
> On 01/15/2014 05:06 PM, Daniel Borkmann wrote:
>> [keeping netdev in loop as well]
>>
>> On 01/15/2014 03:27 PM, Vlastimil Babka wrote:
>>> On 01/13/2014 12:39 PM, Daniel Borkmann wrote:
>>>> On 01/13/2014 11:16 AM, Vlastimil Babka wrote:
>>>>> On 01/11/2014 02:32 PM, Daniel Borkmann wrote:
>>>>>> On 01/11/2014 07:22 AM, Andrew Morton wrote:
>>>>>>> On Fri, 10 Jan 2014 19:23:26 +0100 Daniel Borkmann <borkmann@iogearbox.net> wrote:
>>>>>>>
>>>>>>>> This is being reliably triggered for each mmaped() packet(7)
>>>>>>>> socket from user space, basically during unmapping resp.
>>>>>>>> closing the TX socket.
>>>>>>>>
>>>>>>>> I believe due to some change in transparent hugepages code ?
>>>>>>>>
>>>>>>>> When I disable transparent hugepages, everything works fine,
>>>>>>>> no BUG triggered.
>>>>>>>>
>>>>>>>> I'd be happy to test patches.
>>>>>>> Did the inclusion of c424be1cbbf852e46acc8 ("mm: munlock: fix a bug
>>>>>>> where THP tail page is encountered") in current mainline fix this?
>>>>>> Thanks for your answer Andrew!
>>>>>>
>>>>>> Hm, I just cherry-picked that onto current net-next as I have some work
>>>>>> there, and this time I got ...
>>>>>>
>>>>>> (User space uses packet mmap() and mlockall(MCL_CURRENT | MCL_FUTURE)
>>>>>> and on shutdown munlockall() ...)
>>>>>>
>>>>>> [ 63.863672] ------------[ cut here ]------------
>>>>>> [ 63.863702] kernel BUG at mm/mlock.c:507!
>>>>>> [ 63.863721] invalid opcode: 0000 [#1] SMP
>>>>>> [ 63.863743] Modules linked in: fuse ebtable_nat xt_CHECKSUM nf_conntrack_netbios_ns nf_conntrack_broadcast ipt_MASQUERADE ip6table_nat nf_nat_ipv6 ip6table_mangle ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 iptable_nat nf_nat_ipv4 nf_nat iptable_mangle nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack bridge ebtable_filter ebtables stp llc ip6table_filter ip6_tables rfcomm bnep snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_intel snd_hda_codec iwlwifi cfg80211 snd_hwdep btusb snd_seq bluetooth sdhci_pci snd_seq_device e1000e tpm_tis snd_pcm thinkpad_acpi sdhci ptp tpm uvcvideo pps_core snd_page_alloc snd_timer snd rfkill mmc_core iTCO_wdt iTCO_vendor_support lpc_ich mfd_core soundcore joydev wmi videobuf2_vmalloc videobuf2_memops videobuf2_core i2c_i801 pcspkr videode
v media uinput i915
>>>>>> [ 63.864152] i2c_algo_bit drm_kms_helper drm i2c_core video
>>>>>> [ 63.864181] CPU: 1 PID: 1617 Comm: trafgen Not tainted 3.13.0-rc6+ #15
>>>>>> [ 63.864209] Hardware name: LENOVO 2429BP3/2429BP3, BIOS G4ET37WW (1.12 ) 05/29/2012
>>>>>> [ 63.864242] task: ffff8801ee060000 ti: ffff8800b5954000 task.ti: ffff8800b5954000
>>>>>> [ 63.864274] RIP: 0010:[<ffffffff8116fa9a>] [<ffffffff8116fa9a>] munlock_vma_pages_range+0x2ea/0x2f0
>>>>>> [ 63.864318] RSP: 0018:ffff8800b5955e08 EFLAGS: 00010202
>>>>>> [ 63.864341] RAX: 00000000000001ff RBX: ffff8800b58f7508 RCX: 0000000000000034
>>>>>> [ 63.864372] RDX: 00000007f0708992 RSI: ffffea0002c3e700 RDI: ffffea0002c3e700
>>>>>> [ 63.864402] RBP: ffff8800b5955ee0 R08: 3800000000000000 R09: a8000b0f9c000000
>>>>>> [ 63.864432] R10: 57ffdef066c3e700 R11: ffffff5cfb00c14a R12: ffffea0002c3e700
>>>>>> [ 63.864462] R13: ffff8800b5955f48 R14: 00007f0708992000 R15: 00007f0708992000
>>>>>> [ 63.864492] FS: 00007f0708b92740(0000) GS:ffff88021e240000(0000) knlGS:0000000000000000
>>>>>> [ 63.864526] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>> [ 63.864551] CR2: 00007f33bb373000 CR3: 00000000b2a2c000 CR4: 00000000001407e0
>>>>>> [ 63.864581] Stack:
>>>>>> [ 63.864593] ffff8800b5955ed0 00007f0708b91fff 00007f0708b92000 ffff8800b5955e48
>>>>>> [ 63.864632] 000001ff810c864b ffff8801ee060000 0000000000000000 0000000000000000
>>>>>> [ 63.864669] ffff8800b5955e58 ffff8801ee060000 0000000700000086 ffff8801ee060000
>>>>>> [ 63.864708] Call Trace:
>>>>>> [ 63.864724] [<ffffffff816956bc>] ? _raw_spin_unlock_irq+0x2c/0x30
>>>>>> [ 63.864754] [<ffffffff81171b52>] ? vma_merge+0xc2/0x330
>>>>>> [ 63.864786] [<ffffffff8116fb9c>] mlock_fixup+0xfc/0x190
>>>>>> [ 63.864812] [<ffffffff8116fde7>] do_mlockall+0x87/0xc0
>>>>>> [ 63.864836] [<ffffffff811702df>] sys_munlockall+0x2f/0x50
>>>>>> [ 63.864873] [<ffffffff8169e192>] system_call_fastpath+0x16/0x1b
>>>>>> [ 63.864898] Code: d7 48 89 95 28 ff ff ff e8 a4 04 fe ff 84 c0 48 8b 95 28 ff ff ff 0f 85 5a ff ff ff e9 46 ff ff ff e8 3f ac 51 00 e8 34 ac 51 00 <0f> 0b 0f 1f 40 00 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55
>>>>>> [ 63.865114] RIP [<ffffffff8116fa9a>] munlock_vma_pages_range+0x2ea/0x2f0
>>>>>> [ 63.865148] RSP <ffff8800b5955e08>
>>>>>> [ 63.874968] ------------[ cut here ]------------
>>>>>>
>>>>>> ... when I find some time, I'll try with normal torvalds' tree, maybe some
>>>>>> other patches are missing as well, not sure right now.
>>>>> Uh so the triggered assertion is the one added by this very patch, and there are no more changes wrt this in mainline.
>>>>>
>>>>> If you can still try debug patches, please try this. Thanks.
>>>> Yes, thanks, I'll come back to you some time by today.
>>> Daniel sent me (off-list) instructions to reproduce:
>>>
>>>> Then in the kernel source tree, you'll find:
>>>>
>>>> tools/testing/selftests/net/
>>>>
>>>> There, just do a 'make' and run ./psock_tpacket
>>> It reproduces deterministically in mainline since 3.12, i.e. my munlock
>>> performance series. Based on the initial debug output, I've expanded the
>>> debug patch below a bit:
>>>
>>>>> From: Vlastimil Babka <vbabka@suse.cz>
>>>>> Date: Mon, 13 Jan 2014 11:13:53 +0100
>>>>> Subject: [PATCH] debug munlock_vma_pages_range
>>>>>
>>>>> ---
>>>>> mm/mlock.c | 22 ++++++++++++++++++++--
>>>>> 1 file changed, 20 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/mm/mlock.c b/mm/mlock.c
>>>>> index c59c420..7d0e29a 100644
>>>>> --- a/mm/mlock.c
>>>>> +++ b/mm/mlock.c
>>>>> @@ -448,12 +448,14 @@ static unsigned long __munlock_pagevec_fill(struct pagevec *pvec,
>>>>> void munlock_vma_pages_range(struct vm_area_struct *vma,
>>>>> unsigned long start, unsigned long end)
>>>>> {
>>>>> + unsigned long orig_start = start;
>>>>> + unsigned long page_increm = 0;
>>>>> +
>>>>> vma->vm_flags &= ~VM_LOCKED;
>>>>>
>>>>> while (start < end) {
>>>>> struct page *page = NULL;
>>>>> unsigned int page_mask;
>>>>> - unsigned long page_increm;
>>>>> struct pagevec pvec;
>>>>> struct zone *zone;
>>>>> int zoneid;
>>>>> @@ -504,7 +506,23 @@ void munlock_vma_pages_range(struct vm_area_struct *vma,
>>>>> }
>>>>> }
>>>>> /* It's a bug to munlock in the middle of a THP page */
>>>>> - VM_BUG_ON((start >> PAGE_SHIFT) & page_mask);
>>>>> + if ((start >> PAGE_SHIFT) & page_mask) {
>>>>> + dump_page(page);
>>>>> + printk("start=%lu pfn=%lu orig_start=%lu "
>>>>> + "prev_page_increm=%lu page_mask=%u "
>>>>> + "vm_start=%lu vm_end=%lu vm_flags=%lu\n",
>>>>> + start, page_to_pfn(page), orig_start,
>>>>> + page_increm, page_mask,
>>>>> + vma->vm_start, vma->vm_end,
>>>>> + vma->vm_flags);
>>> + printk("vm_ops=%pF, open=%pF, fault=%pF, remap_pages=%pF\n", vma->vm_ops,
>>> + vma->vm_ops->open, vma->vm_ops->fault, vma->vm_ops->remap_pages);
>>> + if (PageCompound(page)) {
>>> + printk("page is compound with order=%d\n", compound_order(page));
>>> + }
>>>>> + if (PageTail(page)) {
>>>>> + struct page *first_page = page->first_page;
>>>>> + printk("first_page pfn=%lu\n",
>>>>> + page_to_pfn(first_page));
>>>>> + dump_page(first_page);
>>>>> + }
>>>>> + VM_BUG_ON(true);
>>>>> + }
>>>>> page_increm = 1 + page_mask;
>>>>> start += page_increm * PAGE_SIZE;
>>>>> next:
>>>>>
>>> And got output like this:
>>>
>>> page:ffffea0002474a40 count:5 mapcount:1 mapping: (null) index:0x0
>>> page flags: 0x100000000004004(referenced|head)
>>> start=140242647736320 pfn=682616 orig_start=140242647736320 prev_page_increm=0 page_mask=511 vm_start=140242647736320 vm_end=140242651930624 vm_flags=268435707
>>> vm_ops=packet_mmap_ops+0x0/0xfffffffffffff8e0 [af_packet], open=packet_mm_open+0x0/0x30 [af_packet], fault= (null), remap_pages= (null)
>>> page is compound with order=2
>>>
>>> Observations:
>>> - address 140242647736320 is where the vma starts, and is not aligned to 512 pages
>>> (so it cannot be a THP head which the munlock expects). Yet there is a head page
>>> that triggers the PageTransHuge() and consequently hpage_nr_pages() in munlock_vma_page()
>>> That's why page_mask is determined to be 511 and the code thinks it's in the
>>> middle of a THP page.
>>> - in fact, the page is a compound page with order=2
>>> - the VM flags (except (may)read/write) are VM_SHARED and VM_MIXEDMAP
>>> - the vma was mmapped by packet_mmap() (net/packet/af_packet.c) which uses
>>> vm_insert_page(), which adds the VM_MIXEDMAP flag
>>> - the buffers that are mapped were allocated by alloc_one_pg_vec_page()
>>> where flags indeed include __GFP_COMP
>>>
>>> So clearly there is a way to have mlock/munlock operate on a vma that contains
>>> compound pages and confuse the checks for PageTransHuge().
>>>
>>> The checks for THP in munlock came with commit ff6a6da60b89 ("mm: accelerate munlock()
>>> treatment of THP pages"), i.e. since 3.9, but did not trigger a bug. It however
>>> makes munlock_vma_pages_range() skip pages until the next 512-pages-aligned page,
>>> when it encounters a head page. If the head page is of smaller order and is followed
>>> by normal LRU pages (theoretically, I'm not sure if that's possible, or done anywhere),
>>> they wouldn't get munlocked.
>>>
>>> My commit 7225522bb429 ("mm: munlock: batch non-THP page isolation and
>>> munlock+putback using pagevec") (since 3.12) has added a new PageTransHuge() check
>>> that can trigger on tail pages of the compound page here. Commit c424be1cbbf852e46acc8
>>> ("mm: munlock: fix a bug where THP tail page is encountered") in current rc's removes
>>> one class of bugs here, but still non-THP compound pages are not expected in mlock/munlock,
>>> which leads to this assertion failing.
>>>
>>> The question is what is the correct fix, and I'm not that familiar with VM_MIXEDMAP
>>> to decide.
>>>
>>> Option 1: mlocking VM_MIXEDMAP vma's has no sense. They should be treated like VM_PFNMAP
>>> and added to VM_SPECIAL, which makes m(un)lock skip them completely.
>>>
>>> Option 2: if indeed VM_MIXEDMAP can contain PageLRU pages for which mlocking is useful,
>>> VM_NO_THP should be checked in munlock before attempting PageTransHuge() and
>>> friends. VM_NO_THP already contains VM_MIXEDMAP, so knowing that there can be
>>> no THP means we don't try optimize for it and no unexpected head pages trip us.
>>>
>>> Thoughts?
> OK, here's a RFC patch to hopefully help get us somewhere. I went for
> Option1, as I didn't see anyone using VM_MIXEDMAP also for LRU pages,
> and Option2 was ugly to implement and also seemed quite arbitrary. I'm
> not sure if making VM_MIXEDMAP also non-mergeable this way is an issue
> though.
>
>
Hi!
Forgive an ignorant question, but are anonymous COW'd pages LRU pages?
The reason I'm asking is that TTM VM_MIXEDMAP vmas may contain such pages.
/Thomas
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Re: Re: IPv4 / IPv6 over IPv4 IPsec tunnel: setting the DF bit
From: Hannes Frederic Sowa @ 2014-01-31 15:01 UTC (permalink / raw)
To: Simon Schneider; +Cc: netdev
In-Reply-To: <trinity-ece5a90d-72c2-4db9-a1f7-8c9af2bbfa65-1391156847114@3capp-gmx-bs01>
On Fri, Jan 31, 2014 at 09:27:27AM +0100, Simon Schneider wrote:
> I think your IPv6 related statements are for a IPv6-over-IPv6 case.
>
> However, I'm especially after the IPv6-over-IPv4 case.
>
> In that case, you cannot copy the DF bit from the inner IPv6 packet.
>
> But you still have the option to set or not set the DF bit in the IPv4 outer packet.
>
> How is that decided?
Basically only pmtudisc setting is cruical then. So no DF-bit if nopmtudisc
and DF-bit if pmtudisc.
Greetings,
Hannes
^ permalink raw reply
* [PATCH 01/34] bnx2: Use pci_enable_msix_range()
From: Alexander Gordeev @ 2014-01-31 15:08 UTC (permalink / raw)
To: linux-kernel; +Cc: Alexander Gordeev, Michael Chan, netdev, linux-pci
In-Reply-To: <cover.1391172839.git.agordeev@redhat.com>
As result of deprecation of MSI-X/MSI enablement functions
pci_enable_msix() and pci_enable_msi_block() all drivers
using these two interfaces need to be updated to use the
new pci_enable_msi_range() and pci_enable_msix_range()
interfaces.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
---
drivers/net/ethernet/broadcom/bnx2.c | 15 ++++-----------
1 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 9d2deda..3df63b2 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -6206,7 +6206,7 @@ bnx2_free_irq(struct bnx2 *bp)
static void
bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
{
- int i, total_vecs, rc;
+ int i, total_vecs;
struct msix_entry msix_ent[BNX2_MAX_MSIX_VEC];
struct net_device *dev = bp->dev;
const int len = sizeof(bp->irq_tbl[0].name);
@@ -6229,16 +6229,9 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
#ifdef BCM_CNIC
total_vecs++;
#endif
- rc = -ENOSPC;
- while (total_vecs >= BNX2_MIN_MSIX_VEC) {
- rc = pci_enable_msix(bp->pdev, msix_ent, total_vecs);
- if (rc <= 0)
- break;
- if (rc > 0)
- total_vecs = rc;
- }
-
- if (rc != 0)
+ total_vecs = pci_enable_msix_range(bp->pdev, msix_ent,
+ BNX2_MIN_MSIX_VEC, total_vecs);
+ if (total_vecs < 0)
return;
msix_vecs = total_vecs;
--
1.7.7.6
^ permalink raw reply related
* [PATCH 24/34] forcedeth: Cleanup MSI-X to MSI to INTx fallback code
From: Alexander Gordeev @ 2014-01-31 15:08 UTC (permalink / raw)
To: linux-kernel
Cc: Alexander Gordeev, David S. Miller, Patrick McHardy, netdev,
linux-pci
In-Reply-To: <cover.1391172839.git.agordeev@redhat.com>
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index f4270b8..74da489 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -3930,7 +3930,7 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
{
struct fe_priv *np = get_nvpriv(dev);
u8 __iomem *base = get_hwbase(dev);
- int ret = 1;
+ int ret;
int i;
irqreturn_t (*handler)(int foo, void *data);
@@ -4010,9 +4010,10 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
writel(0, base + NvRegMSIXMap1);
}
netdev_info(dev, "MSI-X enabled\n");
+ return 0;
}
}
- if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
+ if (np->msi_flags & NV_MSI_CAPABLE) {
ret = pci_enable_msi(np->pci_dev);
if (ret == 0) {
np->msi_flags |= NV_MSI_ENABLED;
@@ -4031,13 +4032,12 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
/* enable msi vector 0 */
writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask);
netdev_info(dev, "MSI enabled\n");
+ return 0;
}
}
- if (ret != 0) {
- if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0)
- goto out_err;
- }
+ if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0)
+ goto out_err;
return 0;
out_free_tx:
--
1.7.7.6
^ permalink raw reply related
* [PATCH 02/34] bnx2x: Use pci_enable_msix_range()
From: Alexander Gordeev @ 2014-01-31 15:08 UTC (permalink / raw)
To: linux-kernel; +Cc: Alexander Gordeev, Ariel Elior, netdev, linux-pci
In-Reply-To: <cover.1391172839.git.agordeev@redhat.com>
As result of deprecation of MSI-X/MSI enablement functions
pci_enable_msix() and pci_enable_msi_block() all drivers
using these two interfaces need to be updated to use the
new pci_enable_msi_range() and pci_enable_msix_range()
interfaces.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 48 ++++++++++-------------
1 files changed, 21 insertions(+), 27 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 9d7419e..b396d74 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -1638,24 +1638,36 @@ int bnx2x_enable_msix(struct bnx2x *bp)
DP(BNX2X_MSG_SP, "about to request enable msix with %d vectors\n",
msix_vec);
- rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], msix_vec);
-
+ rc = pci_enable_msix_range(bp->pdev, &bp->msix_table[0],
+ BNX2X_MIN_MSIX_VEC_CNT(bp), msix_vec);
/*
* reconfigure number of tx/rx queues according to available
* MSI-X vectors
*/
- if (rc >= BNX2X_MIN_MSIX_VEC_CNT(bp)) {
+ if (rc < 0) {
+ BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc);
+ goto no_msix;
+ } else if (rc == -ENOSPC) {
+ /* Get by with single vector */
+ rc = pci_enable_msix_range(bp->pdev, &bp->msix_table[0], 1, 1);
+ if (rc < 0) {
+ BNX2X_DEV_INFO("Single MSI-X is not attainable rc %d\n",
+ rc);
+ goto no_msix;
+ }
+
+ BNX2X_DEV_INFO("Using single MSI-X vector\n");
+ bp->flags |= USING_SINGLE_MSIX_FLAG;
+
+ BNX2X_DEV_INFO("set number of queues to 1\n");
+ bp->num_ethernet_queues = 1;
+ bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues;
+ } else if (rc < msix_vec) {
/* how less vectors we will have? */
int diff = msix_vec - rc;
BNX2X_DEV_INFO("Trying to use less MSI-X vectors: %d\n", rc);
- rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], rc);
-
- if (rc) {
- BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc);
- goto no_msix;
- }
/*
* decrease number of queues by number of unallocated entries
*/
@@ -1664,24 +1676,6 @@ int bnx2x_enable_msix(struct bnx2x *bp)
BNX2X_DEV_INFO("New queue configuration set: %d\n",
bp->num_queues);
- } else if (rc > 0) {
- /* Get by with single vector */
- rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], 1);
- if (rc) {
- BNX2X_DEV_INFO("Single MSI-X is not attainable rc %d\n",
- rc);
- goto no_msix;
- }
-
- BNX2X_DEV_INFO("Using single MSI-X vector\n");
- bp->flags |= USING_SINGLE_MSIX_FLAG;
-
- BNX2X_DEV_INFO("set number of queues to 1\n");
- bp->num_ethernet_queues = 1;
- bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues;
- } else if (rc < 0) {
- BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc);
- goto no_msix;
}
bp->flags |= USING_MSIX_FLAG;
--
1.7.7.6
^ permalink raw reply related
* [PATCH 03/34] tg3: Use pci_enable_msix_range()
From: Alexander Gordeev @ 2014-01-31 15:08 UTC (permalink / raw)
To: linux-kernel
Cc: Alexander Gordeev, Nithin Nayak Sujir, Michael Chan, netdev,
linux-pci
In-Reply-To: <cover.1391172839.git.agordeev@redhat.com>
As result of deprecation of MSI-X/MSI enablement functions
pci_enable_msix() and pci_enable_msi_block() all drivers
using these two interfaces need to be updated to use the
new pci_enable_msi_range() and pci_enable_msix_range()
interfaces.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
---
drivers/net/ethernet/broadcom/tg3.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index e2ca03e..fca9996 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -11361,12 +11361,10 @@ static bool tg3_enable_msix(struct tg3 *tp)
msix_ent[i].vector = 0;
}
- rc = pci_enable_msix(tp->pdev, msix_ent, tp->irq_cnt);
+ rc = pci_enable_msix_range(tp->pdev, msix_ent, 1, tp->irq_cnt);
if (rc < 0) {
return false;
- } else if (rc != 0) {
- if (pci_enable_msix(tp->pdev, msix_ent, rc))
- return false;
+ } else if (rc < tp->irq_cnt) {
netdev_notice(tp->dev, "Requested %d MSI-X vectors, received %d\n",
tp->irq_cnt, rc);
tp->irq_cnt = rc;
--
1.7.7.6
^ permalink raw reply related
* [PATCH 04/34] bna: Use pci_enable_msix_range()
From: Alexander Gordeev @ 2014-01-31 15:08 UTC (permalink / raw)
To: linux-kernel; +Cc: Alexander Gordeev, Rasesh Mody, netdev, linux-pci
In-Reply-To: <cover.1391172839.git.agordeev@redhat.com>
As result of deprecation of MSI-X/MSI enablement functions
pci_enable_msix() and pci_enable_msi_block() all drivers
using these two interfaces need to be updated to use the
new pci_enable_msi_range() and pci_enable_msix_range()
interfaces.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
---
drivers/net/ethernet/brocade/bna/bnad.c | 23 +++++++++--------------
1 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index cf64f3d..bf436d0 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -2666,9 +2666,11 @@ bnad_enable_msix(struct bnad *bnad)
for (i = 0; i < bnad->msix_num; i++)
bnad->msix_table[i].entry = i;
- ret = pci_enable_msix(bnad->pcidev, bnad->msix_table, bnad->msix_num);
- if (ret > 0) {
- /* Not enough MSI-X vectors. */
+ ret = pci_enable_msix_range(bnad->pcidev, bnad->msix_table,
+ 1, bnad->msix_num);
+ if (ret < 0) {
+ goto intx_mode;
+ } else if (ret < bnad->msix_num) {
pr_warn("BNA: %d MSI-X vectors allocated < %d requested\n",
ret, bnad->msix_num);
@@ -2681,18 +2683,11 @@ bnad_enable_msix(struct bnad *bnad)
bnad->msix_num = BNAD_NUM_TXQ + BNAD_NUM_RXP +
BNAD_MAILBOX_MSIX_VECTORS;
- if (bnad->msix_num > ret)
- goto intx_mode;
-
- /* Try once more with adjusted numbers */
- /* If this fails, fall back to INTx */
- ret = pci_enable_msix(bnad->pcidev, bnad->msix_table,
- bnad->msix_num);
- if (ret)
+ if (bnad->msix_num > ret) {
+ pci_disable_msix(bnad->pcidev);
goto intx_mode;
-
- } else if (ret < 0)
- goto intx_mode;
+ }
+ }
pci_intx(bnad->pcidev, 0);
--
1.7.7.6
^ permalink raw reply related
* [PATCH 05/34] cxgb3: Remove superfluous call to pci_disable_msix()
From: Alexander Gordeev @ 2014-01-31 15:08 UTC (permalink / raw)
To: linux-kernel; +Cc: Alexander Gordeev, Santosh Raspatur, netdev, linux-pci
In-Reply-To: <cover.1391172839.git.agordeev@redhat.com>
There is no need to call pci_disable_msix() in case
the previous call to pci_enable_msix() failed
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
---
drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
index 45d7733..b72d2ed 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
@@ -3097,9 +3097,6 @@ static int cxgb_enable_msix(struct adapter *adap)
while ((err = pci_enable_msix(adap->pdev, entries, vectors)) > 0)
vectors = err;
- if (err < 0)
- pci_disable_msix(adap->pdev);
-
if (!err && vectors < (adap->params.nports + 1)) {
pci_disable_msix(adap->pdev);
err = -1;
--
1.7.7.6
^ permalink raw reply related
* [PATCH 06/34] cxgb3: Use pci_enable_msix_range()
From: Alexander Gordeev @ 2014-01-31 15:08 UTC (permalink / raw)
To: linux-kernel; +Cc: Alexander Gordeev, Santosh Raspatur, netdev, linux-pci
In-Reply-To: <cover.1391172839.git.agordeev@redhat.com>
As result of deprecation of MSI-X/MSI enablement functions
pci_enable_msix() and pci_enable_msi_block() all drivers
using these two interfaces need to be updated to use the
new pci_enable_msi_range() and pci_enable_msix_range()
interfaces.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
---
drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 23 +++++++++--------------
1 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
index b72d2ed..07bbb71 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
@@ -3088,27 +3088,22 @@ static int cxgb_enable_msix(struct adapter *adap)
{
struct msix_entry entries[SGE_QSETS + 1];
int vectors;
- int i, err;
+ int i;
vectors = ARRAY_SIZE(entries);
for (i = 0; i < vectors; ++i)
entries[i].entry = i;
- while ((err = pci_enable_msix(adap->pdev, entries, vectors)) > 0)
- vectors = err;
-
- if (!err && vectors < (adap->params.nports + 1)) {
- pci_disable_msix(adap->pdev);
- err = -1;
- }
+ vectors = pci_enable_msix_range(adap->pdev, entries,
+ adap->params.nports + 1, vectors);
+ if (vectors < 0)
+ return vectors;
- if (!err) {
- for (i = 0; i < vectors; ++i)
- adap->msix_info[i].vec = entries[i].vector;
- adap->msix_nvectors = vectors;
- }
+ for (i = 0; i < vectors; ++i)
+ adap->msix_info[i].vec = entries[i].vector;
+ adap->msix_nvectors = vectors;
- return err;
+ return 0;
}
static void print_port_info(struct adapter *adap, const struct adapter_info *ai)
--
1.7.7.6
^ 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