* [PATCH v6 2/6] can: m_can: Add call to of_can_transceiver
From: Faiz Abbas @ 2017-12-22 13:31 UTC (permalink / raw)
To: wg, mkl, robh+dt, mark.rutland
Cc: linux-can, netdev, devicetree, linux-kernel, faiz_abbas, nsekhar,
fcooper, robh, Wenyou.Yang, sergei.shtylyov
In-Reply-To: <1513949488-13026-1-git-send-email-faiz_abbas@ti.com>
From: Franklin S Cooper Jr <fcooper@ti.com>
Add call to new generic functions that provides support via a binding
to limit the arbitration rate and/or data rate imposed by the physical
transceiver connected to the MCAN peripheral.
Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
---
drivers/net/can/m_can/m_can.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index f4947a7..f72116e 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -1649,6 +1649,8 @@ static int m_can_plat_probe(struct platform_device *pdev)
devm_can_led_init(dev);
+ of_can_transceiver(dev);
+
dev_info(&pdev->dev, "%s device registered (irq=%d, version=%d)\n",
KBUILD_MODNAME, dev->irq, priv->version);
--
2.7.4
^ permalink raw reply related
* [PATCH v6 0/6] Add M_CAN Support for Dra76 platform
From: Faiz Abbas @ 2017-12-22 13:31 UTC (permalink / raw)
To: wg, mkl, robh+dt, mark.rutland
Cc: linux-can, netdev, devicetree, linux-kernel, faiz_abbas, nsekhar,
fcooper, robh, Wenyou.Yang, sergei.shtylyov
This patch series adds support for M_CAN on the TI Dra76
platform. Device tree patches will be sent separately.
A bunch of patches were sent before by
Franklin Cooper <fcooper@ti.com>. I have clubbed the
series together and rebased to the latest kernel.
v6 changes:
Dropped the patches to make hclk optional. Drivers
which enable hclk as the interface clock using
pm_runtime calls must still provide a hclk in the
clocks property.
Support higher speed CAN-FD bitrate:
The community decided that data sampling point be used
for the secondary sampling point here
https://patchwork.kernel.org/patch/9909845/
Franklin S Cooper Jr (6):
can: dev: Add support for limiting configured bitrate
can: m_can: Add call to of_can_transceiver
can: m_can: Add PM Runtime
can: m_can: Support higher speed CAN-FD bitrates
dt-bindings: can: m_can: Document new can transceiver binding
dt-bindings: can: can-transceiver: Document new binding
.../bindings/net/can/can-transceiver.txt | 24 +++++++
.../devicetree/bindings/net/can/m_can.txt | 9 +++
drivers/net/can/dev.c | 39 +++++++++++
drivers/net/can/m_can/m_can.c | 81 ++++++++++++++++++++--
include/linux/can/dev.h | 8 +++
5 files changed, 156 insertions(+), 5 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/can/can-transceiver.txt
--
2.7.4
^ permalink raw reply
* [PATCH v6 1/6] can: dev: Add support for limiting configured bitrate
From: Faiz Abbas @ 2017-12-22 13:31 UTC (permalink / raw)
To: wg-5Yr1BZd7O62+XT7JhA+gdA, mkl-bIcnvbaLZ9MEGnE8C9+IrQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8
Cc: linux-can-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, faiz_abbas-l0cyMroinI0,
nsekhar-l0cyMroinI0, fcooper-l0cyMroinI0,
robh-DgEjT+Ai2ygdnm+yROfE0A, Wenyou.Yang-UWL1GkI3JZL3oGB3hsPCZA,
sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8
In-Reply-To: <1513949488-13026-1-git-send-email-faiz_abbas-l0cyMroinI0@public.gmane.org>
From: Franklin S Cooper Jr <fcooper-l0cyMroinI0@public.gmane.org>
Various CAN or CAN-FD IP may be able to run at a faster rate than
what the transceiver the CAN node is connected to. This can lead to
unexpected errors. However, CAN transceivers typically have fixed
limitations and provide no means to discover these limitations at
runtime. Therefore, add support for a can-transceiver node that
can be reused by other CAN peripheral drivers to determine for both
CAN and CAN-FD what the max bitrate that can be used. If the user
tries to configure CAN to pass these maximum bitrates it will throw
an error.
Signed-off-by: Franklin S Cooper Jr <fcooper-l0cyMroinI0@public.gmane.org>
[nsekhar-l0cyMroinI0@public.gmane.org: fix build error with !CONFIG_OF]
Signed-off-by: Sekhar Nori <nsekhar-l0cyMroinI0@public.gmane.org>
Signed-off-by: Faiz Abbas <faiz_abbas-l0cyMroinI0@public.gmane.org>
---
v6 changes:
fix build error with !CONFIG_OF
drivers/net/can/dev.c | 39 +++++++++++++++++++++++++++++++++++++++
include/linux/can/dev.h | 8 ++++++++
2 files changed, 47 insertions(+)
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index 365a8cc..007cfc0 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -27,6 +27,7 @@
#include <linux/can/skb.h>
#include <linux/can/netlink.h>
#include <linux/can/led.h>
+#include <linux/of.h>
#include <net/rtnetlink.h>
#define MOD_DESC "CAN device driver interface"
@@ -814,6 +815,30 @@ int open_candev(struct net_device *dev)
}
EXPORT_SYMBOL_GPL(open_candev);
+#ifdef CONFIG_OF
+/*
+ * Common function that can be used to understand the limitation of
+ * a transceiver when it provides no means to determine these limitations
+ * at runtime.
+ */
+void of_can_transceiver(struct net_device *dev)
+{
+ struct device_node *dn;
+ struct can_priv *priv = netdev_priv(dev);
+ struct device_node *np = dev->dev.parent->of_node;
+ int ret;
+
+ dn = of_get_child_by_name(np, "can-transceiver");
+ if (!dn)
+ return;
+
+ ret = of_property_read_u32(dn, "max-bitrate", &priv->max_bitrate);
+ if ((ret && ret != -EINVAL) || (!ret && !priv->max_bitrate))
+ netdev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit.\n");
+}
+EXPORT_SYMBOL_GPL(of_can_transceiver);
+#endif
+
/*
* Common close function for cleanup before the device gets closed.
*
@@ -913,6 +938,13 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
priv->bitrate_const_cnt);
if (err)
return err;
+
+ if (priv->max_bitrate && bt.bitrate > priv->max_bitrate) {
+ netdev_err(dev, "arbitration bitrate surpasses transceiver capabilities of %d bps\n",
+ priv->max_bitrate);
+ return -EINVAL;
+ }
+
memcpy(&priv->bittiming, &bt, sizeof(bt));
if (priv->do_set_bittiming) {
@@ -997,6 +1029,13 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
priv->data_bitrate_const_cnt);
if (err)
return err;
+
+ if (priv->max_bitrate && dbt.bitrate > priv->max_bitrate) {
+ netdev_err(dev, "canfd data bitrate surpasses transceiver capabilities of %d bps\n",
+ priv->max_bitrate);
+ return -EINVAL;
+ }
+
memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));
if (priv->do_set_data_bittiming) {
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 61f1cf2..fbb7810 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -48,6 +48,8 @@ struct can_priv {
unsigned int data_bitrate_const_cnt;
struct can_clock clock;
+ unsigned int max_bitrate;
+
enum can_state state;
/* CAN controller features - see include/uapi/linux/can/netlink.h */
@@ -166,6 +168,12 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx);
void can_free_echo_skb(struct net_device *dev, unsigned int idx);
+#ifdef CONFIG_OF
+void of_can_transceiver(struct net_device *dev);
+#else
+static inline void of_can_transceiver(struct net_device *dev) { }
+#endif
+
struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf);
struct sk_buff *alloc_canfd_skb(struct net_device *dev,
struct canfd_frame **cfd);
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v6 3/6] can: m_can: Add PM Runtime
From: Faiz Abbas @ 2017-12-22 13:31 UTC (permalink / raw)
To: wg, mkl, robh+dt, mark.rutland
Cc: linux-can, netdev, devicetree, linux-kernel, faiz_abbas, nsekhar,
fcooper, robh, Wenyou.Yang, sergei.shtylyov
In-Reply-To: <1513949488-13026-1-git-send-email-faiz_abbas@ti.com>
From: Franklin S Cooper Jr <fcooper@ti.com>
Add support for PM Runtime which is the new way to handle managing clocks.
However, to avoid breaking SoCs not using PM_RUNTIME leave the old clk
management approach in place.
PM_RUNTIME is required by OMAP based devices to handle clock management.
Therefore, this allows future Texas Instruments SoCs that have the MCAN IP
to work with this driver.
Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
[nsekhar@ti.com: handle pm_runtime_get_sync() failure, fix some bugs]
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
---
drivers/net/can/m_can/m_can.c | 38 ++++++++++++++++++++++++++++++++++----
1 file changed, 34 insertions(+), 4 deletions(-)
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index f72116e..53e764f 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -23,6 +23,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/iopoll.h>
#include <linux/can/dev.h>
@@ -625,19 +626,33 @@ static int m_can_clk_start(struct m_can_priv *priv)
{
int err;
+ err = pm_runtime_get_sync(priv->device);
+ if (err) {
+ pm_runtime_put_noidle(priv->device);
+ return err;
+ }
+
err = clk_prepare_enable(priv->hclk);
if (err)
- return err;
+ goto pm_runtime_put;
err = clk_prepare_enable(priv->cclk);
if (err)
- clk_disable_unprepare(priv->hclk);
+ goto disable_hclk;
return err;
+
+disable_hclk:
+ clk_disable_unprepare(priv->hclk);
+pm_runtime_put:
+ pm_runtime_put_sync(priv->device);
+ return err;
}
static void m_can_clk_stop(struct m_can_priv *priv)
{
+ pm_runtime_put_sync(priv->device);
+
clk_disable_unprepare(priv->cclk);
clk_disable_unprepare(priv->hclk);
}
@@ -1577,13 +1592,20 @@ static int m_can_plat_probe(struct platform_device *pdev)
/* Enable clocks. Necessary to read Core Release in order to determine
* M_CAN version
*/
+ pm_runtime_enable(&pdev->dev);
+ ret = pm_runtime_get_sync(&pdev->dev);
+ if (ret) {
+ pm_runtime_put_noidle(&pdev->dev);
+ goto pm_runtime_fail;
+ }
+
ret = clk_prepare_enable(hclk);
if (ret)
- goto disable_hclk_ret;
+ goto pm_runtime_put;
ret = clk_prepare_enable(cclk);
if (ret)
- goto disable_cclk_ret;
+ goto disable_hclk_ret;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "m_can");
addr = devm_ioremap_resource(&pdev->dev, res);
@@ -1666,6 +1688,11 @@ static int m_can_plat_probe(struct platform_device *pdev)
clk_disable_unprepare(cclk);
disable_hclk_ret:
clk_disable_unprepare(hclk);
+pm_runtime_put:
+ pm_runtime_put_sync(&pdev->dev);
+pm_runtime_fail:
+ if (ret)
+ pm_runtime_disable(&pdev->dev);
failed_ret:
return ret;
}
@@ -1723,6 +1750,9 @@ static int m_can_plat_remove(struct platform_device *pdev)
struct net_device *dev = platform_get_drvdata(pdev);
unregister_m_can_dev(dev);
+
+ pm_runtime_disable(&pdev->dev);
+
platform_set_drvdata(pdev, NULL);
free_m_can_dev(dev);
--
2.7.4
^ permalink raw reply related
* [PATCH v6 4/6] can: m_can: Support higher speed CAN-FD bitrates
From: Faiz Abbas @ 2017-12-22 13:31 UTC (permalink / raw)
To: wg, mkl, robh+dt, mark.rutland
Cc: linux-can, netdev, devicetree, linux-kernel, faiz_abbas, nsekhar,
fcooper, robh, Wenyou.Yang, sergei.shtylyov
In-Reply-To: <1513949488-13026-1-git-send-email-faiz_abbas@ti.com>
From: Franklin S Cooper Jr <fcooper@ti.com>
During test transmitting using CAN-FD at high bitrates (> 2 Mbps)
would fail. Scoping the signals I noticed that only a single bit
was being transmitted and with a bit more investigation realized the actual
MCAN IP would go back to initialization mode automatically.
It appears this issue is due to the MCAN needing to use the Transmitter
Delay Compensation Mode with the correct value for the transmitter delay
compensation offset (tdco). What impacts the tdco value isn't 100% clear
but to calculate it you use an equation defined in the MCAN User's Guide.
The user guide mentions that this register needs to be set based on clock
values, secondary sample point and the data bitrate. One of the key
variables that can't automatically be determined is the secondary
sample point (ssp). This ssp is similar to the sp but is specific to this
transmitter delay compensation mode. The guidelines for configuring
ssp is rather vague but via some CAN test it appears for DRA76x that putting
the value same as data sampling point works.
The CAN-CIA's "Bit Time Requirements for CAN FD" paper presented at
the International CAN Conference 2013 indicates that this TDC mode is
only needed for data bit rates above 2.5 Mbps. Therefore, only enable
this mode when the data bit rate is above 2.5 Mbps.
Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
---
drivers/net/can/m_can/m_can.c | 41 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 53e764f..371ffc1 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -127,6 +127,12 @@ enum m_can_mram_cfg {
#define DBTP_DSJW_SHIFT 0
#define DBTP_DSJW_MASK (0xf << DBTP_DSJW_SHIFT)
+/* Transmitter Delay Compensation Register (TDCR) */
+#define TDCR_TDCO_SHIFT 8
+#define TDCR_TDCO_MASK (0x7F << TDCR_TDCO_SHIFT)
+#define TDCR_TDCF_SHIFT 0
+#define TDCR_TDCF_MASK (0x7F << TDCR_TDCF_SHIFT)
+
/* Test Register (TEST) */
#define TEST_LBCK BIT(4)
@@ -991,7 +997,8 @@ static int m_can_set_bittiming(struct net_device *dev)
const struct can_bittiming *bt = &priv->can.bittiming;
const struct can_bittiming *dbt = &priv->can.data_bittiming;
u16 brp, sjw, tseg1, tseg2;
- u32 reg_btp;
+ u32 reg_btp, tdco, ssp;
+ bool enable_tdc = false;
brp = bt->brp - 1;
sjw = bt->sjw - 1;
@@ -1006,9 +1013,41 @@ static int m_can_set_bittiming(struct net_device *dev)
sjw = dbt->sjw - 1;
tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1;
tseg2 = dbt->phase_seg2 - 1;
+
+ /* TDC is only needed for bitrates beyond 2.5 MBit/s.
+ * This is mentioned in the "Bit Time Requirements for CAN FD"
+ * paper presented at the International CAN Conference 2013
+ */
+ if (dbt->bitrate > 2500000) {
+ /* Use the same value of secondary sampling point
+ * as the data sampling point
+ */
+ ssp = dbt->sample_point;
+
+ /* Equation based on Bosch's M_CAN User Manual's
+ * Transmitter Delay Compensation Section
+ */
+ tdco = (priv->can.clock.freq / 1000) *
+ ssp / dbt->bitrate;
+
+ /* Max valid TDCO value is 127 */
+ if (tdco > 127) {
+ netdev_warn(dev, "TDCO value of %u is beyond maximum limit. Disabling Transmitter Delay Compensation mode\n",
+ tdco);
+ } else {
+ enable_tdc = true;
+ m_can_write(priv, M_CAN_TDCR,
+ tdco << TDCR_TDCO_SHIFT);
+ }
+ }
+
reg_btp = (brp << DBTP_DBRP_SHIFT) | (sjw << DBTP_DSJW_SHIFT) |
(tseg1 << DBTP_DTSEG1_SHIFT) |
(tseg2 << DBTP_DTSEG2_SHIFT);
+
+ if (enable_tdc)
+ reg_btp |= DBTP_TDC;
+
m_can_write(priv, M_CAN_DBTP, reg_btp);
}
--
2.7.4
^ permalink raw reply related
* [PATCH v6 5/6] dt-bindings: can: m_can: Document new can transceiver binding
From: Faiz Abbas @ 2017-12-22 13:31 UTC (permalink / raw)
To: wg-5Yr1BZd7O62+XT7JhA+gdA, mkl-bIcnvbaLZ9MEGnE8C9+IrQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8
Cc: linux-can-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, faiz_abbas-l0cyMroinI0,
nsekhar-l0cyMroinI0, fcooper-l0cyMroinI0,
robh-DgEjT+Ai2ygdnm+yROfE0A, Wenyou.Yang-UWL1GkI3JZL3oGB3hsPCZA,
sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8
In-Reply-To: <1513949488-13026-1-git-send-email-faiz_abbas-l0cyMroinI0@public.gmane.org>
From: Franklin S Cooper Jr <fcooper-l0cyMroinI0@public.gmane.org>
Add information regarding can-transceiver binding. This is especially
important for MCAN since the IP allows CAN FD mode to run significantly
faster than what most transceivers are capable of.
Signed-off-by: Franklin S Cooper Jr <fcooper-l0cyMroinI0@public.gmane.org>
Signed-off-by: Sekhar Nori <nsekhar-l0cyMroinI0@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Faiz Abbas <faiz_abbas-l0cyMroinI0@public.gmane.org>
---
Documentation/devicetree/bindings/net/can/m_can.txt | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/can/m_can.txt b/Documentation/devicetree/bindings/net/can/m_can.txt
index 63e9042..ed61438 100644
--- a/Documentation/devicetree/bindings/net/can/m_can.txt
+++ b/Documentation/devicetree/bindings/net/can/m_can.txt
@@ -43,6 +43,11 @@ Required properties:
Please refer to 2.4.1 Message RAM Configuration in
Bosch M_CAN user manual for details.
+Optional Subnode:
+- can-transceiver : Can-transceiver subnode describing maximum speed
+ that can be used for CAN/CAN-FD modes. See
+ Documentation/devicetree/bindings/net/can/can-transceiver.txt
+ for details.
Example:
SoC dtsi:
m_can1: can@20e8000 {
@@ -63,4 +68,8 @@ Board dts:
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_m_can1>;
status = "enabled";
+
+ can-transceiver {
+ max-bitrate = <5000000>;
+ };
};
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v6 6/6] dt-bindings: can: can-transceiver: Document new binding
From: Faiz Abbas @ 2017-12-22 13:31 UTC (permalink / raw)
To: wg, mkl, robh+dt, mark.rutland
Cc: linux-can, netdev, devicetree, linux-kernel, faiz_abbas, nsekhar,
fcooper, robh, Wenyou.Yang, sergei.shtylyov
In-Reply-To: <1513949488-13026-1-git-send-email-faiz_abbas@ti.com>
From: Franklin S Cooper Jr <fcooper@ti.com>
Add documentation to describe usage of the new can-transceiver binding.
This new binding is applicable for any CAN device therefore it exists as
its own document.
Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
---
.../bindings/net/can/can-transceiver.txt | 24 ++++++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/can/can-transceiver.txt
diff --git a/Documentation/devicetree/bindings/net/can/can-transceiver.txt b/Documentation/devicetree/bindings/net/can/can-transceiver.txt
new file mode 100644
index 0000000..0011f53
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/can-transceiver.txt
@@ -0,0 +1,24 @@
+Generic CAN transceiver Device Tree binding
+------------------------------
+
+CAN transceiver typically limits the max speed in standard CAN and CAN FD
+modes. Typically these limitations are static and the transceivers themselves
+provide no way to detect this limitation at runtime. For this situation,
+the "can-transceiver" node can be used.
+
+Required Properties:
+ max-bitrate: a positive non 0 value that determines the max
+ speed that CAN/CAN-FD can run. Any other value
+ will be ignored.
+
+Examples:
+
+Based on Texas Instrument's TCAN1042HGV CAN Transceiver
+
+m_can0 {
+ ....
+ can-transceiver {
+ max-bitrate = <5000000>;
+ };
+ ...
+};
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net] rtnetlink: fix struct net reference leak
From: Craig Gallek @ 2017-12-22 13:59 UTC (permalink / raw)
To: Nicolas Dichtel; +Cc: David Miller, Jiri Benc, netdev, Jason A . Donenfeld
In-Reply-To: <60dfb17d-3da8-ea53-cf9f-912dca52889b@6wind.com>
On Fri, Dec 22, 2017 at 3:11 AM, Nicolas Dichtel
<nicolas.dichtel@6wind.com> wrote:
> Le 21/12/2017 à 23:18, Craig Gallek a écrit :
>> From: Craig Gallek <kraig@google.com>
>>
>> The below referenced commit extended the RTM_GETLINK interface to
>> allow querying by netns id. The netnsid property was previously
>> defined as a signed integer, but this patch assumes that the user
>> always passes a positive integer. syzkaller discovered this problem
>> by setting a negative netnsid and then calling the get-link path
>> in a tight loop. This surprisingly quickly overflows the reference
>> count on the associated struct net, potentially destroying it. When the
>> default namespace is used, the machine crashes in strange and interesting
>> ways.
>>
>> Unfortunately, this is not easy to reproduce with just the ip tool
>> as it enforces unsigned integer parsing despite the interface interpeting
>> the NETNSID attribute as signed.
>>
>> I'm not sure why this attribute is signed in the first place, but
>> the first commit that introduced it (6621dd29eb9b) is in v4.15-rc4,
>> so I assume it's too late to change.
> A valid (assigned) nsid is always >= 0.
>
>>
>> This patch removes the positive netns id assumption, but adds another
>> assumption that the netns id 0 is always the 'self' identifying id (for
>> which an additional struct net reference is not necessary).
> We cannot make this assumption, this is wrong. nsids may be automatically
> allocated by the kernel, and it starts by 0.
> The current netns can be identify by NETNSA_NSID_NOT_ASSIGNED, ie -1.
Thank you, I'll respin this with NETNSA_NSID_NOT_ASSIGNED as the sentinel value.
Craig
^ permalink raw reply
* [PATCH net-next 0/2] l2tp: fix offset/peer_offset conf parameters
From: Lorenzo Bianconi @ 2017-12-22 14:10 UTC (permalink / raw)
To: davem; +Cc: netdev, jchapman, liuhangbin
This patchset add peer_offset configuration parameter in order to
specify two different values for payload offset on tx/rx side.
Moreover fix missing print session offset info
Hangbin Liu (1):
l2tp: fix missing print session offset info
Lorenzo Bianconi (1):
l2tp: add peer_offset parameter
include/uapi/linux/l2tp.h | 1 +
net/l2tp/l2tp_core.c | 3 ++-
net/l2tp/l2tp_core.h | 13 ++++++++++---
net/l2tp/l2tp_debugfs.c | 8 +++++---
net/l2tp/l2tp_netlink.c | 23 ++++++++++++++++++++++-
5 files changed, 40 insertions(+), 8 deletions(-)
--
2.13.6
^ permalink raw reply
* [PATCH net-next 1/2] l2tp: fix missing print session offset info
From: Lorenzo Bianconi @ 2017-12-22 14:10 UTC (permalink / raw)
To: davem; +Cc: netdev, jchapman, liuhangbin
In-Reply-To: <cover.1513951129.git.lorenzo.bianconi@redhat.com>
From: Hangbin Liu <liuhangbin@gmail.com>
Report offset parameter in L2TP_CMD_SESSION_GET command if
it has been configured by userspace
Fixes: 309795f4bec ("l2tp: Add netlink control API for L2TP")
Reported-by: Jianlin Shi <jishi@redhat.com>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
net/l2tp/l2tp_netlink.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index a1f24fb2be98..7e9c50125556 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -761,6 +761,8 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl
if ((session->ifname[0] &&
nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) ||
+ (session->offset &&
+ nla_put_u16(skb, L2TP_ATTR_OFFSET, session->offset)) ||
(session->cookie_len &&
nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len,
&session->cookie[0])) ||
--
2.13.6
^ permalink raw reply related
* [PATCH net-next 2/2] l2tp: add peer_offset parameter
From: Lorenzo Bianconi @ 2017-12-22 14:10 UTC (permalink / raw)
To: davem; +Cc: netdev, jchapman, liuhangbin
In-Reply-To: <cover.1513951129.git.lorenzo.bianconi@redhat.com>
Introduce peer_offset parameter in order to add the capability
to specify two different values for payload offset on tx/rx side.
If just offset is provided by userspace use it for rx side as well
in order to maintain compatibility with older l2tp versions
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
include/uapi/linux/l2tp.h | 1 +
net/l2tp/l2tp_core.c | 3 ++-
net/l2tp/l2tp_core.h | 13 ++++++++++---
net/l2tp/l2tp_debugfs.c | 8 +++++---
net/l2tp/l2tp_netlink.c | 21 ++++++++++++++++++++-
5 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h
index d84ce5c1c9aa..d6fee55dbded 100644
--- a/include/uapi/linux/l2tp.h
+++ b/include/uapi/linux/l2tp.h
@@ -127,6 +127,7 @@ enum {
L2TP_ATTR_UDP_ZERO_CSUM6_TX, /* flag */
L2TP_ATTR_UDP_ZERO_CSUM6_RX, /* flag */
L2TP_ATTR_PAD,
+ L2TP_ATTR_PEER_OFFSET, /* u16 */
__L2TP_ATTR_MAX,
};
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 115918ad8eca..6ff64717da1e 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -792,7 +792,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
ptr += 2 + offset;
}
} else
- ptr += session->offset;
+ ptr += session->peer_offset;
offset = ptr - optr;
if (!pskb_may_pull(skb, offset))
@@ -1785,6 +1785,7 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
session->lns_mode = cfg->lns_mode;
session->reorder_timeout = cfg->reorder_timeout;
session->offset = cfg->offset;
+ session->peer_offset = cfg->peer_offset;
session->l2specific_type = cfg->l2specific_type;
session->l2specific_len = cfg->l2specific_len;
session->cookie_len = cfg->cookie_len;
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index 9534e16965cc..c6fe7cc42a05 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -59,7 +59,8 @@ struct l2tp_session_cfg {
int debug; /* bitmask of debug message
* categories */
u16 vlan_id; /* VLAN pseudowire only */
- u16 offset; /* offset to payload */
+ u16 offset; /* offset to tx payload */
+ u16 peer_offset; /* offset to rx payload */
u16 l2specific_len; /* Layer 2 specific length */
u16 l2specific_type; /* Layer 2 specific type */
u8 cookie[8]; /* optional cookie */
@@ -86,8 +87,14 @@ struct l2tp_session {
int cookie_len;
u8 peer_cookie[8];
int peer_cookie_len;
- u16 offset; /* offset from end of L2TP header
- to beginning of data */
+ u16 offset; /* offset from end of L2TP
+ * header to beginning of
+ * tx data
+ */
+ u16 peer_offset; /* offset from end of L2TP
+ * header to beginning of
+ * rx data
+ */
u16 l2specific_len;
u16 l2specific_type;
u16 hdr_len;
diff --git a/net/l2tp/l2tp_debugfs.c b/net/l2tp/l2tp_debugfs.c
index eb69411bcb47..4cc30b38aba4 100644
--- a/net/l2tp/l2tp_debugfs.c
+++ b/net/l2tp/l2tp_debugfs.c
@@ -180,8 +180,9 @@ static void l2tp_dfs_seq_session_show(struct seq_file *m, void *v)
session->lns_mode ? "LNS" : "LAC",
session->debug,
jiffies_to_msecs(session->reorder_timeout));
- seq_printf(m, " offset %hu l2specific %hu/%hu\n",
- session->offset, session->l2specific_type, session->l2specific_len);
+ seq_printf(m, " offset %hu peer_offset %hu l2specific %hu/%hu\n",
+ session->offset, session->peer_offset,
+ session->l2specific_type, session->l2specific_len);
if (session->cookie_len) {
seq_printf(m, " cookie %02x%02x%02x%02x",
session->cookie[0], session->cookie[1],
@@ -228,7 +229,8 @@ static int l2tp_dfs_seq_show(struct seq_file *m, void *v)
seq_puts(m, " debug tx-pkts/bytes/errs rx-pkts/bytes/errs\n");
seq_puts(m, " SESSION ID, peer ID, PWTYPE\n");
seq_puts(m, " refcnt cnt\n");
- seq_puts(m, " offset OFFSET l2specific TYPE/LEN\n");
+ seq_puts(m, " offset OFFSET peer_offset OFFSET");
+ seq_puts(m, " l2specific TYPE/LEN\n");
seq_puts(m, " [ cookie ]\n");
seq_puts(m, " [ peer cookie ]\n");
seq_puts(m, " config mtu/mru/rcvseq/sendseq/dataseq/lns debug reorderto\n");
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index 7e9c50125556..d7d4d7a7a54d 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -547,9 +547,25 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
}
if (tunnel->version > 2) {
- if (info->attrs[L2TP_ATTR_OFFSET])
+ if (info->attrs[L2TP_ATTR_PEER_OFFSET]) {
+ struct nlattr *peer_offset;
+
+ peer_offset = info->attrs[L2TP_ATTR_PEER_OFFSET];
+ cfg.peer_offset = nla_get_u16(peer_offset);
+ }
+
+ if (info->attrs[L2TP_ATTR_OFFSET]) {
cfg.offset = nla_get_u16(info->attrs[L2TP_ATTR_OFFSET]);
+ /* in order to maintain compatibility with older
+ * versions where offset was used for both tx and
+ * rx side, update rx side with offset if peer_offset
+ * is not provided by userspace
+ */
+ if (!info->attrs[L2TP_ATTR_PEER_OFFSET])
+ cfg.peer_offset = cfg.offset;
+ }
+
if (info->attrs[L2TP_ATTR_DATA_SEQ])
cfg.data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]);
@@ -763,6 +779,8 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl
nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) ||
(session->offset &&
nla_put_u16(skb, L2TP_ATTR_OFFSET, session->offset)) ||
+ (session->peer_offset &&
+ nla_put_u16(skb, L2TP_ATTR_PEER_OFFSET, session->peer_offset)) ||
(session->cookie_len &&
nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len,
&session->cookie[0])) ||
@@ -903,6 +921,7 @@ static const struct nla_policy l2tp_nl_policy[L2TP_ATTR_MAX + 1] = {
[L2TP_ATTR_PW_TYPE] = { .type = NLA_U16, },
[L2TP_ATTR_ENCAP_TYPE] = { .type = NLA_U16, },
[L2TP_ATTR_OFFSET] = { .type = NLA_U16, },
+ [L2TP_ATTR_PEER_OFFSET] = { .type = NLA_U16, },
[L2TP_ATTR_DATA_SEQ] = { .type = NLA_U8, },
[L2TP_ATTR_L2SPEC_TYPE] = { .type = NLA_U8, },
[L2TP_ATTR_L2SPEC_LEN] = { .type = NLA_U8, },
--
2.13.6
^ permalink raw reply related
* Re: [PATCH v4 01/36] asm-generic/io.h: move ioremap_nocache/ioremap_uc/ioremap_wc/ioremap_wt out of ifndef CONFIG_MMU
From: Greentime Hu @ 2017-12-22 14:38 UTC (permalink / raw)
To: kbuild test robot
Cc: kbuild-all, Greentime, Linux Kernel Mailing List, Arnd Bergmann,
linux-arch, Thomas Gleixner, Jason Cooper, Marc Zyngier,
Rob Herring, netdev, Vincent Chen, DTML, Al Viro, David Howells,
Will Deacon, Daniel Lezcano, linux-serial, Geert Uytterhoeven,
Linus Walleij, Mark Rutland, Greg
In-Reply-To: <201712201836.XDtv2JdK%fengguang.wu@intel.com>
2017-12-20 18:09 GMT+08:00 kbuild test robot <lkp@intel.com>:
> Hi Greentime,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on tip/timers/core]
> [also build test ERROR on v4.15-rc4 next-20171220]
> [cannot apply to linus/master]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Greentime-Hu/Andes-nds32-Linux-Kernel/20171220-155937
> config: sparc-defconfig (attached as .config)
> compiler: sparc-linux-gcc (GCC) 7.2.0
> reproduce:
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> make.cross ARCH=sparc
>
> All error/warnings (new ones prefixed by >>):
>
> In file included from arch/sparc/include/asm/io.h:6:0,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from arch/sparc/kernel/kernel.h:4,
> from arch/sparc/kernel/traps_32.c:30:
>>> arch/sparc/include/asm/io_32.h:129:15: error: conflicting types for 'ioremap'
> void __iomem *ioremap(unsigned long offset, unsigned long size);
> ^~~~~~~
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from arch/sparc/kernel/kernel.h:4,
> from arch/sparc/kernel/traps_32.c:30:
> include/asm-generic/io.h:864:15: note: previous declaration of 'ioremap' was here
> void __iomem *ioremap(phys_addr_t phys_addr, size_t size);
> ^~~~~~~
> In file included from arch/sparc/include/asm/io.h:6:0,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from arch/sparc/kernel/kernel.h:4,
> from arch/sparc/kernel/traps_32.c:30:
> arch/sparc/include/asm/io_32.h:130:0: error: "ioremap_nocache" redefined [-Werror]
> #define ioremap_nocache(X,Y) ioremap((X),(Y))
>
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from arch/sparc/kernel/kernel.h:4,
> from arch/sparc/kernel/traps_32.c:30:
> include/asm-generic/io.h:865:0: note: this is the location of the previous definition
> #define ioremap_nocache ioremap_nocache
>
> In file included from arch/sparc/include/asm/io.h:6:0,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from arch/sparc/kernel/kernel.h:4,
> from arch/sparc/kernel/traps_32.c:30:
> arch/sparc/include/asm/io_32.h:131:0: error: "ioremap_wc" redefined [-Werror]
> #define ioremap_wc(X,Y) ioremap((X),(Y))
>
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from arch/sparc/kernel/kernel.h:4,
> from arch/sparc/kernel/traps_32.c:30:
> include/asm-generic/io.h:881:0: note: this is the location of the previous definition
> #define ioremap_wc ioremap_wc
>
> In file included from arch/sparc/include/asm/io.h:6:0,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from arch/sparc/kernel/kernel.h:4,
> from arch/sparc/kernel/traps_32.c:30:
> arch/sparc/include/asm/io_32.h:132:0: error: "ioremap_wt" redefined [-Werror]
> #define ioremap_wt(X,Y) ioremap((X),(Y))
>
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from arch/sparc/kernel/kernel.h:4,
> from arch/sparc/kernel/traps_32.c:30:
> include/asm-generic/io.h:889:0: note: this is the location of the previous definition
> #define ioremap_wt ioremap_wt
>
> cc1: all warnings being treated as errors
> --
> In file included from arch/sparc/include/asm/io.h:6:0,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc/kernel/ioport.c:36:
>>> arch/sparc/include/asm/io_32.h:129:15: error: conflicting types for 'ioremap'
> void __iomem *ioremap(unsigned long offset, unsigned long size);
> ^~~~~~~
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc/kernel/ioport.c:36:
> include/asm-generic/io.h:864:15: note: previous declaration of 'ioremap' was here
> void __iomem *ioremap(phys_addr_t phys_addr, size_t size);
> ^~~~~~~
> In file included from arch/sparc/include/asm/io.h:6:0,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc/kernel/ioport.c:36:
> arch/sparc/include/asm/io_32.h:130:0: error: "ioremap_nocache" redefined [-Werror]
> #define ioremap_nocache(X,Y) ioremap((X),(Y))
>
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc/kernel/ioport.c:36:
> include/asm-generic/io.h:865:0: note: this is the location of the previous definition
> #define ioremap_nocache ioremap_nocache
>
> In file included from arch/sparc/include/asm/io.h:6:0,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc/kernel/ioport.c:36:
> arch/sparc/include/asm/io_32.h:131:0: error: "ioremap_wc" redefined [-Werror]
> #define ioremap_wc(X,Y) ioremap((X),(Y))
>
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc/kernel/ioport.c:36:
> include/asm-generic/io.h:881:0: note: this is the location of the previous definition
> #define ioremap_wc ioremap_wc
>
> In file included from arch/sparc/include/asm/io.h:6:0,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc/kernel/ioport.c:36:
> arch/sparc/include/asm/io_32.h:132:0: error: "ioremap_wt" redefined [-Werror]
> #define ioremap_wt(X,Y) ioremap((X),(Y))
>
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc/kernel/ioport.c:36:
> include/asm-generic/io.h:889:0: note: this is the location of the previous definition
> #define ioremap_wt ioremap_wt
>
>>> arch/sparc/kernel/ioport.c:124:15: error: conflicting types for 'ioremap'
> void __iomem *ioremap(unsigned long offset, unsigned long size)
> ^~~~~~~
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc/kernel/ioport.c:36:
> include/asm-generic/io.h:864:15: note: previous declaration of 'ioremap' was here
> void __iomem *ioremap(phys_addr_t phys_addr, size_t size);
> ^~~~~~~
> In file included from include/linux/linkage.h:6:0,
> from include/linux/kernel.h:6,
> from include/linux/list.h:8,
> from include/linux/module.h:9,
> from arch/sparc/kernel/ioport.c:28:
> arch/sparc/kernel/ioport.c:131:15: error: conflicting types for 'ioremap'
> EXPORT_SYMBOL(ioremap);
> ^
> include/linux/export.h:65:21: note: in definition of macro '___EXPORT_SYMBOL'
> extern typeof(sym) sym; \
> ^~~
>>> arch/sparc/kernel/ioport.c:131:1: note: in expansion of macro 'EXPORT_SYMBOL'
> EXPORT_SYMBOL(ioremap);
> ^~~~~~~~~~~~~
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc/kernel/ioport.c:36:
> include/asm-generic/io.h:864:15: note: previous declaration of 'ioremap' was here
> void __iomem *ioremap(phys_addr_t phys_addr, size_t size);
> ^~~~~~~
> cc1: all warnings being treated as errors
> --
> In file included from arch/sparc/include/asm/io.h:6:0,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc//kernel/ioport.c:36:
>>> arch/sparc/include/asm/io_32.h:129:15: error: conflicting types for 'ioremap'
> void __iomem *ioremap(unsigned long offset, unsigned long size);
> ^~~~~~~
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc//kernel/ioport.c:36:
> include/asm-generic/io.h:864:15: note: previous declaration of 'ioremap' was here
> void __iomem *ioremap(phys_addr_t phys_addr, size_t size);
> ^~~~~~~
> In file included from arch/sparc/include/asm/io.h:6:0,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc//kernel/ioport.c:36:
> arch/sparc/include/asm/io_32.h:130:0: error: "ioremap_nocache" redefined [-Werror]
> #define ioremap_nocache(X,Y) ioremap((X),(Y))
>
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc//kernel/ioport.c:36:
> include/asm-generic/io.h:865:0: note: this is the location of the previous definition
> #define ioremap_nocache ioremap_nocache
>
> In file included from arch/sparc/include/asm/io.h:6:0,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc//kernel/ioport.c:36:
> arch/sparc/include/asm/io_32.h:131:0: error: "ioremap_wc" redefined [-Werror]
> #define ioremap_wc(X,Y) ioremap((X),(Y))
>
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc//kernel/ioport.c:36:
> include/asm-generic/io.h:881:0: note: this is the location of the previous definition
> #define ioremap_wc ioremap_wc
>
> In file included from arch/sparc/include/asm/io.h:6:0,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc//kernel/ioport.c:36:
> arch/sparc/include/asm/io_32.h:132:0: error: "ioremap_wt" redefined [-Werror]
> #define ioremap_wt(X,Y) ioremap((X),(Y))
>
> In file included from arch/sparc/include/asm/io_32.h:13:0,
> from arch/sparc/include/asm/io.h:6,
> from include/linux/io.h:25,
> from include/linux/irq.h:24,
> from include/asm-generic/hardirq.h:12,
> from arch/sparc/include/asm/hardirq_32.h:10,
> from arch/sparc/include/asm/hardirq.h:6,
> from include/linux/hardirq.h:8,
> from include/linux/interrupt.h:12,
> from include/linux/pci.h:31,
> from arch/sparc//kernel/ioport.c:36:
> include/asm-generic/io.h:889:0: note: this is the location of the previous definition
> #define ioremap_wt ioremap_wt
>
> arch/sparc//kernel/ioport.c:124:15: error: conflicting types for 'ioremap'
> void __iomem *ioremap(unsigned long offset, unsigned long size)
> ^~~~~~~
>
Hi, all:
I just tried to fix this build error.
Should I send this patch next time with nds32 patchset?
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -126,12 +126,7 @@ static inline void sbus_memcpy_toio(volatile void
__iomem *dst,
* Bus number may be embedded in the higher bits of the physical address.
* This is why we have no bus number argument to ioremap().
*/
-void __iomem *ioremap(unsigned long offset, unsigned long size);
-#define ioremap_nocache(X,Y) ioremap((X),(Y))
-#define ioremap_wc(X,Y) ioremap((X),(Y))
-#define ioremap_wt(X,Y) ioremap((X),(Y))
void iounmap(volatile void __iomem *addr);
-
/* Create a virtual mapping cookie for an IO port range */
void __iomem *ioport_map(unsigned long port, unsigned int nr);
void ioport_unmap(void __iomem *);
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 12894f2..9cdeb54 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -121,12 +121,12 @@ static void xres_free(struct xresource *xrp) {
*
* Bus type is always zero on IIep.
*/
-void __iomem *ioremap(unsigned long offset, unsigned long size)
+void __iomem *ioremap(phys_addr_t offset, size_t size)
{
char name[14];
sprintf(name, "phys_%08x", (u32)offset);
- return _sparc_alloc_io(0, offset, size, name);
+ return _sparc_alloc_io(0, (unsigned long)offset, size, name);
}
EXPORT_SYMBOL(ioremap);
^ permalink raw reply related
* Re: [PATCH v4 01/36] asm-generic/io.h: move ioremap_nocache/ioremap_uc/ioremap_wc/ioremap_wt out of ifndef CONFIG_MMU
From: Greentime Hu @ 2017-12-22 14:40 UTC (permalink / raw)
To: kbuild test robot
Cc: kbuild-all, Greentime, Linux Kernel Mailing List, Arnd Bergmann,
linux-arch, Thomas Gleixner, Jason Cooper, Marc Zyngier,
Rob Herring, netdev, Vincent Chen, DTML, Al Viro, David Howells,
Will Deacon, Daniel Lezcano, linux-serial, Geert Uytterhoeven,
Linus Walleij, Mark Rutland, Greg
In-Reply-To: <201712201748.C4nCizdE%fengguang.wu@intel.com>
2017-12-20 18:10 GMT+08:00 kbuild test robot <lkp@intel.com>:
> Hi Greentime,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on tip/timers/core]
> [also build test ERROR on v4.15-rc4 next-20171220]
> [cannot apply to linus/master]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Greentime-Hu/Andes-nds32-Linux-Kernel/20171220-155937
> config: openrisc-or1ksim_defconfig (attached as .config)
> compiler: or1k-linux-gcc (GCC) 6.0.0 20160327 (experimental)
> reproduce:
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> make.cross ARCH=openrisc
>
> All error/warnings (new ones prefixed by >>):
>
> In file included from include/linux/io.h:25:0,
> from arch/openrisc/kernel/asm-offsets.c:35:
>>> arch/openrisc/include/asm/io.h:38:29: error: conflicting types for 'ioremap'
> static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
> ^~~~~~~
> In file included from arch/openrisc/include/asm/io.h:32:0,
> from include/linux/io.h:25,
> from arch/openrisc/kernel/asm-offsets.c:35:
> include/asm-generic/io.h:864:15: note: previous declaration of 'ioremap' was here
> void __iomem *ioremap(phys_addr_t phys_addr, size_t size);
> ^~~~~~~
> include/asm-generic/io.h:865:25: error: conflicting types for 'ioremap_nocache'
> #define ioremap_nocache ioremap_nocache
> ^
>>> arch/openrisc/include/asm/io.h:44:29: note: in expansion of macro 'ioremap_nocache'
> static inline void __iomem *ioremap_nocache(phys_addr_t offset,
> ^~~~~~~~~~~~~~~
> include/asm-generic/io.h:865:25: note: previous definition of 'ioremap_nocache' was here
> #define ioremap_nocache ioremap_nocache
> ^
> include/asm-generic/io.h:866:29: note: in expansion of macro 'ioremap_nocache'
> static inline void __iomem *ioremap_nocache(phys_addr_t offset, size_t size)
> ^~~~~~~~~~~~~~~
> make[2]: *** [arch/openrisc/kernel/asm-offsets.s] Error 1
> make[2]: Target '__build' not remade because of errors.
> make[1]: *** [prepare0] Error 2
> make[1]: Target 'prepare' not remade because of errors.
> make: *** [sub-make] Error 2
>
> vim +/ioremap +38 arch/openrisc/include/asm/io.h
>
> 58e0166a Jonas Bonn 2011-06-04 31
> 58e0166a Jonas Bonn 2011-06-04 @32 #include <asm-generic/io.h>
> 9b04ebd1 James Hogan 2012-10-23 33 #include <asm/pgtable.h>
> 58e0166a Jonas Bonn 2011-06-04 34
> 58e0166a Jonas Bonn 2011-06-04 35 extern void __iomem *__ioremap(phys_addr_t offset, unsigned long size,
> 58e0166a Jonas Bonn 2011-06-04 36 pgprot_t prot);
> 58e0166a Jonas Bonn 2011-06-04 37
> 58e0166a Jonas Bonn 2011-06-04 @38 static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
> 58e0166a Jonas Bonn 2011-06-04 39 {
> 58e0166a Jonas Bonn 2011-06-04 40 return __ioremap(offset, size, PAGE_KERNEL);
> 58e0166a Jonas Bonn 2011-06-04 41 }
> 58e0166a Jonas Bonn 2011-06-04 42
> 58e0166a Jonas Bonn 2011-06-04 43 /* #define _PAGE_CI 0x002 */
> 58e0166a Jonas Bonn 2011-06-04 @44 static inline void __iomem *ioremap_nocache(phys_addr_t offset,
> 58e0166a Jonas Bonn 2011-06-04 45 unsigned long size)
> 58e0166a Jonas Bonn 2011-06-04 46 {
> 58e0166a Jonas Bonn 2011-06-04 47 return __ioremap(offset, size,
> 58e0166a Jonas Bonn 2011-06-04 48 __pgprot(pgprot_val(PAGE_KERNEL) | _PAGE_CI));
> 58e0166a Jonas Bonn 2011-06-04 49 }
> 58e0166a Jonas Bonn 2011-06-04 50
>
> :::::: The code at line 38 was first introduced by commit
> :::::: 58e0166a4772aaeb10c9b0f6d59f19099d2047df OpenRISC: Headers
>
> :::::: TO: Jonas Bonn <jonas@southpole.se>
> :::::: CC: Jonas Bonn <jonas@southpole.se>
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi, all:
I just tried to fix this build error.
Should I send this patch next time with nds32 patchset?
--- a/arch/openrisc/include/asm/io.h
+++ b/arch/openrisc/include/asm/io.h
@@ -29,13 +29,14 @@
#define PIO_OFFSET 0
#define PIO_MASK 0
+#define ioremap_nocache ioremap_nocache
#include <asm-generic/io.h>
#include <asm/pgtable.h>
extern void __iomem *__ioremap(phys_addr_t offset, unsigned long size,
pgprot_t prot);
-static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
+static inline void __iomem *ioremap(phys_addr_t offset, size_t size)
{
return __ioremap(offset, size, PAGE_KERNEL);
}
^ permalink raw reply
* Re: pull-request: bpf-next 2017-12-18
From: David Miller @ 2017-12-22 14:42 UTC (permalink / raw)
To: daniel; +Cc: alexei.starovoitov, ast, netdev
In-Reply-To: <9a25f2dd-596f-5aae-65d9-5730406848d0@iogearbox.net>
From: Daniel Borkmann <daniel@iogearbox.net>
Date: Fri, 22 Dec 2017 00:48:22 +0100
> Looks good, one thing: If I spot this correctly, isn't here a ...
>
> prog->aux->jit_data = jit_data;
>
> ... missing? Otherwise the context from the initial pass is neither
> saved for the extra pass nor freed.
Good catch, here is an updated patch:
====================
bpf: sparc64: Add JIT support for multi-function programs.
Modelled strongly upon the arm64 implementation.
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c
index a2f1b5e..991a3ab 100644
--- a/arch/sparc/net/bpf_jit_comp_64.c
+++ b/arch/sparc/net/bpf_jit_comp_64.c
@@ -1507,11 +1507,19 @@ static void jit_fill_hole(void *area, unsigned int size)
*ptr++ = 0x91d02005; /* ta 5 */
}
+struct sparc64_jit_data {
+ struct bpf_binary_header *header;
+ u8 *image;
+ struct jit_ctx ctx;
+};
+
struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
{
struct bpf_prog *tmp, *orig_prog = prog;
+ struct sparc64_jit_data *jit_data;
struct bpf_binary_header *header;
bool tmp_blinded = false;
+ bool extra_pass = false;
struct jit_ctx ctx;
u32 image_size;
u8 *image_ptr;
@@ -1531,13 +1539,31 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
prog = tmp;
}
+ jit_data = prog->aux->jit_data;
+ if (!jit_data) {
+ jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL);
+ if (!jit_data) {
+ prog = orig_prog;
+ goto out;
+ }
+ prog->aux->jit_data = jit_data;
+ }
+ if (jit_data->ctx.offset) {
+ ctx = jit_data->ctx;
+ image_ptr = jit_data->image;
+ header = jit_data->header;
+ extra_pass = true;
+ image_size = sizeof(u32) * ctx.idx;
+ goto skip_init_ctx;
+ }
+
memset(&ctx, 0, sizeof(ctx));
ctx.prog = prog;
ctx.offset = kcalloc(prog->len, sizeof(unsigned int), GFP_KERNEL);
if (ctx.offset == NULL) {
prog = orig_prog;
- goto out;
+ goto out_off;
}
/* Fake pass to detect features used, and get an accurate assessment
@@ -1560,7 +1586,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
}
ctx.image = (u32 *)image_ptr;
-
+skip_init_ctx:
for (pass = 1; pass < 3; pass++) {
ctx.idx = 0;
@@ -1591,14 +1617,24 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
bpf_flush_icache(header, (u8 *)header + (header->pages * PAGE_SIZE));
- bpf_jit_binary_lock_ro(header);
+ if (!prog->is_func || extra_pass) {
+ bpf_jit_binary_lock_ro(header);
+ } else {
+ jit_data->ctx = ctx;
+ jit_data->image = image_ptr;
+ jit_data->header = header;
+ }
prog->bpf_func = (void *)ctx.image;
prog->jited = 1;
prog->jited_len = image_size;
+ if (!prog->is_func || extra_pass) {
out_off:
- kfree(ctx.offset);
+ kfree(ctx.offset);
+ kfree(jit_data);
+ prog->aux->jit_data = NULL;
+ }
out:
if (tmp_blinded)
bpf_jit_prog_release_other(prog, prog == orig_prog ?
^ permalink raw reply related
* Re: [PATCH net-next v5 0/5] Introduce NETIF_F_GRO_HW
From: Sabrina Dubroca @ 2017-12-22 14:57 UTC (permalink / raw)
To: Michael Chan; +Cc: davem, netdev, andrew.gospodarek, alexander.duyck
In-Reply-To: <1513411784-17653-1-git-send-email-michael.chan@broadcom.com>
Hello,
Sorry for commenting late.
2017-12-16, 03:09:39 -0500, Michael Chan wrote:
> Introduce NETIF_F_GRO_HW feature flag and convert drivers that support
> hardware GRO to use the new flag.
>
> v5:
> - Documentation changes requested by Alexander Duyck.
> - bnx2x changes requested by Manish Chopra to enable LRO by default, and
> disable GRO_HW if disable_tpa module parameter is set.
>
> v4:
> - more changes requested by Alexander Duyck:
> - check GRO_HW/GRO dependency in drivers's ndo_fix_features().
> - Reverse the order of RXCSUM and GRO_HW dependency check in
> netdev_fix_features().
> - No propagation in netdev_disable_gro_hw().
IIUC, with the patches that were applied, each driver can define
whether GRO_HW depends on GRO? From a user's perspective, this
inconsistent behavior is going to be quite confusing.
Worse than inconsistent behavior, it looks like a driver deciding that
GRO_HW doesn't depend on GRO is going to introduce a change of
behavior. Previously, when GRO was disabled, there wouldn't be any
packet over MTU handed to the network stack. Now, even if GRO is
disabled, GRO_HW might still be enabled, so we might get over-MTU
packets because of hardware GRO.
I don't think drivers should be allowed to say "GRO_HW doesn't depend
on GRO".
I think it's reasonable to be able to disable software GRO even if
hardware GRO is enabled. Thus, I would propose:
- keep the current GRO flag
- add a GRO_HW flag, depending on GRO, enforced by the core as in
earlier versions of these patches
- add a GRO_SW flag, also depending on GRO
Thanks,
--
Sabrina
^ permalink raw reply
* [PATCH net] bnx2x: Improve reliability in case of nested PCI errors
From: Guilherme G. Piccoli @ 2017-12-22 15:01 UTC (permalink / raw)
To: ariel.elior, everest-linux-l2; +Cc: netdev, gpiccoli, gpiccoli
While in recovery process of PCI error (called EEH on PowerPC arch),
another PCI transaction could be corrupted causing a situation of
nested PCI errors. Also, this scenario could be reproduced with
error injection mechanisms (for debug purposes).
We observe that in case of nested PCI errors, bnx2x might attempt to
initialize its shmem and cause a kernel crash due to bad addresses
read from MCP. Multiple different stack traces were observed depending
on the point the second PCI error happens.
This patch avoids the crashes by:
* failing PCI recovery in case of nested errors (since multiple
PCI errors in a row are not expected to lead to a functional
adapter anyway), and by,
* preventing access to adapter FW when MCP is failed (we mark it as
failed when shmem cannot get initialized properly).
Reported-by: Abdul Haleem <abdhalee@linux.vnet.ibm.com>
Signed-off-by: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 4 ++--
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 14 +++++++++++++-
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 4c739d5355d2..8ae269ec17a1 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -3030,7 +3030,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link)
del_timer_sync(&bp->timer);
- if (IS_PF(bp)) {
+ if (IS_PF(bp) && !BP_NOMCP(bp)) {
/* Set ALWAYS_ALIVE bit in shmem */
bp->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE;
bnx2x_drv_pulse(bp);
@@ -3116,7 +3116,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link)
bp->cnic_loaded = false;
/* Clear driver version indication in shmem */
- if (IS_PF(bp))
+ if (IS_PF(bp) && !BP_NOMCP(bp))
bnx2x_update_mng_version(bp);
/* Check if there are pending parity attentions. If there are - set
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 91e2a7560b48..ddd5d3ebd201 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -9578,6 +9578,15 @@ static int bnx2x_init_shmem(struct bnx2x *bp)
do {
bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
+
+ /* If we read all 0xFFs, means we are in PCI error state and
+ * should bail out to avoid crashes on adapter's FW reads.
+ */
+ if (bp->common.shmem_base == 0xFFFFFFFF) {
+ bp->flags |= NO_MCP_FLAG;
+ return -ENODEV;
+ }
+
if (bp->common.shmem_base) {
val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
if (val & SHR_MEM_VALIDITY_MB)
@@ -14320,7 +14329,10 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
BNX2X_ERR("IO slot reset --> driver unload\n");
/* MCP should have been reset; Need to wait for validity */
- bnx2x_init_shmem(bp);
+ if (bnx2x_init_shmem(bp)) {
+ rtnl_unlock();
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) {
u32 v;
--
2.15.0
^ permalink raw reply related
* [PATCH net-next] net/trace: fix printk format in inet_sock_set_state
From: Yafang Shao @ 2017-12-22 15:37 UTC (permalink / raw)
To: davem; +Cc: netdev, Yafang Shao
There's a space character missed in the printk messages.
This error should be prevented with checkscript.pl, but it couldn't caught
by running with "checkscript.pl -f xxxx.patch", that's what I had run
before.
What a carelessness.
Fixes: 563e0bb0dc74("net: tracepoint: replace tcp_set_state tracepoint with
inet_sock_set_state tracepoint")
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
include/trace/events/sock.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/trace/events/sock.h b/include/trace/events/sock.h
index 3b9094a..598399da 100644
--- a/include/trace/events/sock.h
+++ b/include/trace/events/sock.h
@@ -160,7 +160,7 @@
}
),
- TP_printk("protocol=%s sport=%hu dport=%hu saddr=%pI4 daddr=%pI4"
+ TP_printk("protocol=%s sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 "
"saddrv6=%pI6c daddrv6=%pI6c oldstate=%s newstate=%s",
show_inet_protocol_name(__entry->protocol),
__entry->sport, __entry->dport,
^ permalink raw reply related
* [PATCH] stcp: Replace use of sockets_allocated with specified macro.
From: Tonghao Zhang @ 2017-12-22 15:40 UTC (permalink / raw)
To: glommer, eric.dumazet; +Cc: netdev, Tonghao Zhang
The patch(180d8cd942ce) replaces all uses of struct sock fields'
memory_pressure, memory_allocated, sockets_allocated, and sysctl_mem
to accessor macros. But the sockets_allocated field of sctp sock is
not replaced at all. Then replace it now for unifying the code.
Fixes: 180d8cd942ce ("foundations of per-cgroup memory pressure controlling.")
Cc: Glauber Costa <glommer@parallels.com>
Signed-off-by: Tonghao Zhang <zhangtonghao@didichuxing.com>
---
net/sctp/socket.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index aadcd4244d9b..a5e2150ab013 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4569,7 +4569,7 @@ static int sctp_init_sock(struct sock *sk)
SCTP_DBG_OBJCNT_INC(sock);
local_bh_disable();
- percpu_counter_inc(&sctp_sockets_allocated);
+ sk_sockets_allocated_inc(sk);
sock_prot_inuse_add(net, sk->sk_prot, 1);
/* Nothing can fail after this block, otherwise
@@ -4613,7 +4613,7 @@ static void sctp_destroy_sock(struct sock *sk)
}
sctp_endpoint_free(sp->ep);
local_bh_disable();
- percpu_counter_dec(&sctp_sockets_allocated);
+ sk_sockets_allocated_dec(sk);
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
local_bh_enable();
}
--
2.13.6
^ permalink raw reply related
* [PATCH] net: sch: api: fix tcf_block_get
From: Sudip Mukherjee @ 2017-12-22 15:52 UTC (permalink / raw)
To: Jamal Hadi Salim, Cong Wang, Jiri Pirko, David S. Miller
Cc: linux-kernel, netdev, Sudip Mukherjee
The build of mips bcm47xx_defconfig is failing with the error:
net/sched/sch_fq_codel.c: In function 'fq_codel_init':
net/sched/sch_fq_codel.c:487:8: error:
too many arguments to function 'tcf_block_get'
While adding the extack support, the commit missed adding it in the
headers when CONFIG_NET_CLS is not defined.
Fixes: 8d1a77f974ca ("net: sch: api: add extack support in tcf_block_get")
Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
---
The build log of next-20171222 is at:
https://travis-ci.org/sudipm-mukherjee/parport/jobs/320089922
include/net/pkt_cls.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 31574c9..5cd3cf5 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -79,7 +79,8 @@ int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
#else
static inline
int tcf_block_get(struct tcf_block **p_block,
- struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q)
+ struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
+ struct netlink_ext_ack *extack)
{
return 0;
}
--
2.1.4
^ permalink raw reply related
* [PATCH v2 bpf-next 1/2] tools/bpftool: use version from the kernel source tree
From: Roman Gushchin @ 2017-12-22 16:11 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel-team, Roman Gushchin, Jakub Kicinski,
Alexei Starovoitov, Daniel Borkmann
Bpftool determines it's own version based on the kernel
version, which is picked from the linux/version.h header.
It's strange to use the version of the installed kernel
headers, and makes much more sense to use the version
of the actual source tree, where bpftool sources are.
Fix this by building kernelversion target and use
the resulting string as bpftool version.
Example:
before:
$ bpftool version
bpftool v4.14.6
after:
$ bpftool version
bpftool v4.15.0-rc3
$bpftool version --json
{"version":"4.15.0-rc3"}
Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Jakub Kicinski <jakub.kicinski@netronome.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
---
tools/bpf/bpftool/Makefile | 3 +++
tools/bpf/bpftool/main.c | 13 ++-----------
2 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index 3f17ad317512..f8f31a8d9269 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -23,6 +23,8 @@ endif
LIBBPF = $(BPF_PATH)libbpf.a
+BPFTOOL_VERSION=$(shell make --no-print-directory -sC ../../.. kernelversion)
+
$(LIBBPF): FORCE
$(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(OUTPUT) $(OUTPUT)libbpf.a FEATURES_DUMP=$(FEATURE_DUMP_EXPORT)
@@ -38,6 +40,7 @@ CC = gcc
CFLAGS += -O2
CFLAGS += -W -Wall -Wextra -Wno-unused-parameter -Wshadow
CFLAGS += -D__EXPORTED_HEADERS__ -I$(srctree)/tools/include/uapi -I$(srctree)/tools/include -I$(srctree)/tools/lib/bpf -I$(srctree)/kernel/bpf/
+CFLAGS += -DBPFTOOL_VERSION='"$(BPFTOOL_VERSION)"'
LIBS = -lelf -lbfd -lopcodes $(LIBBPF)
INSTALL ?= install
diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
index ecd53ccf1239..3a0396d87c42 100644
--- a/tools/bpf/bpftool/main.c
+++ b/tools/bpf/bpftool/main.c
@@ -38,7 +38,6 @@
#include <errno.h>
#include <getopt.h>
#include <linux/bpf.h>
-#include <linux/version.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -95,21 +94,13 @@ static int do_help(int argc, char **argv)
static int do_version(int argc, char **argv)
{
- unsigned int version[3];
-
- version[0] = LINUX_VERSION_CODE >> 16;
- version[1] = LINUX_VERSION_CODE >> 8 & 0xf;
- version[2] = LINUX_VERSION_CODE & 0xf;
-
if (json_output) {
jsonw_start_object(json_wtr);
jsonw_name(json_wtr, "version");
- jsonw_printf(json_wtr, "\"%u.%u.%u\"",
- version[0], version[1], version[2]);
+ jsonw_printf(json_wtr, "\"%s\"", BPFTOOL_VERSION);
jsonw_end_object(json_wtr);
} else {
- printf("%s v%u.%u.%u\n", bin_name,
- version[0], version[1], version[2]);
+ printf("%s v%s\n", bin_name, BPFTOOL_VERSION);
}
return 0;
}
--
2.14.3
^ permalink raw reply related
* [PATCH v2 bpf-next 2/2] tools/bpftool: fix bpftool build with bintutils >= 2.8
From: Roman Gushchin @ 2017-12-22 16:11 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel-team, Roman Gushchin, Jakub Kicinski,
Alexei Starovoitov, Daniel Borkmann
In-Reply-To: <20171222161152.24715-1-guro@fb.com>
Bpftool build is broken with binutils version 2.28 and later.
The cause is commit 003ca0fd2286 ("Refactor disassembler selection")
in the binutils repo, which changed the disassembler() function
signature.
Fix this by adding a new "feature" to the tools/build/features
infrastructure and make it responsible for decision which
disassembler() function signature to use.
Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Jakub Kicinski <jakub.kicinski@netronome.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
---
tools/bpf/Makefile | 29 +++++++++++++++++++++++
tools/bpf/bpf_jit_disasm.c | 7 ++++++
tools/bpf/bpftool/Makefile | 24 +++++++++++++++++++
tools/bpf/bpftool/jit_disasm.c | 7 ++++++
tools/build/feature/Makefile | 4 ++++
tools/build/feature/test-disassembler-four-args.c | 15 ++++++++++++
6 files changed, 86 insertions(+)
create mode 100644 tools/build/feature/test-disassembler-four-args.c
diff --git a/tools/bpf/Makefile b/tools/bpf/Makefile
index 07a6697466ef..c8ec0ae16bf0 100644
--- a/tools/bpf/Makefile
+++ b/tools/bpf/Makefile
@@ -9,6 +9,35 @@ MAKE = make
CFLAGS += -Wall -O2
CFLAGS += -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+endif
+
+FEATURE_USER = .bpf
+FEATURE_TESTS = libbfd disassembler-four-args
+FEATURE_DISPLAY = libbfd disassembler-four-args
+
+check_feat := 1
+NON_CHECK_FEAT_TARGETS := clean bpftool_clean
+ifdef MAKECMDGOALS
+ifeq ($(filter-out $(NON_CHECK_FEAT_TARGETS),$(MAKECMDGOALS)),)
+ check_feat := 0
+endif
+endif
+
+ifeq ($(check_feat),1)
+ifeq ($(FEATURES_DUMP),)
+include $(srctree)/tools/build/Makefile.feature
+else
+include $(FEATURES_DUMP)
+endif
+endif
+
+ifeq ($(feature-disassembler-four-args), 1)
+CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE
+endif
+
%.yacc.c: %.y
$(YACC) -o $@ -d $<
diff --git a/tools/bpf/bpf_jit_disasm.c b/tools/bpf/bpf_jit_disasm.c
index 75bf526a0168..30044bc4f389 100644
--- a/tools/bpf/bpf_jit_disasm.c
+++ b/tools/bpf/bpf_jit_disasm.c
@@ -72,7 +72,14 @@ static void get_asm_insns(uint8_t *image, size_t len, int opcodes)
disassemble_init_for_target(&info);
+#ifdef DISASM_FOUR_ARGS_SIGNATURE
+ disassemble = disassembler(info.arch,
+ bfd_big_endian(bfdf),
+ info.mach,
+ bfdf);
+#else
disassemble = disassembler(bfdf);
+#endif
assert(disassemble);
do {
diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index f8f31a8d9269..2237bc43f71c 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -46,6 +46,30 @@ LIBS = -lelf -lbfd -lopcodes $(LIBBPF)
INSTALL ?= install
RM ?= rm -f
+FEATURE_USER = .bpftool
+FEATURE_TESTS = libbfd disassembler-four-args
+FEATURE_DISPLAY = libbfd disassembler-four-args
+
+check_feat := 1
+NON_CHECK_FEAT_TARGETS := clean uninstall doc doc-clean doc-install doc-uninstall
+ifdef MAKECMDGOALS
+ifeq ($(filter-out $(NON_CHECK_FEAT_TARGETS),$(MAKECMDGOALS)),)
+ check_feat := 0
+endif
+endif
+
+ifeq ($(check_feat),1)
+ifeq ($(FEATURES_DUMP),)
+include $(srctree)/tools/build/Makefile.feature
+else
+include $(FEATURES_DUMP)
+endif
+endif
+
+ifeq ($(feature-disassembler-four-args), 1)
+CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE
+endif
+
include $(wildcard *.d)
all: $(OUTPUT)bpftool
diff --git a/tools/bpf/bpftool/jit_disasm.c b/tools/bpf/bpftool/jit_disasm.c
index 1551d3918d4c..57d32e8a1391 100644
--- a/tools/bpf/bpftool/jit_disasm.c
+++ b/tools/bpf/bpftool/jit_disasm.c
@@ -107,7 +107,14 @@ void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes)
disassemble_init_for_target(&info);
+#ifdef DISASM_FOUR_ARGS_SIGNATURE
+ disassemble = disassembler(info.arch,
+ bfd_big_endian(bfdf),
+ info.mach,
+ bfdf);
+#else
disassemble = disassembler(bfdf);
+#endif
assert(disassemble);
if (json_output)
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 96982640fbf8..17f2c73fff8b 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -13,6 +13,7 @@ FILES= \
test-hello.bin \
test-libaudit.bin \
test-libbfd.bin \
+ test-disassembler-four-args.bin \
test-liberty.bin \
test-liberty-z.bin \
test-cplus-demangle.bin \
@@ -188,6 +189,9 @@ $(OUTPUT)test-libpython-version.bin:
$(OUTPUT)test-libbfd.bin:
$(BUILD) -DPACKAGE='"perf"' -lbfd -lz -liberty -ldl
+$(OUTPUT)test-disassembler-four-args.bin:
+ $(BUILD) -lbfd -lopcodes
+
$(OUTPUT)test-liberty.bin:
$(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty
diff --git a/tools/build/feature/test-disassembler-four-args.c b/tools/build/feature/test-disassembler-four-args.c
new file mode 100644
index 000000000000..45ce65cfddf0
--- /dev/null
+++ b/tools/build/feature/test-disassembler-four-args.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <bfd.h>
+#include <dis-asm.h>
+
+int main(void)
+{
+ bfd *abfd = bfd_openr(NULL, NULL);
+
+ disassembler(bfd_get_arch(abfd),
+ bfd_big_endian(abfd),
+ bfd_get_mach(abfd),
+ abfd);
+
+ return 0;
+}
--
2.14.3
^ permalink raw reply related
* [PATCH] stcp: Replace use of sockets_allocated with specified macro.
From: Tonghao Zhang @ 2017-12-22 16:27 UTC (permalink / raw)
To: netdev; +Cc: eric.dumazet, davem, Tonghao Zhang
The patch(180d8cd942ce) replaces all uses of struct sock fields'
memory_pressure, memory_allocated, sockets_allocated, and sysctl_mem
to accessor macros. But the sockets_allocated field of sctp sock is
not replaced at all. Then replace it now for unifying the code.
Fixes: 180d8cd942ce ("foundations of per-cgroup memory pressure controlling.")
Cc: Glauber Costa <glommer@parallels.com>
Signed-off-by: Tonghao Zhang <zhangtonghao@didichuxing.com>
---
net/sctp/socket.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index aadcd4244d9b..a5e2150ab013 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4569,7 +4569,7 @@ static int sctp_init_sock(struct sock *sk)
SCTP_DBG_OBJCNT_INC(sock);
local_bh_disable();
- percpu_counter_inc(&sctp_sockets_allocated);
+ sk_sockets_allocated_inc(sk);
sock_prot_inuse_add(net, sk->sk_prot, 1);
/* Nothing can fail after this block, otherwise
@@ -4613,7 +4613,7 @@ static void sctp_destroy_sock(struct sock *sk)
}
sctp_endpoint_free(sp->ep);
local_bh_disable();
- percpu_counter_dec(&sctp_sockets_allocated);
+ sk_sockets_allocated_dec(sk);
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
local_bh_enable();
}
--
2.13.6
^ permalink raw reply related
* [PATCH net 1/3] rds; Reset rs->rs_bound_addr in rds_add_bound() failure path
From: Sowmini Varadhan @ 2017-12-22 16:14 UTC (permalink / raw)
To: netdev; +Cc: davem, rds-devel, sowmini.varadhan, santosh.shilimkar
In-Reply-To: <cover.1513946398.git.sowmini.varadhan@oracle.com>
If the rds_sock is not added to the bind_hash_table, we must
reset rs_bound_addr so that rds_remove_bound will not trip on
this rds_sock.
rds_add_bound() does a rds_sock_put() in this failure path, so
failing to reset rs_bound_addr will result in a socket refcount
bug, and will trigger a WARN_ON with the stack shown below when
the application subsequently tries to close the PF_RDS socket.
WARNING: CPU: 20 PID: 19499 at net/rds/af_rds.c:496 \
rds_sock_destruct+0x15/0x30 [rds]
:
__sk_destruct+0x21/0x190
rds_remove_bound.part.13+0xb6/0x140 [rds]
rds_release+0x71/0x120 [rds]
sock_release+0x1a/0x70
sock_close+0xe/0x20
__fput+0xd5/0x210
task_work_run+0x82/0xa0
do_exit+0x2ce/0xb30
? syscall_trace_enter+0x1cc/0x2b0
do_group_exit+0x39/0xa0
SyS_exit_group+0x10/0x10
do_syscall_64+0x61/0x1a0
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
---
net/rds/bind.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/net/rds/bind.c b/net/rds/bind.c
index 75d43dc..5aa3a64 100644
--- a/net/rds/bind.c
+++ b/net/rds/bind.c
@@ -114,6 +114,7 @@ static int rds_add_bound(struct rds_sock *rs, __be32 addr, __be16 *port)
rs, &addr, (int)ntohs(*port));
break;
} else {
+ rs->rs_bound_addr = 0;
rds_sock_put(rs);
ret = -ENOMEM;
break;
--
1.7.1
^ permalink raw reply related
* [PATCH net 2/3] rds: tcp: initialize t_tcp_detached to false
From: Sowmini Varadhan @ 2017-12-22 16:14 UTC (permalink / raw)
To: netdev; +Cc: davem, rds-devel, sowmini.varadhan, santosh.shilimkar
In-Reply-To: <cover.1513946398.git.sowmini.varadhan@oracle.com>
Commit f10b4cff98c6 ("rds: tcp: atomically purge entries from
rds_tcp_conn_list during netns delete") adds the field t_tcp_detached,
but this needs to be initialized explicitly to false.
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
---
net/rds/tcp.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index 39f502d..a61a498 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -290,6 +290,7 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp)
tc->t_cpath = &conn->c_path[i];
spin_lock_irq(&rds_tcp_conn_lock);
+ tc->t_tcp_node_detached = false;
list_add_tail(&tc->t_tcp_node, &rds_tcp_conn_list);
spin_unlock_irq(&rds_tcp_conn_lock);
rdsdebug("rds_conn_path [%d] tc %p\n", i,
--
1.7.1
^ permalink raw reply related
* [PATCH net 3/3] rds: tcp: cleanup if kmem_cache_alloc fails in rds_tcp_conn_alloc()
From: Sowmini Varadhan @ 2017-12-22 16:14 UTC (permalink / raw)
To: netdev; +Cc: davem, rds-devel, sowmini.varadhan, santosh.shilimkar
In-Reply-To: <cover.1513946398.git.sowmini.varadhan@oracle.com>
If kmem_cache_alloc() fails in the middle of the for() loop,
cleanup anything that might have been allocated so far.
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
---
net/rds/tcp.c | 46 ++++++++++++++++++++++++++--------------------
1 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index a61a498..2e554ef 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -270,16 +270,33 @@ static int rds_tcp_laddr_check(struct net *net, __be32 addr)
return -EADDRNOTAVAIL;
}
+static void rds_tcp_conn_free(void *arg)
+{
+ struct rds_tcp_connection *tc = arg;
+ unsigned long flags;
+
+ rdsdebug("freeing tc %p\n", tc);
+
+ spin_lock_irqsave(&rds_tcp_conn_lock, flags);
+ if (!tc->t_tcp_node_detached)
+ list_del(&tc->t_tcp_node);
+ spin_unlock_irqrestore(&rds_tcp_conn_lock, flags);
+
+ kmem_cache_free(rds_tcp_conn_slab, tc);
+}
+
static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp)
{
struct rds_tcp_connection *tc;
- int i;
+ int i, j;
+ int ret = 0;
for (i = 0; i < RDS_MPATH_WORKERS; i++) {
tc = kmem_cache_alloc(rds_tcp_conn_slab, gfp);
- if (!tc)
- return -ENOMEM;
-
+ if (!tc) {
+ ret = -ENOMEM;
+ break;
+ }
mutex_init(&tc->t_conn_path_lock);
tc->t_sock = NULL;
tc->t_tinc = NULL;
@@ -296,22 +313,11 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp)
rdsdebug("rds_conn_path [%d] tc %p\n", i,
conn->c_path[i].cp_transport_data);
}
-
- return 0;
-}
-
-static void rds_tcp_conn_free(void *arg)
-{
- struct rds_tcp_connection *tc = arg;
- unsigned long flags;
- rdsdebug("freeing tc %p\n", tc);
-
- spin_lock_irqsave(&rds_tcp_conn_lock, flags);
- if (!tc->t_tcp_node_detached)
- list_del(&tc->t_tcp_node);
- spin_unlock_irqrestore(&rds_tcp_conn_lock, flags);
-
- kmem_cache_free(rds_tcp_conn_slab, tc);
+ if (ret) {
+ for (j = 0; j < i; j++)
+ rds_tcp_conn_free(conn->c_path[j].cp_transport_data);
+ }
+ return ret;
}
static bool list_has_conn(struct list_head *list, struct rds_connection *conn)
--
1.7.1
^ 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