* [PATCH 1/3] net: thunderx: Cleanup PHY probing code.
From: David Daney @ 2016-03-11 16:47 UTC (permalink / raw)
To: David S. Miller, netdev, linux-arm-kernel, Florian Fainelli,
Robert Richter, Sunil Goutham, Kumar Gala, Ian Campbell,
Mark Rutland, Pawel Moll, Rob Herring
Cc: linux-kernel, Radha Mohan Chintakuntla, David Daney
In-Reply-To: <1457714822-5754-1-git-send-email-ddaney.cavm@gmail.com>
From: David Daney <david.daney@cavium.com>
Remove the call to force the octeon-mdio driver to be loaded. Allow
the standard driver loading mechanisms to load the PHY drivers, and
use -EPROBE_DEFER to cause the BGX driver to be probed only after the
PHY drivers are available.
Reorder the setting of MAC addresses and PHY probing to allow BGX
LMACs with no attached PHY to still be assigned a MAC address.
Signed-off-by: David Daney <david.daney@cavium.com>
---
drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 31 ++++++++++++-----------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index f8abdff..928c02b 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -978,27 +978,31 @@ static int bgx_init_of_phy(struct bgx *bgx)
const char *mac;
device_for_each_child_node(&bgx->pdev->dev, fwn) {
+ struct phy_device *pd;
struct device_node *phy_np;
struct device_node *node = to_of_node(fwn);
- /* If it is not an OF node we cannot handle it yet, so
- * exit the loop.
- */
- if (!node)
- break;
-
- phy_np = of_parse_phandle(node, "phy-handle", 0);
- if (!phy_np)
- continue;
-
- bgx->lmac[lmac].phydev = of_phy_find_device(phy_np);
-
mac = of_get_mac_address(node);
if (mac)
ether_addr_copy(bgx->lmac[lmac].mac, mac);
SET_NETDEV_DEV(&bgx->lmac[lmac].netdev, &bgx->pdev->dev);
bgx->lmac[lmac].lmacid = lmac;
+
+ phy_np = of_parse_phandle(node, "phy-handle", 0);
+ /* If there is no phy or defective firmware presents
+ * this cortina phy, for which there is no driver
+ * support, ignore it.
+ */
+ if (phy_np &&
+ !of_device_is_compatible(phy_np, "cortina,cs4223-slice")) {
+ /* Wait until the phy drivers are available */
+ pd = of_phy_find_device(phy_np);
+ if (!pd)
+ return -EPROBE_DEFER;
+ bgx->lmac[lmac].phydev = pd;
+ }
+
lmac++;
if (lmac == MAX_LMAC_PER_BGX) {
of_node_put(node);
@@ -1032,9 +1036,6 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct bgx *bgx = NULL;
u8 lmac;
- /* Load octeon mdio driver */
- octeon_mdiobus_force_mod_depencency();
-
bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL);
if (!bgx)
return -ENOMEM;
--
1.7.11.7
^ permalink raw reply related
* [PATCH 0/3] net/phy: Improvements to Cavium Thunder MDIO code.
From: David Daney @ 2016-03-11 16:46 UTC (permalink / raw)
To: David S. Miller, netdev, linux-arm-kernel, Florian Fainelli,
Robert Richter, Sunil Goutham, Kumar Gala, Ian Campbell,
Mark Rutland, Pawel Moll, Rob Herring
Cc: linux-kernel, Radha Mohan Chintakuntla, David Daney
From: David Daney <david.daney@cavium.com>
The firmware on many Cavium Thunder systems configures the MDIO bus
hardware to be probed as a PCI device. In order to use the MDIO bus
drivers in this configuration, we must add PCI probing to the driver.
There are two parts to this set of three patches:
1) Cleanup the PHY probing code in thunder_bgx.c to handle the case
where there is no PHY attached to a port, as well as being more
robust in the face of driver loading order by use of
-EPROBE_DEFER.
2) Split mdio-octeon.c into two drivers, one with platform probing,
and the other with PCI probing. Common code is shared between the
two.
Tested on several different Thunder and OCTEON systems, also compile
tested on x86_64.
David Daney (3):
net: thunderx: Cleanup PHY probing code.
phy: mdio-octeon: Refactor into two files/modules
phy: mdio-thunder: Add driver for Cavium Thunder SoC MDIO buses.
.../devicetree/bindings/net/cavium-mdio.txt | 61 ++++-
drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 31 +--
drivers/net/phy/Kconfig | 22 +-
drivers/net/phy/Makefile | 2 +
drivers/net/phy/mdio-cavium.c | 149 +++++++++++
drivers/net/phy/mdio-cavium.h | 119 +++++++++
drivers/net/phy/mdio-octeon.c | 280 ++-------------------
drivers/net/phy/mdio-thunder.c | 154 ++++++++++++
8 files changed, 533 insertions(+), 285 deletions(-)
create mode 100644 drivers/net/phy/mdio-cavium.c
create mode 100644 drivers/net/phy/mdio-cavium.h
create mode 100644 drivers/net/phy/mdio-thunder.c
--
1.7.11.7
^ permalink raw reply
* Re: [PATCH] kcm: fix variable type
From: David Miller @ 2016-03-11 16:44 UTC (permalink / raw)
To: a.hajda; +Cc: tom, b.zolnierkie, m.szyprowski, netdev, linux-kernel
In-Reply-To: <1457679075-22094-1-git-send-email-a.hajda@samsung.com>
From: Andrzej Hajda <a.hajda@samsung.com>
Date: Fri, 11 Mar 2016 07:51:15 +0100
> Function skb_splice_bits can return negative values, its result should
> be assigned to signed variable to allow correct error checking.
>
> The problem has been detected using patch
> scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci.
>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Since skb_splice_bits() returns an 'int', that would be a more appropriate
type to use here.
Thank you.
^ permalink raw reply
* Re: net: use-after-free in recvmmsg
From: Dmitry Vyukov @ 2016-03-11 16:42 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: David S. Miller, netdev, LKML, Eric Dumazet, syzkaller,
Kostya Serebryany, Alexander Potapenko, Sasha Levin,
Arnaldo Carvalho de Melo
In-Reply-To: <20160310193107.GA2976@redhat.com>
On Thu, Mar 10, 2016 at 8:31 PM, Arnaldo Carvalho de Melo
<acme@redhat.com> wrote:
> Em Thu, Mar 10, 2016 at 07:35:57PM +0100, Dmitry Vyukov escreveu:
>> On Tue, Jan 26, 2016 at 8:30 PM, Arnaldo Carvalho de Melo
>> <acme@redhat.com> wrote:
>> > Em Tue, Jan 26, 2016 at 08:27:48PM +0100, Dmitry Vyukov escreveu:
>> >> On Fri, Jan 22, 2016 at 10:16 PM, Arnaldo Carvalho de Melo <acme@redhat.com> wrote:
>> >> > Em Fri, Jan 22, 2016 at 09:39:53PM +0100, Dmitry Vyukov escreveu:
>> >> >> I am on commit 30f05309bde49295e02e45c7e615f73aa4e0ccc2 (Jan 20).
>> >> >> Seems to be added in commit a2e2725541fad72416326798c2d7fa4dafb7d337
>> >> >> (Oct 2009).
>> >> >
>> >> > Maybe this helps? Compile testing now...
>> >>
>> >>
>> >> I don't have a reliable reproducer, so can't test it per se.
>> >> I will integrate this patch tomorrow and restart fuzzer with it.
>> >
>> > Thanks a lot!
>>
>> Hi Arnaldo,
>>
>> I am running with that patch since then, and did not see the bug.
>> Please mail it as a proper patch.
>
> Thanks, and I'll add a:
>
> Reported-and-Tested-by: Dmitry Vyukov <dvyukov@google.com>
>
> Ok?
Ok
Reported-and-Tested-by: Dmitry Vyukov <dvyukov@google.com>
^ permalink raw reply
* Re: [PATCH net v2 0/2] qlcnic fixes
From: David Miller @ 2016-03-11 16:41 UTC (permalink / raw)
To: rajesh.borundia; +Cc: netdev, Dept-GELinuxNICDev
In-Reply-To: <BN3PR11MB02730845402BE347A2F978848BB50@BN3PR11MB0273.namprd11.prod.outlook.com>
From: Rajesh Borundia <rajesh.borundia@qlogic.com>
Date: Fri, 11 Mar 2016 06:40:01 +0000
>>-----Original Message-----
>>From: David Miller [mailto:davem@davemloft.net]
>>Sent: Friday, March 11, 2016 2:47 AM
>>Let me know if you'd like me to therefore queue these changes up for -stable.
>>
> Please queue the changes for stable.
Done.
^ permalink raw reply
* Re: [v2, resend] b43: Fix memory leaks in b43_bus_dev_ssb_init and b43_bus_dev_bcma_init
From: Sudip Mukherjee @ 2016-03-11 16:22 UTC (permalink / raw)
To: Jia-Ju Bai
Cc: kvalo, zajec5, joe, davem, m, johannes.berg, linux-wireless,
b43-dev, netdev
In-Reply-To: <1452949690-16387-1-git-send-email-baijiaju1990@163.com>
On Sat, Jan 16, 2016 at 09:08:10PM +0800, Jia-Ju Bai wrote:
> The memory allocated by kzalloc in b43_bus_dev_ssb_init and
> b43_bus_dev_bcma_init is not freed.
> This patch fixes the bug by adding kfree in b43_ssb_remove,
> b43_bcma_remove and error handling code of b43_bcma_probe.
>
> Thanks Michael for his suggestion.
>
> Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
The patch did not apply cleanly. I had to edit the patch to point to
drivers/net/wireless/broadcom/b43/main.c
For CONFIG_B43_SSB part-
Tested-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
regards
sudip
^ permalink raw reply
* Re: userns, netns, and quick physical memory consumption by unprivileged user
From: Florian Westphal @ 2016-03-11 15:34 UTC (permalink / raw)
To: Yuriy M. Kaminskiy; +Cc: netdev, containers, linux-kernel
In-Reply-To: <m3r3fhhx4c.fsf@gmail.com>
Yuriy M. Kaminskiy <yumkam@gmail.com> wrote:
> BTW, all those hash/conntrack/etc default sizes was calculated from
> physical memory size in assumption there will be only *one* instance of
> those tables. Obviously, introduction of network namespaces (and
> especially unprivileged user-ns) thrown this assumption in the window
> (and here comes that "falling back to vmalloc" message again; in pre-netns
> world, those tables were allocated *once* on early system startup, with
> typically plenty of free and unfragmented memory).
No idea how to fix this expect by removing conntrack support in net
namespaces completely.
I'd disallow all write accesses to skb->nfct (NAT, CONNMARK,
CONNSECMARK, ...) and then no longer clear skb->nfct when forwarding
packet from init_ns to container.
Containers could then still test conntrack as seen from init namespace pov
in PREROUTING/FORWARD/INPUT (but not OUTPUT, obviously).
[ OUTPUT *might* be doable as well by allowing NEW creation in output
but skipping nat and deferring the confirmation/commit of the new
entry to the table until skb leaves initns ]
We could key conntrack entries to initns conntrack table
instead of adding one new table per netns, but seems like this only
replaces one problem with a new one (filling/blocking initns table from
another netns).
Maybe we could go with a compromise and skip/disallow conntrack in
unpriv userns only?
^ permalink raw reply
* Re: [PATCHv3 (net.git) 2/2] stmmac: fix MDIO settings
From: Giuseppe CAVALLARO @ 2016-03-11 15:32 UTC (permalink / raw)
To: Phil Reid, netdev
Cc: gabriel.fernandez, afaerber, fschaefer.oss, dinh.linux, davem
In-Reply-To: <56E2E0F2.7050506@electromag.com.au>
On 3/11/2016 4:14 PM, Phil Reid wrote:
> G'day Giuseppe,
>
> I wont be able to test until Monday.
> Concept looks ok to me except for comment below.
>
> On 11/03/2016 9:33 PM, Giuseppe Cavallaro wrote:
>> Initially the phy_bus_name was added to manipulate the
>> driver name but It was recently just used to manage the
>> fixed-link and then to take some decision at run-time
>> inside the main (for example to skip EEE).
>> So the patch uses the is_pseudo_fixed_link and removes
>> removes the phy_bus_name variable not necessary anymore.
>>
>> The driver can manage the mdio registration by using phy-handle,
>> dwmac-mdio and own parameter e.g. snps,phy-addr.
>> This patch takes care about all these possible configurations
>> and fixes the mdio registration in case of there is a real
>> transceiver or a switch (that needs to be managed by using
>> fixed-link).
>>
>> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
>> Reviewed-by: Andreas Färber <afaerber@suse.de>
>> Tested-by: Frank Schäfer <fschaefer.oss@googlemail.com>
>> Cc: Gabriel Fernandez <gabriel.fernandez@linaro.org>
>> Cc: Dinh Nguyen <dinh.linux@gmail.com>
>> Cc: David S. Miller <davem@davemloft.net>
>> Cc: Phil Reid <preid@electromag.com.au>
>> ---
>>
>> V2: use is_pseudo_fixed_link
>> V3: parse device-tree driver parameters to allocate PHY resources
>> considering
>> DSA case (+ fixed-link).
>>
>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 11 +--
>> drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 19 +-----
>> .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 77
>> ++++++++++++++++----
>> include/linux/stmmac.h | 2 +-
>> 4 files changed, 68 insertions(+), 41 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> index c21015b..389d7d0 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> @@ -271,7 +271,6 @@ static void stmmac_eee_ctrl_timer(unsigned long arg)
>> */
>> bool stmmac_eee_init(struct stmmac_priv *priv)
>> {
>> - char *phy_bus_name = priv->plat->phy_bus_name;
>> unsigned long flags;
>> bool ret = false;
>>
>> @@ -283,7 +282,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
>> goto out;
>>
>> /* Never init EEE in case of a switch is attached */
>> - if (phy_bus_name && (!strcmp(phy_bus_name, "fixed")))
>> + if (priv->phydev->is_pseudo_fixed_link)
>> goto out;
>>
>> /* MAC core supports the EEE feature. */
>> @@ -820,12 +819,8 @@ static int stmmac_init_phy(struct net_device *dev)
>> phydev = of_phy_connect(dev, priv->plat->phy_node,
>> &stmmac_adjust_link, 0, interface);
>> } else {
>> - if (priv->plat->phy_bus_name)
>> - snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
>> - priv->plat->phy_bus_name, priv->plat->bus_id);
>> - else
>> - snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
>> - priv->plat->bus_id);
>> + snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
>> + priv->plat->bus_id);
>>
>> snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
>> priv->plat->phy_addr);
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
>> b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
>> index 0faf163..3f5512f 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
>> @@ -198,29 +198,12 @@ int stmmac_mdio_register(struct net_device *ndev)
>> struct mii_bus *new_bus;
>> struct stmmac_priv *priv = netdev_priv(ndev);
>> struct stmmac_mdio_bus_data *mdio_bus_data =
>> priv->plat->mdio_bus_data;
>> + struct device_node *mdio_node = priv->plat->mdio_node;
>> int addr, found;
>> - struct device_node *mdio_node = NULL;
>> - struct device_node *child_node = NULL;
>>
>> if (!mdio_bus_data)
>> return 0;
>>
>> - if (IS_ENABLED(CONFIG_OF)) {
>> - for_each_child_of_node(priv->device->of_node, child_node) {
>> - if (of_device_is_compatible(child_node,
>> - "snps,dwmac-mdio")) {
>> - mdio_node = child_node;
>> - break;
>> - }
>> - }
>> -
>> - if (mdio_node) {
>> - netdev_dbg(ndev, "FOUND MDIO subnode\n");
>> - } else {
>> - netdev_warn(ndev, "No MDIO subnode found\n");
>> - }
>> - }
>> -
>> new_bus = mdiobus_alloc();
>> if (new_bus == NULL)
>> return -ENOMEM;
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
>> b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
>> index 6a52fa1..d2322e9 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
>> @@ -96,6 +96,66 @@ static int dwmac1000_validate_ucast_entries(int
>> ucast_entries)
>> }
>>
>> /**
>> + * stmmac_dt_phy - parse device-tree driver parameters to allocate
>> PHY resources
>> + * @plat: driver data platform structure
>> + * @np: device tree node
>> + * @dev: device pointer
>> + * Description:
>> + * The mdio bus will be allocated in case of a phy transceiver is on
>> board;
>> + * it will be NULL if the fixed-link is configured.
>> + * If there is the "snps,dwmac-mdio" sub-node the mdio will be allocated
>> + * in any case (for DSA, mdio must be registered even if fixed-link).
>> + * The table below sums the supported configurations:
>> + * -------------------------------
>> + * snps,phy-addr | Y
>> + * -------------------------------
>> + * phy-handle | Y
>> + * -------------------------------
>> + * fixed-link | N
>> + * -------------------------------
>> + * snps,dwmac-mdio |
>> + * even if | Y
>> + * fixed-link |
>> + * -------------------------------
>> + *
>> + * It returns true in case of the mdio needs to be registered in the
>> main.
>> + */
>> +static bool stmmac_dt_phy(struct plat_stmmacenet_data *plat,
>> + struct device_node *np, struct device *dev)
>> +{
>> + bool ret = true;
>> +
>> + /* If phy-handle property is passed from DT, use it as the PHY */
>> + plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
>> + if (plat->phy_node)
>> + dev_dbg(dev, "Found phy-handle subnode\n");
>> +
>> + /* If phy-handle is not specified, check if we have a fixed-phy */
>> + if (!plat->phy_node && of_phy_is_fixed_link(np)) {
>> + if ((of_phy_register_fixed_link(np) < 0))
>> + return -ENODEV;
>> +
>> + dev_dbg(dev, "Found fixed-link subnode\n");
>> + plat->phy_node = of_node_get(np);
>> +
>> + ret = false;
>> + }
>> +
>> + /* If snps,dwmac-mdio is passed from DT, always register the MDIO */
>> + for_each_child_of_node(np, plat->mdio_node) {
>> + if (of_device_is_compatible(plat->mdio_node, "snps,dwmac-mdio"))
>> + break;
>> + }
>> +
>
> Won't this always result in plat->mdio_node being assigned to something
> if np has a child.
> Regardless of the compatible string.
> Which is why I had the child_node temp.
> Still learning so may be missing something.
hmm, i think so, let me know as soon as you test it so I can
rework the patch and send a v4.
Thanks
peppe
>
>> + if (plat->mdio_node) {
>> + dev_dbg(dev, "Found MDIO subnode\n");
>> + ret = true;
>> + }
>> +
>> + return ret;
>> +}
>> +
>> +/**
>> * stmmac_probe_config_dt - parse device-tree driver parameters
>> * @pdev: platform_device structure
>> * @plat: driver data platform structure
>> @@ -129,30 +189,19 @@ stmmac_probe_config_dt(struct platform_device
>> *pdev, const char **mac)
>> /* Default to phy auto-detection */
>> plat->phy_addr = -1;
>>
>> - /* If we find a phy-handle property, use it as the PHY */
>> - plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
>> -
>> - /* If phy-handle is not specified, check if we have a fixed-phy */
>> - if (!plat->phy_node && of_phy_is_fixed_link(np)) {
>> - if ((of_phy_register_fixed_link(np) < 0))
>> - return ERR_PTR(-ENODEV);
>> -
>> - plat->phy_node = of_node_get(np);
>> - }
>> -
>> /* "snps,phy-addr" is not a standard property. Mark it as
>> deprecated
>> * and warn of its use. Remove this when phy node support is added.
>> */
>> if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr)
>> == 0)
>> dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
>>
>> - if ((plat->phy_node && !of_phy_is_fixed_link(np)) ||
>> plat->phy_bus_name)
>> - plat->mdio_bus_data = NULL;
>> - else
>> + /* To Configure PHY by using all device-tree supported properties */
>> + if (stmmac_dt_phy(plat, np, &pdev->dev)) {
>> plat->mdio_bus_data =
>> devm_kzalloc(&pdev->dev,
>> sizeof(struct stmmac_mdio_bus_data),
>> GFP_KERNEL);
>> + }
>>
>> of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size);
>>
>> diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
>> index eead8ab..8b1ff2b 100644
>> --- a/include/linux/stmmac.h
>> +++ b/include/linux/stmmac.h
>> @@ -94,12 +94,12 @@ struct stmmac_dma_cfg {
>> };
>>
>> struct plat_stmmacenet_data {
>> - char *phy_bus_name;
>> int bus_id;
>> int phy_addr;
>> int interface;
>> struct stmmac_mdio_bus_data *mdio_bus_data;
>> struct device_node *phy_node;
>> + struct device_node *mdio_node;
>> struct stmmac_dma_cfg *dma_cfg;
>> int clk_csr;
>> int has_gmac;
>>
>
>
^ permalink raw reply
* [PATCH net v3.16]r8169: Remove unsupported command on pci express
From: Corcodel Marian @ 2016-03-11 15:06 UTC (permalink / raw)
To: netdev; +Cc: Francois Romieu, Corcodel Marian
On pci express not support latency timer.For more info read file /drivers/pci/pci.c
on pcibios_set_master function.
Signed-off-by: Corcodel Marian <asd@marian1000.go.ro>
---
drivers/net/ethernet/realtek/r8169.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 41750df..02aec96 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -753,6 +753,7 @@ struct rtl8169_private {
struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */
struct timer_list timer;
u16 cp_cmd;
+ bool pcie;
u16 event_slow;
@@ -3757,8 +3758,8 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
RTL_W8(0x82, 0x01);
}
-
- pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
+ if (tp->pcie == 0)
+ pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08);
@@ -7083,8 +7084,11 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
tp->mmio_addr = ioaddr;
- if (!pci_is_pcie(pdev))
+ if (!pci_is_pcie(pdev)) {
netif_info(tp, probe, dev, "not PCI Express\n");
+ tp->pcie = 0;
+ } else
+ tp->pcie = 1;
/* Identify chip attached to board */
rtl8169_get_mac_version(tp, dev, cfg->default_ver);
--
2.1.4
^ permalink raw reply related
* Re: [PATCHv3 (net.git) 2/2] stmmac: fix MDIO settings
From: Phil Reid @ 2016-03-11 15:14 UTC (permalink / raw)
To: Giuseppe Cavallaro, netdev
Cc: gabriel.fernandez, afaerber, fschaefer.oss, dinh.linux, davem
In-Reply-To: <1457703196-15008-3-git-send-email-peppe.cavallaro@st.com>
G'day Giuseppe,
I wont be able to test until Monday.
Concept looks ok to me except for comment below.
On 11/03/2016 9:33 PM, Giuseppe Cavallaro wrote:
> Initially the phy_bus_name was added to manipulate the
> driver name but It was recently just used to manage the
> fixed-link and then to take some decision at run-time
> inside the main (for example to skip EEE).
> So the patch uses the is_pseudo_fixed_link and removes
> removes the phy_bus_name variable not necessary anymore.
>
> The driver can manage the mdio registration by using phy-handle,
> dwmac-mdio and own parameter e.g. snps,phy-addr.
> This patch takes care about all these possible configurations
> and fixes the mdio registration in case of there is a real
> transceiver or a switch (that needs to be managed by using
> fixed-link).
>
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> Reviewed-by: Andreas Färber <afaerber@suse.de>
> Tested-by: Frank Schäfer <fschaefer.oss@googlemail.com>
> Cc: Gabriel Fernandez <gabriel.fernandez@linaro.org>
> Cc: Dinh Nguyen <dinh.linux@gmail.com>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: Phil Reid <preid@electromag.com.au>
> ---
>
> V2: use is_pseudo_fixed_link
> V3: parse device-tree driver parameters to allocate PHY resources considering
> DSA case (+ fixed-link).
>
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 11 +--
> drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 19 +-----
> .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 77 ++++++++++++++++----
> include/linux/stmmac.h | 2 +-
> 4 files changed, 68 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index c21015b..389d7d0 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -271,7 +271,6 @@ static void stmmac_eee_ctrl_timer(unsigned long arg)
> */
> bool stmmac_eee_init(struct stmmac_priv *priv)
> {
> - char *phy_bus_name = priv->plat->phy_bus_name;
> unsigned long flags;
> bool ret = false;
>
> @@ -283,7 +282,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
> goto out;
>
> /* Never init EEE in case of a switch is attached */
> - if (phy_bus_name && (!strcmp(phy_bus_name, "fixed")))
> + if (priv->phydev->is_pseudo_fixed_link)
> goto out;
>
> /* MAC core supports the EEE feature. */
> @@ -820,12 +819,8 @@ static int stmmac_init_phy(struct net_device *dev)
> phydev = of_phy_connect(dev, priv->plat->phy_node,
> &stmmac_adjust_link, 0, interface);
> } else {
> - if (priv->plat->phy_bus_name)
> - snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
> - priv->plat->phy_bus_name, priv->plat->bus_id);
> - else
> - snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
> - priv->plat->bus_id);
> + snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
> + priv->plat->bus_id);
>
> snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
> priv->plat->phy_addr);
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
> index 0faf163..3f5512f 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
> @@ -198,29 +198,12 @@ int stmmac_mdio_register(struct net_device *ndev)
> struct mii_bus *new_bus;
> struct stmmac_priv *priv = netdev_priv(ndev);
> struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
> + struct device_node *mdio_node = priv->plat->mdio_node;
> int addr, found;
> - struct device_node *mdio_node = NULL;
> - struct device_node *child_node = NULL;
>
> if (!mdio_bus_data)
> return 0;
>
> - if (IS_ENABLED(CONFIG_OF)) {
> - for_each_child_of_node(priv->device->of_node, child_node) {
> - if (of_device_is_compatible(child_node,
> - "snps,dwmac-mdio")) {
> - mdio_node = child_node;
> - break;
> - }
> - }
> -
> - if (mdio_node) {
> - netdev_dbg(ndev, "FOUND MDIO subnode\n");
> - } else {
> - netdev_warn(ndev, "No MDIO subnode found\n");
> - }
> - }
> -
> new_bus = mdiobus_alloc();
> if (new_bus == NULL)
> return -ENOMEM;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> index 6a52fa1..d2322e9 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> @@ -96,6 +96,66 @@ static int dwmac1000_validate_ucast_entries(int ucast_entries)
> }
>
> /**
> + * stmmac_dt_phy - parse device-tree driver parameters to allocate PHY resources
> + * @plat: driver data platform structure
> + * @np: device tree node
> + * @dev: device pointer
> + * Description:
> + * The mdio bus will be allocated in case of a phy transceiver is on board;
> + * it will be NULL if the fixed-link is configured.
> + * If there is the "snps,dwmac-mdio" sub-node the mdio will be allocated
> + * in any case (for DSA, mdio must be registered even if fixed-link).
> + * The table below sums the supported configurations:
> + * -------------------------------
> + * snps,phy-addr | Y
> + * -------------------------------
> + * phy-handle | Y
> + * -------------------------------
> + * fixed-link | N
> + * -------------------------------
> + * snps,dwmac-mdio |
> + * even if | Y
> + * fixed-link |
> + * -------------------------------
> + *
> + * It returns true in case of the mdio needs to be registered in the main.
> + */
> +static bool stmmac_dt_phy(struct plat_stmmacenet_data *plat,
> + struct device_node *np, struct device *dev)
> +{
> + bool ret = true;
> +
> + /* If phy-handle property is passed from DT, use it as the PHY */
> + plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
> + if (plat->phy_node)
> + dev_dbg(dev, "Found phy-handle subnode\n");
> +
> + /* If phy-handle is not specified, check if we have a fixed-phy */
> + if (!plat->phy_node && of_phy_is_fixed_link(np)) {
> + if ((of_phy_register_fixed_link(np) < 0))
> + return -ENODEV;
> +
> + dev_dbg(dev, "Found fixed-link subnode\n");
> + plat->phy_node = of_node_get(np);
> +
> + ret = false;
> + }
> +
> + /* If snps,dwmac-mdio is passed from DT, always register the MDIO */
> + for_each_child_of_node(np, plat->mdio_node) {
> + if (of_device_is_compatible(plat->mdio_node, "snps,dwmac-mdio"))
> + break;
> + }
> +
Won't this always result in plat->mdio_node being assigned to something if np has a child.
Regardless of the compatible string.
Which is why I had the child_node temp.
Still learning so may be missing something.
> + if (plat->mdio_node) {
> + dev_dbg(dev, "Found MDIO subnode\n");
> + ret = true;
> + }
> +
> + return ret;
> +}
> +
> +/**
> * stmmac_probe_config_dt - parse device-tree driver parameters
> * @pdev: platform_device structure
> * @plat: driver data platform structure
> @@ -129,30 +189,19 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
> /* Default to phy auto-detection */
> plat->phy_addr = -1;
>
> - /* If we find a phy-handle property, use it as the PHY */
> - plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
> -
> - /* If phy-handle is not specified, check if we have a fixed-phy */
> - if (!plat->phy_node && of_phy_is_fixed_link(np)) {
> - if ((of_phy_register_fixed_link(np) < 0))
> - return ERR_PTR(-ENODEV);
> -
> - plat->phy_node = of_node_get(np);
> - }
> -
> /* "snps,phy-addr" is not a standard property. Mark it as deprecated
> * and warn of its use. Remove this when phy node support is added.
> */
> if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
> dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
>
> - if ((plat->phy_node && !of_phy_is_fixed_link(np)) || plat->phy_bus_name)
> - plat->mdio_bus_data = NULL;
> - else
> + /* To Configure PHY by using all device-tree supported properties */
> + if (stmmac_dt_phy(plat, np, &pdev->dev)) {
> plat->mdio_bus_data =
> devm_kzalloc(&pdev->dev,
> sizeof(struct stmmac_mdio_bus_data),
> GFP_KERNEL);
> + }
>
> of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size);
>
> diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
> index eead8ab..8b1ff2b 100644
> --- a/include/linux/stmmac.h
> +++ b/include/linux/stmmac.h
> @@ -94,12 +94,12 @@ struct stmmac_dma_cfg {
> };
>
> struct plat_stmmacenet_data {
> - char *phy_bus_name;
> int bus_id;
> int phy_addr;
> int interface;
> struct stmmac_mdio_bus_data *mdio_bus_data;
> struct device_node *phy_node;
> + struct device_node *mdio_node;
> struct stmmac_dma_cfg *dma_cfg;
> int clk_csr;
> int has_gmac;
>
--
Regards
Phil Reid
^ permalink raw reply
* [PATCH] net: socket: use pr_info_once to tip the obsolete usage of PF_PACKET
From: liping.zhang @ 2016-03-11 15:08 UTC (permalink / raw)
To: davem, netdev, linux-kernel; +Cc: liping.zhang
From: "liping.zhang" <liping.zhang@spreadtrum.com>
There is no need to use the static variable here, pr_info_once is more
concise.
Signed-off-by: Liping Zhang <liping.zhang@spreadtrum.com>
---
net/socket.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/net/socket.c b/net/socket.c
index c044d1e..c499784 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1106,12 +1106,8 @@ int __sock_create(struct net *net, int family, int type, int protocol,
deadlock in module load.
*/
if (family == PF_INET && type == SOCK_PACKET) {
- static int warned;
- if (!warned) {
- warned = 1;
- pr_info("%s uses obsolete (PF_INET,SOCK_PACKET)\n",
- current->comm);
- }
+ pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)\n",
+ current->comm);
family = PF_PACKET;
}
--
1.7.9.5
^ permalink raw reply related
* Re: userns, netns, and quick physical memory consumption by unprivileged user
From: Yuriy M. Kaminskiy @ 2016-03-11 15:06 UTC (permalink / raw)
To: netdev; +Cc: containers, linux-kernel
In-Reply-To: <m3d1rclioc.fsf@gmail.com>
ping (+ more test results at bottom)
On Wed, 02 Mar 2016, I wrote:
> While looking at CVE-2016-2847, I remembered about infamous
> nf_conntrack: falling back to vmalloc
> message, that was often triggered by network namespace creation (message
> was removed recently, but it changed nothing with underlying problem).
>
> So, how about something like this:
>
> $ cat << EOF >> eatphysmem
> #!/bin/bash -xe
> fd=6
> d="`mktemp -d /tmp/eatmemXXXXXXXXX`"
> cd "$d"
> rule="iptables -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT"
> # rule="$rule;$rule"
> # ... just because we can; same with any number of ip li/ro/ru/etc
> while :; do
> let fd=fd+1
> [ ! -e /proc/$$/fd/$fd ] || continue
> mkfifo f1 f2
> unshare -rn sh -xec "echo foo >f1;ip li se lo up; $rule;read r <f2" &
> pid=$!
> read r <f1
> eval "exec $fd</proc/$pid/ns/net"
> echo bar >f2
> wait
> rm f2 f1
> free
> sleep 0.1s
> done
> sleep inf
> EOF
> $ chmod a+x eatphysmem; unshare -rpf --mount-proc ./eatphysmem
> ?
>
> You can easily eat 0.5M physical memory per netns (conntrack hash table
> (hashsize*sizeof(list_head))) and more, and pin them to single process
> with opened netns fds.
> What can stop it?
> ulimit? What is ulimit? Conntrack knows nothing about them.
> Ah-yeah, `ulimit -n`? 64k. 64k*512k = 32G. Per process. Oh-uh.
> OOM killer? But this is not this process memory; if any, it will be
> killed last.
> (I wonder, if memcg can tackle it; probably yes; but how many people
> have it configured?).
I tested in vm with kernel 4.4.2 (from user account, with ulimit
-v 32768); as expected, it quickly eaten all memory, OOM killer went
berserk and killed even systemd-journald and systemd-udevd, but left
this process living (and hogging all physical memory; also note that
swap was enabled - and mostly remained unused).
And also tried with memcg:
t=/sys/fs/cgroup/memory/test1;mkdir $t;echo 0 >$t/tasks;
echo 48M >$t/memory.limit_in_bytes; su testuser [...]
and it has not helped at all (rather opposite, it ended up with killed
init and kernel panic; well, later is pure (un)luck; but point is, memcg
apparently *CANNOT* curb net/ns allocations).
BTW, all those hash/conntrack/etc default sizes was calculated from
physical memory size in assumption there will be only *one* instance of
those tables. Obviously, introduction of network namespaces (and
especially unprivileged user-ns) thrown this assumption in the window
(and here comes that "falling back to vmalloc" message again; in pre-netns
world, those tables were allocated *once* on early system startup, with
typically plenty of free and unfragmented memory).
^ permalink raw reply
* Re: [PATCH 3/6] net: arc_emac: support the phy reset for emac driver
From: Heiko Stübner @ 2016-03-11 14:59 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: Caesar Wang, David S. Miller, Rob Herring, linux-rockchip,
keescook, leozwang, Alexander Kochetkov, netdev, linux-kernel
In-Reply-To: <2693723.gBjS0iQk4I@diego>
Am Freitag, 11. März 2016, 15:56:04 schrieb Heiko Stübner:
> Hi Caesar,
>
> Am Freitag, 11. März 2016, 16:47:59 schrieb Sergei Shtylyov:
> > On 3/11/2016 1:55 PM, Caesar Wang wrote:
> > > This patch adds to support the emac phy reset.
> > >
> > > 1) phy-reset-gpios:
> > > The phy-reset-gpios is an optional property for arc emac device tree
> > > boot.
> > > Change the binding document to match the driver code.
> > >
> > > 2) phy-reset-duration:
> > > Different boards may require different phy reset duration. Add property
> > > phy-reset-duration for device tree probe, so that the boards that need
> > > a longer reset duration can specify it in their device tree.
> > >
> > > 3) phy-reset-active-high:
> > > We need that for a custom hardware that needs the reverse reset
> > > sequence.
> > >
> > > Of course, this patch will fix the issue on
> > > https://patchwork.kernel.org/patch/8186801/.
> > >
> > > In some cases, the emac couldn't work if you don't have reset the phy.
> > > Let's add it to happy work.
> > >
> > > Signed-off-by: Caesar Wang <wxt@rock-chips.com>
> > > ---
> > >
> > > drivers/net/ethernet/arc/emac_main.c | 41
> > > ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
> > >
> > > diff --git a/drivers/net/ethernet/arc/emac_main.c
> > > b/drivers/net/ethernet/arc/emac_main.c index 6446af1..42384f6a 100644
> > > --- a/drivers/net/ethernet/arc/emac_main.c
> > > +++ b/drivers/net/ethernet/arc/emac_main.c
> > > @@ -764,6 +764,45 @@ static const struct net_device_ops
> > > arc_emac_netdev_ops = {>
> > >
> > > #endif
> > > };
> > >
> > > +#ifdef CONFIG_OF
> > > +static void emac_reset_phy(struct net_device *pdev)
> > > +{
> > > + int err, phy_reset;
> > > + bool active_high = false;
> > > + int msec = 10;
> > > + struct device *dev = pdev->dev.parent;
> > > + struct device_node *np = dev->of_node;
> > > +
> > > + if (!np)
> > > + return;
> > > +
> > > + of_property_read_u32(np, "phy-reset-duration", &msec);
> > > + /* A sane reset duration should not be longer than 1s */
> > > + if (msec > 1000)
> > > + msec = 1;
> > > +
> > > + phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
> > > + if (!gpio_is_valid(phy_reset))
> > > + return;
> > > +
> > > + active_high = of_property_read_bool(np, "phy-reset-active-high");
> > > +
> > > + err = devm_gpio_request_one(dev, phy_reset, active_high ?
> > > + GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
> > > + "phy-reset");
> > > + if (err) {
> > > + dev_err(dev, "failed to get phy-reset-gpios: %d\n", err);
> > > + return;
> > > + }
> > > + msleep(msec);
> > > + gpio_set_value_cansleep(phy_reset, !active_high);
> > > +}
> >
> > [...]
> >
> > Why not make it the mii_bus::reset() method? It gets called before the
> >
> > MDIO bus scan.
>
> while meddling with the emac, I've built some sort of preliminary variant of
> Sergei's suggestion at [0] - maybe you could take a look for some sort of
> inspiration ;-)
forgot to add ... of course the newer gpiod_* infrastructure should be used
instead of the old integer-based gpio numbers
>
> The code is lifted from the designware gmac driver, so the binding also is
> similar.
>
>
> Heiko
>
>
> [0]
> https://github.com/mmind/linux-rockchip/commit/a943c588783438ff1c508dfa8c79
> f1709aa5775e
^ permalink raw reply
* Re: [PATCH 3/6] net: arc_emac: support the phy reset for emac driver
From: Heiko Stübner @ 2016-03-11 14:56 UTC (permalink / raw)
To: Sergei Shtylyov, Caesar Wang
Cc: David S. Miller, Rob Herring, linux-rockchip, keescook, leozwang,
Alexander Kochetkov, netdev, linux-kernel
In-Reply-To: <56E2CC8F.5040703@cogentembedded.com>
Hi Caesar,
Am Freitag, 11. März 2016, 16:47:59 schrieb Sergei Shtylyov:
> On 3/11/2016 1:55 PM, Caesar Wang wrote:
> > This patch adds to support the emac phy reset.
> >
> > 1) phy-reset-gpios:
> > The phy-reset-gpios is an optional property for arc emac device tree boot.
> > Change the binding document to match the driver code.
> >
> > 2) phy-reset-duration:
> > Different boards may require different phy reset duration. Add property
> > phy-reset-duration for device tree probe, so that the boards that need
> > a longer reset duration can specify it in their device tree.
> >
> > 3) phy-reset-active-high:
> > We need that for a custom hardware that needs the reverse reset sequence.
> >
> > Of course, this patch will fix the issue on
> > https://patchwork.kernel.org/patch/8186801/.
> >
> > In some cases, the emac couldn't work if you don't have reset the phy.
> > Let's add it to happy work.
> >
> > Signed-off-by: Caesar Wang <wxt@rock-chips.com>
> > ---
> >
> > drivers/net/ethernet/arc/emac_main.c | 41
> > ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
> >
> > diff --git a/drivers/net/ethernet/arc/emac_main.c
> > b/drivers/net/ethernet/arc/emac_main.c index 6446af1..42384f6a 100644
> > --- a/drivers/net/ethernet/arc/emac_main.c
> > +++ b/drivers/net/ethernet/arc/emac_main.c
> > @@ -764,6 +764,45 @@ static const struct net_device_ops
> > arc_emac_netdev_ops = {>
> > #endif
> > };
> >
> > +#ifdef CONFIG_OF
> > +static void emac_reset_phy(struct net_device *pdev)
> > +{
> > + int err, phy_reset;
> > + bool active_high = false;
> > + int msec = 10;
> > + struct device *dev = pdev->dev.parent;
> > + struct device_node *np = dev->of_node;
> > +
> > + if (!np)
> > + return;
> > +
> > + of_property_read_u32(np, "phy-reset-duration", &msec);
> > + /* A sane reset duration should not be longer than 1s */
> > + if (msec > 1000)
> > + msec = 1;
> > +
> > + phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
> > + if (!gpio_is_valid(phy_reset))
> > + return;
> > +
> > + active_high = of_property_read_bool(np, "phy-reset-active-high");
> > +
> > + err = devm_gpio_request_one(dev, phy_reset, active_high ?
> > + GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
> > + "phy-reset");
> > + if (err) {
> > + dev_err(dev, "failed to get phy-reset-gpios: %d\n", err);
> > + return;
> > + }
> > + msleep(msec);
> > + gpio_set_value_cansleep(phy_reset, !active_high);
> > +}
>
> [...]
>
> Why not make it the mii_bus::reset() method? It gets called before the
> MDIO bus scan.
while meddling with the emac, I've built some sort of preliminary variant of
Sergei's suggestion at [0] - maybe you could take a look for some sort of
inspiration ;-)
The code is lifted from the designware gmac driver, so the binding also is
similar.
Heiko
[0] https://github.com/mmind/linux-rockchip/commit/a943c588783438ff1c508dfa8c79f1709aa5775e
^ permalink raw reply
* Re: [PATCH 0/6] arc_emac: fixes the emac issues oand cleanup emac drivers
From: Caesar Wang @ 2016-03-11 14:48 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: Caesar Wang, Heiko Stuebner, David S. Miller, Rob Herring,
Mark Rutland, devicetree, Ian Campbell, Russell King, Pawel Moll,
zhengxing, Alexander Kochetkov, netdev, Michael Turquette,
Kumar Gala, Stephen Boyd, linux-kernel, linux-rockchip,
linux-arm-kernel, keescook, Jiri Kosina, linux-clk, leozwang
In-Reply-To: <56E2CC39.6050907@cogentembedded.com>
Hi Sergei,
在 2016年03月11日 21:46, Sergei Shtylyov 写道:
> Hello.
>
> On 3/11/2016 1:55 PM, Caesar Wang wrote:
>
>> This series patches are based on kernel 4.5-rc7+ version.
>> Linux version 4.5.0-rc7-next-20160310+ (wxt@nb) (...) #23 SMP Fri Mar
>> 11 15:55:53
>
> [...]
>
>> 1) This series has 6 patches: (1--->6)
>> net: arc_emac: make the rockchip emac document more compatible
>> net: arc_emac: add phy-reset-* are optional for device tree
>
> I'm not seeing these patches on netdev...
Sent by the patman tool.
LKML:
https://patchwork.kernel.org/patch/8564501/
https://patchwork.kernel.org/patch/8564511/
>
>> net: arc_emac: support the phy reset for emac driver
>> net: arc: trivial: cleanup the emac driver
>> clk: rockchip: rk3036: fix and add node id for emac clock
>> ARM: dts: rockchip: add support emac for RK3036
>>
>> 2) This series patches have the following decriptions:
>
> Descriptions.
>
>> Hi Rob, David:
>> PATCH[1/6-2/6]: ====>
>> net: arc_emac: make the rockchip emac document more compatible
>> net: arc_emac: add phy-reset-* are optional for device tree
>>
>> The patches change the rockchip emac document for more compatible and
>> Add the phy-reset-* property for document.
>>
>> This patch adds the following property for arc_emac.
>>
>> phy-reset-* include the following:
>> 1) phy-reset-gpios:
>> The phy-reset-gpios is an optional property for arc emac device tree
>> boot.
>> Change the binding document to match the driver code.
>>
>> 2) phy-reset-duration:
>> Different boards may require different phy reset duration. Add property
>> phy-reset-duration for device tree probe, so that the boards that need
>> a longer reset duration can specify it in their device tree.
>>
>> 3) phy-reset-active-high:
>> We need that for a custom hardware that needs the reverse reset
>> sequence.
>
> Why not infer this from the "phy-reset-gpios" prop?
See:
https://patchwork.kernel.org/patch/8564511/
phy-reset-active-high : If present then the reset sequence using the GPIO
specified in the "phy-reset-gpios" property is reversed (H=reset state,
L=operation state).
Thanks,
Caesar
>
> MBR, Sergei
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* Re: [net-next RFC 0/4] SO_BINDTOSUBNET
From: Gilberto Bertin @ 2016-03-11 14:43 UTC (permalink / raw)
To: Tom Herbert; +Cc: Linux Kernel Network Developers
In-Reply-To: <CALx6S35UMTif0pFMKLV4Ks8hVkb9L-=571pURbGkXEux4VJfyA@mail.gmail.com>
> On 7 Mar 2016, at 17:49, Tom Herbert <tom@herbertland.com> wrote:
>
>> That said, do you believe it could be an option to maybe have both these
>> options? I think that the ability to run BPF in the listening path is
>> really interesting, but it's probably an overkill for the bind-to-subnet
>> use case.
>>
>
> Maybe. It will be quite common server configuration with IPv6 to
> assign each server its own /64 prefix(es). From that POV I suppose
> there is some value in having SO_BINDTOSUBNET.
Good, in this case I will submit again this RFC when the net-next window
will open for the 4.6 release, so that we can gather more comments and
decide what to do.
Thank you,
Gilberto
^ permalink raw reply
* [PATCH] at803x: fix suspend/resume for SGMII link
From: Zefir Kurtisi @ 2016-03-11 14:31 UTC (permalink / raw)
To: netdev; +Cc: Florian Fainelli, chunkeey
When operating the at803x in SGMII mode, resuming the chip
from power down brings up the copper-side link but leaves
the SGMII link in unconnected state (tested with at8031
attached to gianfar). In effect, this caused a permanent
link loss once the related interface was put down.
This patch ensures that power down handling in supspend()
and resume() is also applied to the SGMII link.
Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
---
drivers/net/phy/at803x.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 2174ec9..1e901c7 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -52,6 +52,9 @@
#define AT803X_DEBUG_REG_5 0x05
#define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8)
+#define AT803X_REG_CHIP_CONFIG 0x1f
+#define AT803X_BT_BX_REG_SEL 0x8000
+
#define ATH8030_PHY_ID 0x004dd076
#define ATH8031_PHY_ID 0x004dd074
#define ATH8035_PHY_ID 0x004dd072
@@ -206,6 +209,7 @@ static int at803x_suspend(struct phy_device *phydev)
{
int value;
int wol_enabled;
+ int ccr;
mutex_lock(&phydev->lock);
@@ -221,6 +225,16 @@ static int at803x_suspend(struct phy_device *phydev)
phy_write(phydev, MII_BMCR, value);
+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII)
+ goto done;
+
+ /* also power-down SGMII interface */
+ ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
+ phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr & ~AT803X_BT_BX_REG_SEL);
+ phy_write(phydev, MII_BMCR, phy_read(phydev, MII_BMCR) | BMCR_PDOWN);
+ phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL);
+
+done:
mutex_unlock(&phydev->lock);
return 0;
@@ -229,6 +243,7 @@ static int at803x_suspend(struct phy_device *phydev)
static int at803x_resume(struct phy_device *phydev)
{
int value;
+ int ccr;
mutex_lock(&phydev->lock);
@@ -236,6 +251,17 @@ static int at803x_resume(struct phy_device *phydev)
value &= ~(BMCR_PDOWN | BMCR_ISOLATE);
phy_write(phydev, MII_BMCR, value);
+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII)
+ goto done;
+
+ /* also power-up SGMII interface */
+ ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
+ phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr & ~AT803X_BT_BX_REG_SEL);
+ value = phy_read(phydev, MII_BMCR) & ~(BMCR_PDOWN | BMCR_ISOLATE);
+ phy_write(phydev, MII_BMCR, value);
+ phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL);
+
+done:
mutex_unlock(&phydev->lock);
return 0;
--
2.7.0
^ permalink raw reply related
* Re: [PATCH net-next 08/13] net/mlx5e: Add fragmented memory support for RX multi packet WQE
From: Eric Dumazet @ 2016-03-11 14:32 UTC (permalink / raw)
To: Saeed Mahameed
Cc: David S. Miller, netdev, Or Gerlitz, Eran Ben Elisha, Tal Alon,
Tariq Toukan, Jesper Dangaard Brouer
In-Reply-To: <1457703594-9482-9-git-send-email-saeedm@mellanox.com>
On ven., 2016-03-11 at 15:39 +0200, Saeed Mahameed wrote:
> From: Tariq Toukan <tariqt@mellanox.com>
>
> If the allocation of a linear (physically continuous) MPWQE fails,
> we allocate a fragmented MPWQE.
>
> This is implemented via device's UMR (User Memory Registration)
> which allows to register multiple memory fragments into ConnectX
> hardware as a continuous buffer.
> UMR registration is an asynchronous operation and is done via
> ICO SQs.
>
...
> +static int mlx5e_alloc_and_map_page(struct mlx5e_rq *rq,
> + struct mlx5e_mpw_info *wi,
> + int i)
> +{
> + struct page *page;
> +
> + page = alloc_page(GFP_ATOMIC | __GFP_COMP | __GFP_COLD);
> + if (!page)
> + return -ENOMEM;
> +
> + wi->umr.dma_info[i].page = page;
> + wi->umr.dma_info[i].addr = dma_map_page(rq->pdev, page, 0, PAGE_SIZE,
> + PCI_DMA_FROMDEVICE);
> + if (dma_mapping_error(rq->pdev, wi->umr.dma_info[i].addr)) {
> + put_page(page);
> + return -ENOMEM;
> + }
> + wi->umr.mtt[i] = cpu_to_be64(wi->umr.dma_info[i].addr | MLX5_EN_WR);
> +
> + return 0;
> +}
> +
> +static int mlx5e_alloc_rx_fragmented_mpwqe(struct mlx5e_rq *rq,
> + struct mlx5e_rx_wqe *wqe,
> + u16 ix)
> +{
> + struct mlx5e_mpw_info *wi = &rq->wqe_info[ix];
> + int mtt_sz = mlx5e_get_wqe_mtt_sz();
> + u32 dma_offset = rq->ix * MLX5_CHANNEL_MAX_NUM_PAGES * PAGE_SIZE +
> + ix * rq->wqe_sz;
> + int i;
> +
> + wi->umr.dma_info = kmalloc(sizeof(*wi->umr.dma_info) *
> + MLX5_MPWRQ_WQE_NUM_PAGES,
> + GFP_ATOMIC | __GFP_COMP | __GFP_COLD);
> + if (!wi->umr.dma_info)
> + goto err_out;
> +
> + /* To avoid copying garbage after the mtt array, we allocate
> + * a little more.
> + */
> + wi->umr.mtt = kzalloc(mtt_sz + MLX5_UMR_ALIGN - 1,
> + GFP_ATOMIC | __GFP_COMP | __GFP_COLD);
__GFP_COLD right before a memset(0) (kzalloc) makes little sense.
> + if (!wi->umr.mtt)
> + goto err_free_umr;
> +
> + wi->umr.mtt = PTR_ALIGN(wi->umr.mtt, MLX5_UMR_ALIGN);
> + wi->umr.mtt_addr = dma_map_single(rq->pdev, wi->umr.mtt, mtt_sz,
> + PCI_DMA_TODEVICE);
> + if (dma_mapping_error(rq->pdev, wi->umr.mtt_addr))
> + goto err_free_mtt;
> +
...
>
> -void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
> +static void mlx5e_add_skb_frag(struct sk_buff *skb, int len, struct page *page,
> + int page_offset)
> +{
> + int f = skb_shinfo(skb)->nr_frags++;
> + skb_frag_t *fr = &skb_shinfo(skb)->frags[f];
> +
> + skb->len += len;
> + skb->data_len += len;
> + get_page(page);
> + skb_frag_set_page(skb, f, page);
> + skb_frag_size_set(fr, len);
> + fr->page_offset = page_offset;
> + skb->truesize = SKB_TRUESIZE(skb->len);
> +}
Really I am speechless.
It is hard to believe how much effort some drivers authors spend trying
to fool linux stack and risk OOM a host under stress.
SKB_TRUESIZE() is absolutely not something a driver is allowed to use.
Here you want instead :
skb->truesize += PAGE_SIZE;
Assuming you allocate and use an order-0 page per fragment. Fact that
you receive say 100 bytes datagram is irrelevant to truesize.
truesize is the real memory usage of one skb. Not the minimal size of an
optimally allocated skb for a given payload.
Better RX speed should not be done at the risk of system stability.
Now if for some reason you need to increase max TCP RWIN, that would be
a TCP stack change, not some obscure lie in a driver trying to be faster
than competitors.
Thanks.
^ permalink raw reply
* Re: [PATCH net-next 04/13] net/mlx5e: Use only close NUMA node for default RSS
From: Sergei Shtylyov @ 2016-03-11 14:08 UTC (permalink / raw)
To: Saeed Mahameed, David S. Miller
Cc: netdev, Or Gerlitz, Eran Ben Elisha, Tal Alon, Tariq Toukan,
Jesper Dangaard Brouer
In-Reply-To: <1457703594-9482-5-git-send-email-saeedm@mellanox.com>
Hello.
On 3/11/2016 4:39 PM, Saeed Mahameed wrote:
> From: Tariq Toukan <tariqt@mellanox.com>
>
> Distribute default RSS table uniformely over the rings of the
Uniformly.
> close NUMA node, instead of all available channels.
> This way we enforce the preference of close rings over far ones.
>
> Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
[...]
MBR, Sergei
^ permalink raw reply
* Re: [PATCH 3/6] net: arc_emac: support the phy reset for emac driver
From: Sergei Shtylyov @ 2016-03-11 13:47 UTC (permalink / raw)
To: Caesar Wang, Heiko Stuebner, David S. Miller, Rob Herring
Cc: linux-rockchip, keescook, leozwang, Alexander Kochetkov, netdev,
linux-kernel
In-Reply-To: <1457693731-6966-4-git-send-email-wxt@rock-chips.com>
Hello.
On 3/11/2016 1:55 PM, Caesar Wang wrote:
> This patch adds to support the emac phy reset.
>
> 1) phy-reset-gpios:
> The phy-reset-gpios is an optional property for arc emac device tree boot.
> Change the binding document to match the driver code.
>
> 2) phy-reset-duration:
> Different boards may require different phy reset duration. Add property
> phy-reset-duration for device tree probe, so that the boards that need
> a longer reset duration can specify it in their device tree.
>
> 3) phy-reset-active-high:
> We need that for a custom hardware that needs the reverse reset sequence.
>
> Of course, this patch will fix the issue on
> https://patchwork.kernel.org/patch/8186801/.
>
> In some cases, the emac couldn't work if you don't have reset the phy.
> Let's add it to happy work.
>
> Signed-off-by: Caesar Wang <wxt@rock-chips.com>
> ---
>
> drivers/net/ethernet/arc/emac_main.c | 41 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 41 insertions(+)
>
> diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
> index 6446af1..42384f6a 100644
> --- a/drivers/net/ethernet/arc/emac_main.c
> +++ b/drivers/net/ethernet/arc/emac_main.c
> @@ -764,6 +764,45 @@ static const struct net_device_ops arc_emac_netdev_ops = {
> #endif
> };
>
> +#ifdef CONFIG_OF
> +static void emac_reset_phy(struct net_device *pdev)
> +{
> + int err, phy_reset;
> + bool active_high = false;
> + int msec = 10;
> + struct device *dev = pdev->dev.parent;
> + struct device_node *np = dev->of_node;
> +
> + if (!np)
> + return;
> +
> + of_property_read_u32(np, "phy-reset-duration", &msec);
> + /* A sane reset duration should not be longer than 1s */
> + if (msec > 1000)
> + msec = 1;
> +
> + phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
> + if (!gpio_is_valid(phy_reset))
> + return;
> +
> + active_high = of_property_read_bool(np, "phy-reset-active-high");
> +
> + err = devm_gpio_request_one(dev, phy_reset, active_high ?
> + GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
> + "phy-reset");
> + if (err) {
> + dev_err(dev, "failed to get phy-reset-gpios: %d\n", err);
> + return;
> + }
> + msleep(msec);
> + gpio_set_value_cansleep(phy_reset, !active_high);
> +}
[...]
Why not make it the mii_bus::reset() method? It gets called before the
MDIO bus scan.
MBR, Sergei
^ permalink raw reply
* Re: [PATCH 0/6] arc_emac: fixes the emac issues oand cleanup emac drivers
From: Sergei Shtylyov @ 2016-03-11 13:46 UTC (permalink / raw)
To: Caesar Wang, Heiko Stuebner, David S. Miller, Rob Herring
Cc: linux-rockchip, keescook, leozwang, devicetree, Michael Turquette,
Alexander Kochetkov, Russell King, Stephen Boyd, netdev,
Kumar Gala, linux-kernel, Ian Campbell, zhengxing, Jiri Kosina,
Pawel Moll, Mark Rutland, linux-clk, linux-arm-kernel
In-Reply-To: <1457693731-6966-1-git-send-email-wxt@rock-chips.com>
Hello.
On 3/11/2016 1:55 PM, Caesar Wang wrote:
> This series patches are based on kernel 4.5-rc7+ version.
> Linux version 4.5.0-rc7-next-20160310+ (wxt@nb) (...) #23 SMP Fri Mar 11 15:55:53
[...]
> 1) This series has 6 patches: (1--->6)
> net: arc_emac: make the rockchip emac document more compatible
> net: arc_emac: add phy-reset-* are optional for device tree
I'm not seeing these patches on netdev...
> net: arc_emac: support the phy reset for emac driver
> net: arc: trivial: cleanup the emac driver
> clk: rockchip: rk3036: fix and add node id for emac clock
> ARM: dts: rockchip: add support emac for RK3036
>
> 2) This series patches have the following decriptions:
Descriptions.
> Hi Rob, David:
> PATCH[1/6-2/6]: ====>
> net: arc_emac: make the rockchip emac document more compatible
> net: arc_emac: add phy-reset-* are optional for device tree
>
> The patches change the rockchip emac document for more compatible and
> Add the phy-reset-* property for document.
>
> This patch adds the following property for arc_emac.
>
> phy-reset-* include the following:
> 1) phy-reset-gpios:
> The phy-reset-gpios is an optional property for arc emac device tree boot.
> Change the binding document to match the driver code.
>
> 2) phy-reset-duration:
> Different boards may require different phy reset duration. Add property
> phy-reset-duration for device tree probe, so that the boards that need
> a longer reset duration can specify it in their device tree.
>
> 3) phy-reset-active-high:
> We need that for a custom hardware that needs the reverse reset sequence.
Why not infer this from the "phy-reset-gpios" prop?
MBR, Sergei
^ permalink raw reply
* [PATCH net-next 10/13] net/mlx5e: Use napi_alloc_skb for RX SKB allocations
From: Saeed Mahameed @ 2016-03-11 13:39 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Or Gerlitz, Eran Ben Elisha, Tal Alon, Tariq Toukan,
Jesper Dangaard Brouer, Saeed Mahameed
In-Reply-To: <1457703594-9482-1-git-send-email-saeedm@mellanox.com>
From: Tariq Toukan <tariqt@mellanox.com>
Instead of netdev_alloc_skb, we use the napi_alloc_skb function
which is designated to allocate skbuff's for RX in a
channel-specific NAPI instance.
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index dd3a6e1..aa7f90c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -47,7 +47,7 @@ int mlx5e_alloc_rx_wqe(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe, u16 ix)
struct sk_buff *skb;
dma_addr_t dma_addr;
- skb = netdev_alloc_skb(rq->netdev, rq->wqe_sz);
+ skb = napi_alloc_skb(rq->cq.napi, rq->wqe_sz);
if (unlikely(!skb))
return -ENOMEM;
@@ -644,7 +644,7 @@ void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
goto mpwrq_cqe_out;
}
- skb = netdev_alloc_skb(rq->netdev, MLX5_MPWRQ_SMALL_PACKET_THRESHOLD);
+ skb = napi_alloc_skb(rq->cq.napi, MLX5_MPWRQ_SMALL_PACKET_THRESHOLD);
if (unlikely(!skb))
goto mpwrq_cqe_out;
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 06/13] net/mlx5e: Support RX multi-packet WQE (Striding RQ)
From: Saeed Mahameed @ 2016-03-11 13:39 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Or Gerlitz, Eran Ben Elisha, Tal Alon, Tariq Toukan,
Jesper Dangaard Brouer, Achiad Shochat, Saeed Mahameed
In-Reply-To: <1457703594-9482-1-git-send-email-saeedm@mellanox.com>
From: Tariq Toukan <tariqt@mellanox.com>
Introduce the feature of multi-packet WQE (RX Work Queue Element)
referred to as (MPWQE or Striding RQ), in which WQEs are larger
and serve multiple packets each.
Every WQE consists of many strides of the same size, every received
packet is aligned to a beginning of a stride and is written to
consecutive strides within a WQE.
In the regular approach, each regular WQE is big enough to be capable
of serving one received packet of any size up to MTU or 64K in case of
device LRO is enabeled, making it very wasteful when dealing with
small packets or device LRO is enabeled.
For its flexibility, MPWQE allows a better memory utilization (implying
improvements in CPU utilization and packet rate) as packets consume
strides according to their size, preserving the rest of the WQE to be
available for other packets.
MPWQE default configuration:
NUM WQEs = 16
Strides Per WQE = 1024
Stride Size = 128
Performance tested on ConnectX4-Lx 50G.
* Netperf single TCP stream:
- message size = 1024, bw raised from ~12300 mbps to 14900 mbps (+20%)
- message size = 65536, bw raised from ~21800 mbps to 33500 mbps (+50%)
- with other message sized we saw some gain or no degradation.
* Netperf multi TCP stream:
- No degradation, line rate reached.
* Pktgen: packet loss in bursts of N small messages (64byte), single
stream
- | num packets | packets loss before | packets loss after
| 2K | ~ 1K | 0
| 16K | ~13K | 0
| 32K | ~29K | 14K
As expected as the driver can recive as many small packets (<=128) as
the number of total strides in the ring (default = 1024 * 16) vs. 1024
(default ring size regardless of packets size) before this feautre.
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Achiad Shochat <achiad@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 71 +++++++++++-
.../net/ethernet/mellanox/mlx5/core/en_ethtool.c | 15 ++-
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 109 +++++++++++++----
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 126 ++++++++++++++++++--
include/linux/mlx5/device.h | 39 ++++++-
include/linux/mlx5/mlx5_ifc.h | 13 ++-
6 files changed, 327 insertions(+), 46 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index c70ec84..cd8805d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -57,12 +57,27 @@
#define MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE 0xa
#define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE 0xd
+#define MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW 0x1
+#define MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW 0x4
+#define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW 0x6
+
+#define MLX5_MPWRQ_LOG_NUM_STRIDES 10 /* >= 9, HW restriction */
+#define MLX5_MPWRQ_LOG_STRIDE_SIZE 7 /* >= 6, HW restriction */
+#define MLX5_MPWRQ_NUM_STRIDES BIT(MLX5_MPWRQ_LOG_NUM_STRIDES)
+#define MLX5_MPWRQ_STRIDE_SIZE BIT(MLX5_MPWRQ_LOG_STRIDE_SIZE)
+#define MLX5_MPWRQ_LOG_WQE_SZ (MLX5_MPWRQ_LOG_NUM_STRIDES +\
+ MLX5_MPWRQ_LOG_STRIDE_SIZE)
+#define MLX5_MPWRQ_WQE_PAGE_ORDER (max_t(int, 0, \
+ MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT))
+#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (128)
+
#define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ (64 * 1024)
#define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC 0x10
#define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_PKTS 0x20
#define MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_USEC 0x10
#define MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS 0x20
#define MLX5E_PARAMS_DEFAULT_MIN_RX_WQES 0x80
+#define MLX5E_PARAMS_DEFAULT_MIN_RX_WQES_MPW 0x2
#define MLX5E_LOG_INDIR_RQT_SIZE 0x7
#define MLX5E_INDIR_RQT_SIZE BIT(MLX5E_LOG_INDIR_RQT_SIZE)
@@ -74,6 +89,38 @@
#define MLX5E_NUM_MAIN_GROUPS 9
#define MLX5E_NET_IP_ALIGN 2
+static inline u16 mlx5_min_rx_wqes(int wq_type, u32 wq_size)
+{
+ switch (wq_type) {
+ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+ return min_t(u16, MLX5E_PARAMS_DEFAULT_MIN_RX_WQES_MPW,
+ wq_size / 2);
+ default:
+ return min_t(u16, MLX5E_PARAMS_DEFAULT_MIN_RX_WQES,
+ wq_size / 2);
+ }
+}
+
+static inline int mlx5_min_log_rq_size(int wq_type)
+{
+ switch (wq_type) {
+ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+ return MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW;
+ default:
+ return MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE;
+ }
+}
+
+static inline int mlx5_max_log_rq_size(int wq_type)
+{
+ switch (wq_type) {
+ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+ return MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW;
+ default:
+ return MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE;
+ }
+}
+
struct mlx5e_tx_wqe {
struct mlx5_wqe_ctrl_seg ctrl;
struct mlx5_wqe_eth_seg eth;
@@ -128,6 +175,7 @@ static const char vport_strings[][ETH_GSTRING_LEN] = {
"tx_queue_wake",
"tx_queue_dropped",
"rx_wqe_err",
+ "rx_mpwqe_filler",
};
struct mlx5e_vport_stats {
@@ -169,8 +217,9 @@ struct mlx5e_vport_stats {
u64 tx_queue_wake;
u64 tx_queue_dropped;
u64 rx_wqe_err;
+ u64 rx_mpwqe_filler;
-#define NUM_VPORT_COUNTERS 35
+#define NUM_VPORT_COUNTERS 36
};
static const char pport_strings[][ETH_GSTRING_LEN] = {
@@ -263,7 +312,8 @@ static const char rq_stats_strings[][ETH_GSTRING_LEN] = {
"csum_sw",
"lro_packets",
"lro_bytes",
- "wqe_err"
+ "wqe_err",
+ "mpwqe_filler",
};
struct mlx5e_rq_stats {
@@ -274,6 +324,7 @@ struct mlx5e_rq_stats {
u64 lro_packets;
u64 lro_bytes;
u64 wqe_err;
+ u64 mpwqe_filler;
#define NUM_RQ_STATS 7
};
@@ -318,6 +369,7 @@ struct mlx5e_stats {
struct mlx5e_params {
u8 log_sq_size;
+ u8 rq_wq_type;
u8 log_rq_size;
u16 num_channels;
u8 num_tc;
@@ -374,11 +426,22 @@ typedef void (*mlx5e_fp_handle_rx_cqe)(struct mlx5e_rq *rq,
typedef int (*mlx5e_fp_alloc_wqe)(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe,
u16 ix);
+struct mlx5e_dma_info {
+ struct page *page;
+ dma_addr_t addr;
+};
+
+struct mlx5e_mpw_info {
+ struct mlx5e_dma_info dma_info;
+ u16 consumed_strides;
+};
+
struct mlx5e_rq {
/* data path */
struct mlx5_wq_ll wq;
u32 wqe_sz;
struct sk_buff **skb;
+ struct mlx5e_mpw_info *wqe_info;
struct device *pdev;
struct net_device *netdev;
@@ -393,6 +456,7 @@ struct mlx5e_rq {
/* control */
struct mlx5_wq_ctrl wq_ctrl;
+ u8 wq_type;
u32 rqn;
struct mlx5e_channel *channel;
struct mlx5e_priv *priv;
@@ -649,9 +713,12 @@ void mlx5e_cq_error_event(struct mlx5_core_cq *mcq, enum mlx5_event event);
int mlx5e_napi_poll(struct napi_struct *napi, int budget);
bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq);
int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget);
+
void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
+void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq);
int mlx5e_alloc_rx_wqe(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe, u16 ix);
+int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe, u16 ix);
struct mlx5_cqe64 *mlx5e_get_cqe(struct mlx5e_cq *cq);
void mlx5e_update_stats(struct mlx5e_priv *priv);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 6f40ba4..4077856 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -273,8 +273,9 @@ static void mlx5e_get_ringparam(struct net_device *dev,
struct ethtool_ringparam *param)
{
struct mlx5e_priv *priv = netdev_priv(dev);
+ int rq_wq_type = priv->params.rq_wq_type;
- param->rx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE;
+ param->rx_max_pending = 1 << mlx5_max_log_rq_size(rq_wq_type);
param->tx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE;
param->rx_pending = 1 << priv->params.log_rq_size;
param->tx_pending = 1 << priv->params.log_sq_size;
@@ -285,6 +286,7 @@ static int mlx5e_set_ringparam(struct net_device *dev,
{
struct mlx5e_priv *priv = netdev_priv(dev);
bool was_opened;
+ int rq_wq_type = priv->params.rq_wq_type;
u16 min_rx_wqes;
u8 log_rq_size;
u8 log_sq_size;
@@ -300,16 +302,16 @@ static int mlx5e_set_ringparam(struct net_device *dev,
__func__);
return -EINVAL;
}
- if (param->rx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)) {
+ if (param->rx_pending < (1 << mlx5_min_log_rq_size(rq_wq_type))) {
netdev_info(dev, "%s: rx_pending (%d) < min (%d)\n",
__func__, param->rx_pending,
- 1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE);
+ 1 << mlx5_min_log_rq_size(rq_wq_type));
return -EINVAL;
}
- if (param->rx_pending > (1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE)) {
+ if (param->rx_pending > (1 << mlx5_max_log_rq_size(rq_wq_type))) {
netdev_info(dev, "%s: rx_pending (%d) > max (%d)\n",
__func__, param->rx_pending,
- 1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE);
+ 1 << mlx5_max_log_rq_size(rq_wq_type));
return -EINVAL;
}
if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) {
@@ -327,8 +329,7 @@ static int mlx5e_set_ringparam(struct net_device *dev,
log_rq_size = order_base_2(param->rx_pending);
log_sq_size = order_base_2(param->tx_pending);
- min_rx_wqes = min_t(u16, param->rx_pending - 1,
- MLX5E_PARAMS_DEFAULT_MIN_RX_WQES);
+ min_rx_wqes = mlx5_min_rx_wqes(rq_wq_type, param->rx_pending);
if (log_rq_size == priv->params.log_rq_size &&
log_sq_size == priv->params.log_sq_size &&
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 23ba12c..871f3af 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -175,6 +175,7 @@ void mlx5e_update_stats(struct mlx5e_priv *priv)
s->rx_csum_none = 0;
s->rx_csum_sw = 0;
s->rx_wqe_err = 0;
+ s->rx_mpwqe_filler = 0;
for (i = 0; i < priv->params.num_channels; i++) {
rq_stats = &priv->channel[i]->rq.stats;
@@ -185,6 +186,7 @@ void mlx5e_update_stats(struct mlx5e_priv *priv)
s->rx_csum_none += rq_stats->csum_none;
s->rx_csum_sw += rq_stats->csum_sw;
s->rx_wqe_err += rq_stats->wqe_err;
+ s->rx_mpwqe_filler += rq_stats->mpwqe_filler;
for (j = 0; j < priv->params.num_tc; j++) {
sq_stats = &priv->channel[i]->sq[j].stats;
@@ -323,6 +325,7 @@ static int mlx5e_create_rq(struct mlx5e_channel *c,
struct mlx5_core_dev *mdev = priv->mdev;
void *rqc = param->rqc;
void *rqc_wq = MLX5_ADDR_OF(rqc, rqc, wq);
+ u32 byte_count;
int wq_sz;
int err;
int i;
@@ -337,28 +340,47 @@ static int mlx5e_create_rq(struct mlx5e_channel *c,
rq->wq.db = &rq->wq.db[MLX5_RCV_DBR];
wq_sz = mlx5_wq_ll_get_size(&rq->wq);
- rq->skb = kzalloc_node(wq_sz * sizeof(*rq->skb), GFP_KERNEL,
- cpu_to_node(c->cpu));
- if (!rq->skb) {
- err = -ENOMEM;
- goto err_rq_wq_destroy;
- }
- rq->wqe_sz = (priv->params.lro_en) ? priv->params.lro_wqe_sz :
- MLX5E_SW2HW_MTU(priv->netdev->mtu);
- rq->wqe_sz = SKB_DATA_ALIGN(rq->wqe_sz + MLX5E_NET_IP_ALIGN);
+ switch (priv->params.rq_wq_type) {
+ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+ rq->wqe_info = kzalloc_node(wq_sz * sizeof(*rq->wqe_info),
+ GFP_KERNEL, cpu_to_node(c->cpu));
+ if (!rq->wqe_info) {
+ err = -ENOMEM;
+ goto err_rq_wq_destroy;
+ }
+ rq->handle_rx_cqe = mlx5e_handle_rx_cqe_mpwrq;
+ rq->alloc_wqe = mlx5e_alloc_rx_mpwqe;
+
+ rq->wqe_sz = MLX5_MPWRQ_NUM_STRIDES * MLX5_MPWRQ_STRIDE_SIZE;
+ byte_count = rq->wqe_sz;
+ break;
+ default: /* MLX5_WQ_TYPE_LINKED_LIST */
+ rq->skb = kzalloc_node(wq_sz * sizeof(*rq->skb), GFP_KERNEL,
+ cpu_to_node(c->cpu));
+ if (!rq->skb) {
+ err = -ENOMEM;
+ goto err_rq_wq_destroy;
+ }
+ rq->handle_rx_cqe = mlx5e_handle_rx_cqe;
+ rq->alloc_wqe = mlx5e_alloc_rx_wqe;
+
+ rq->wqe_sz = (priv->params.lro_en) ?
+ priv->params.lro_wqe_sz :
+ MLX5E_SW2HW_MTU(priv->netdev->mtu);
+ rq->wqe_sz = SKB_DATA_ALIGN(rq->wqe_sz + MLX5E_NET_IP_ALIGN);
+ byte_count = rq->wqe_sz - MLX5E_NET_IP_ALIGN;
+ byte_count |= MLX5_HW_START_PADDING;
+ }
for (i = 0; i < wq_sz; i++) {
struct mlx5e_rx_wqe *wqe = mlx5_wq_ll_get_wqe(&rq->wq, i);
- u32 byte_count = rq->wqe_sz - MLX5E_NET_IP_ALIGN;
wqe->data.lkey = c->mkey_be;
- wqe->data.byte_count =
- cpu_to_be32(byte_count | MLX5_HW_START_PADDING);
+ wqe->data.byte_count = cpu_to_be32(byte_count);
}
- rq->handle_rx_cqe = mlx5e_handle_rx_cqe;
- rq->alloc_wqe = mlx5e_alloc_rx_wqe;
+ rq->wq_type = priv->params.rq_wq_type;
rq->pdev = c->pdev;
rq->netdev = c->netdev;
rq->tstamp = &priv->tstamp;
@@ -376,7 +398,14 @@ err_rq_wq_destroy:
static void mlx5e_destroy_rq(struct mlx5e_rq *rq)
{
- kfree(rq->skb);
+ switch (rq->wq_type) {
+ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+ kfree(rq->wqe_info);
+ break;
+ default: /* MLX5_WQ_TYPE_LINKED_LIST */
+ kfree(rq->skb);
+ }
+
mlx5_wq_destroy(&rq->wq_ctrl);
}
@@ -1065,7 +1094,18 @@ static void mlx5e_build_rq_param(struct mlx5e_priv *priv,
void *rqc = param->rqc;
void *wq = MLX5_ADDR_OF(rqc, rqc, wq);
- MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_LINKED_LIST);
+ switch (priv->params.rq_wq_type) {
+ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+ MLX5_SET(wq, wq, log_wqe_num_of_strides,
+ MLX5_MPWRQ_LOG_NUM_STRIDES - 9);
+ MLX5_SET(wq, wq, log_wqe_stride_size,
+ MLX5_MPWRQ_LOG_STRIDE_SIZE - 6);
+ MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ);
+ break;
+ default: /* MLX5_WQ_TYPE_LINKED_LIST */
+ MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_LINKED_LIST);
+ }
+
MLX5_SET(wq, wq, end_padding_mode, MLX5_WQ_END_PAD_MODE_ALIGN);
MLX5_SET(wq, wq, log_wq_stride, ilog2(sizeof(struct mlx5e_rx_wqe)));
MLX5_SET(wq, wq, log_wq_sz, priv->params.log_rq_size);
@@ -1111,8 +1151,18 @@ static void mlx5e_build_rx_cq_param(struct mlx5e_priv *priv,
struct mlx5e_cq_param *param)
{
void *cqc = param->cqc;
+ u8 log_cq_size;
- MLX5_SET(cqc, cqc, log_cq_size, priv->params.log_rq_size);
+ switch (priv->params.rq_wq_type) {
+ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+ log_cq_size = priv->params.log_rq_size +
+ MLX5_MPWRQ_LOG_NUM_STRIDES;
+ break;
+ default: /* MLX5_WQ_TYPE_LINKED_LIST */
+ log_cq_size = priv->params.log_rq_size;
+ }
+
+ MLX5_SET(cqc, cqc, log_cq_size, log_cq_size);
mlx5e_build_common_cq_param(priv, param);
}
@@ -1983,7 +2033,8 @@ static int mlx5e_set_features(struct net_device *netdev,
if (changes & NETIF_F_LRO) {
bool was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
- if (was_opened)
+ if (was_opened && (priv->params.rq_wq_type ==
+ MLX5_WQ_TYPE_LINKED_LIST))
mlx5e_close_locked(priv->netdev);
priv->params.lro_en = !!(features & NETIF_F_LRO);
@@ -1992,7 +2043,8 @@ static int mlx5e_set_features(struct net_device *netdev,
mlx5_core_warn(priv->mdev, "lro modify failed, %d\n",
err);
- if (was_opened)
+ if (was_opened && (priv->params.rq_wq_type ==
+ MLX5_WQ_TYPE_LINKED_LIST))
err = mlx5e_open_locked(priv->netdev);
}
@@ -2327,8 +2379,21 @@ static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev,
priv->params.log_sq_size =
MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
- priv->params.log_rq_size =
- MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE;
+ priv->params.rq_wq_type = MLX5_CAP_GEN(mdev, striding_rq) ?
+ MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ :
+ MLX5_WQ_TYPE_LINKED_LIST;
+
+ switch (priv->params.rq_wq_type) {
+ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+ priv->params.log_rq_size = MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW;
+ priv->params.lro_en = true;
+ break;
+ default: /* MLX5_WQ_TYPE_LINKED_LIST */
+ priv->params.log_rq_size = MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE;
+ }
+
+ priv->params.min_rx_wqes = mlx5_min_rx_wqes(priv->params.rq_wq_type,
+ BIT(priv->params.log_rq_size));
priv->params.rx_cq_moderation_usec =
MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC;
priv->params.rx_cq_moderation_pkts =
@@ -2338,8 +2403,6 @@ static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev,
priv->params.tx_cq_moderation_pkts =
MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS;
priv->params.tx_max_inline = mlx5e_get_max_inline_cap(mdev);
- priv->params.min_rx_wqes =
- MLX5E_PARAMS_DEFAULT_MIN_RX_WQES;
priv->params.num_tc = 1;
priv->params.rss_hfunc = ETH_RSS_HASH_XOR;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index d7ccced..18105c1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -76,6 +76,33 @@ err_free_skb:
return -ENOMEM;
}
+int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe, u16 ix)
+{
+ struct mlx5e_mpw_info *wi = &rq->wqe_info[ix];
+ int ret = 0;
+
+ wi->dma_info.page = alloc_pages(GFP_ATOMIC | __GFP_COMP | __GFP_COLD,
+ MLX5_MPWRQ_WQE_PAGE_ORDER);
+ if (unlikely(!wi->dma_info.page))
+ return -ENOMEM;
+
+ wi->dma_info.addr = dma_map_page(rq->pdev, wi->dma_info.page, 0,
+ rq->wqe_sz, PCI_DMA_FROMDEVICE);
+ if (dma_mapping_error(rq->pdev, wi->dma_info.addr)) {
+ ret = -ENOMEM;
+ goto err_put_page;
+ }
+
+ wi->consumed_strides = 0;
+ wqe->data.addr = cpu_to_be64(wi->dma_info.addr);
+
+ return 0;
+
+err_put_page:
+ put_page(wi->dma_info.page);
+ return ret;
+}
+
bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq)
{
struct mlx5_wq_ll *wq = &rq->wq;
@@ -100,7 +127,8 @@ bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq)
return !mlx5_wq_ll_is_full(wq);
}
-static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe)
+static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe,
+ u32 cqe_bcnt)
{
struct ethhdr *eth = (struct ethhdr *)(skb->data);
struct iphdr *ipv4 = (struct iphdr *)(skb->data + ETH_HLEN);
@@ -111,7 +139,7 @@ static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe)
int tcp_ack = ((CQE_L4_HDR_TYPE_TCP_ACK_NO_DATA == l4_hdr_type) ||
(CQE_L4_HDR_TYPE_TCP_ACK_AND_DATA == l4_hdr_type));
- u16 tot_len = be32_to_cpu(cqe->byte_cnt) - ETH_HLEN;
+ u16 tot_len = cqe_bcnt - ETH_HLEN;
if (eth->h_proto == htons(ETH_P_IP)) {
tcp = (struct tcphdr *)(skb->data + ETH_HLEN +
@@ -191,19 +219,17 @@ csum_none:
}
static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
+ u32 cqe_bcnt,
struct mlx5e_rq *rq,
struct sk_buff *skb)
{
struct net_device *netdev = rq->netdev;
- u32 cqe_bcnt = be32_to_cpu(cqe->byte_cnt);
struct mlx5e_tstamp *tstamp = rq->tstamp;
int lro_num_seg;
- skb_put(skb, cqe_bcnt);
-
lro_num_seg = be32_to_cpu(cqe->srqn) >> 24;
if (lro_num_seg > 1) {
- mlx5e_lro_update_hdr(skb, cqe);
+ mlx5e_lro_update_hdr(skb, cqe, cqe_bcnt);
skb_shinfo(skb)->gso_size = DIV_ROUND_UP(cqe_bcnt, lro_num_seg);
rq->stats.lro_packets++;
rq->stats.lro_bytes += cqe_bcnt;
@@ -228,12 +254,24 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
skb->mark = be32_to_cpu(cqe->sop_drop_qpn) & MLX5E_TC_FLOW_ID_MASK;
}
+static inline void mlx5e_complete_rx_cqe(struct mlx5e_rq *rq,
+ struct mlx5_cqe64 *cqe,
+ u32 cqe_bcnt,
+ struct sk_buff *skb)
+{
+ mlx5e_build_rx_skb(cqe, cqe_bcnt, rq, skb);
+ rq->stats.packets++;
+ rq->stats.bytes += cqe_bcnt;
+ napi_gro_receive(rq->cq.napi, skb);
+}
+
void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
{
struct mlx5e_rx_wqe *wqe;
struct sk_buff *skb;
__be16 wqe_counter_be;
u16 wqe_counter;
+ u32 cqe_bcnt;
wqe_counter_be = cqe->wqe_counter;
wqe_counter = be16_to_cpu(wqe_counter_be);
@@ -253,16 +291,84 @@ void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
goto wq_ll_pop;
}
- mlx5e_build_rx_skb(cqe, rq, skb);
- rq->stats.packets++;
- rq->stats.bytes += be32_to_cpu(cqe->byte_cnt);
- napi_gro_receive(rq->cq.napi, skb);
+ cqe_bcnt = be32_to_cpu(cqe->byte_cnt);
+ skb_put(skb, cqe_bcnt);
+
+ mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
wq_ll_pop:
mlx5_wq_ll_pop(&rq->wq, wqe_counter_be,
&wqe->next.next_wqe_index);
}
+void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
+{
+ u16 cstrides = mpwrq_get_cqe_consumed_strides(cqe);
+ u16 stride_ix = mpwrq_get_cqe_stride_index(cqe);
+ u32 consumed_bytes = cstrides * MLX5_MPWRQ_STRIDE_SIZE;
+ u32 stride_offset = stride_ix * MLX5_MPWRQ_STRIDE_SIZE;
+ u16 wqe_id = be16_to_cpu(cqe->wqe_id);
+ struct mlx5e_mpw_info *wi = &rq->wqe_info[wqe_id];
+ struct mlx5e_rx_wqe *wqe = mlx5_wq_ll_get_wqe(&rq->wq, wqe_id);
+ struct sk_buff *skb;
+ u16 byte_cnt;
+ u16 cqe_bcnt;
+ u16 headlen;
+
+ wi->consumed_strides += cstrides;
+
+ if (unlikely((cqe->op_own >> 4) != MLX5_CQE_RESP_SEND)) {
+ rq->stats.wqe_err++;
+ goto mpwrq_cqe_out;
+ }
+
+ if (mpwrq_is_filler_cqe(cqe)) {
+ rq->stats.mpwqe_filler++;
+ goto mpwrq_cqe_out;
+ }
+
+ skb = netdev_alloc_skb(rq->netdev, MLX5_MPWRQ_SMALL_PACKET_THRESHOLD);
+ if (unlikely(!skb))
+ goto mpwrq_cqe_out;
+
+ dma_sync_single_for_cpu(rq->pdev, wi->dma_info.addr + stride_offset,
+ consumed_bytes, DMA_FROM_DEVICE);
+
+ cqe_bcnt = mpwrq_get_cqe_byte_cnt(cqe);
+ headlen = min_t(u16, MLX5_MPWRQ_SMALL_PACKET_THRESHOLD, cqe_bcnt);
+ skb_copy_to_linear_data(skb,
+ page_address(wi->dma_info.page) + stride_offset,
+ headlen);
+ skb_put(skb, headlen);
+
+ byte_cnt = cqe_bcnt - headlen;
+ if (byte_cnt) {
+ skb_frag_t *f0 = &skb_shinfo(skb)->frags[0];
+
+ skb_shinfo(skb)->nr_frags = 1;
+
+ skb->data_len = byte_cnt;
+ skb->len += byte_cnt;
+ skb->truesize = SKB_TRUESIZE(skb->len);
+
+ get_page(wi->dma_info.page);
+ skb_frag_set_page(skb, 0, wi->dma_info.page);
+ skb_frag_size_set(f0, skb->data_len);
+ f0->page_offset = stride_offset + headlen;
+ }
+
+ mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
+
+mpwrq_cqe_out:
+ if (likely(wi->consumed_strides < MLX5_MPWRQ_NUM_STRIDES))
+ return;
+
+ dma_unmap_page(rq->pdev, wi->dma_info.addr, rq->wqe_sz,
+ PCI_DMA_FROMDEVICE);
+ put_page(wi->dma_info.page);
+ mlx5_wq_ll_pop(&rq->wq, cqe->wqe_id, &wqe->next.next_wqe_index);
+}
+
int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget)
{
struct mlx5e_rq *rq = container_of(cq, struct mlx5e_rq, cq);
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index 68a56bc..9b60f45 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -621,7 +621,8 @@ struct mlx5_err_cqe {
};
struct mlx5_cqe64 {
- u8 rsvd0[4];
+ u8 rsvd0[2];
+ __be16 wqe_id;
u8 lro_tcppsh_abort_dupack;
u8 lro_min_ttl;
__be16 lro_tcp_win;
@@ -673,6 +674,42 @@ static inline u64 get_cqe_ts(struct mlx5_cqe64 *cqe)
return (u64)lo | ((u64)hi << 32);
}
+struct mpwrq_cqe_bc {
+ __be16 filler_consumed_strides;
+ __be16 byte_cnt;
+};
+
+static inline u16 mpwrq_get_cqe_byte_cnt(struct mlx5_cqe64 *cqe)
+{
+ struct mpwrq_cqe_bc *bc = (struct mpwrq_cqe_bc *)&cqe->byte_cnt;
+
+ return be16_to_cpu(bc->byte_cnt);
+}
+
+static inline u16 mpwrq_get_cqe_bc_consumed_strides(struct mpwrq_cqe_bc *bc)
+{
+ return 0x7fff & be16_to_cpu(bc->filler_consumed_strides);
+}
+
+static inline u16 mpwrq_get_cqe_consumed_strides(struct mlx5_cqe64 *cqe)
+{
+ struct mpwrq_cqe_bc *bc = (struct mpwrq_cqe_bc *)&cqe->byte_cnt;
+
+ return mpwrq_get_cqe_bc_consumed_strides(bc);
+}
+
+static inline bool mpwrq_is_filler_cqe(struct mlx5_cqe64 *cqe)
+{
+ struct mpwrq_cqe_bc *bc = (struct mpwrq_cqe_bc *)&cqe->byte_cnt;
+
+ return 0x8000 & be16_to_cpu(bc->filler_consumed_strides);
+}
+
+static inline u16 mpwrq_get_cqe_stride_index(struct mlx5_cqe64 *cqe)
+{
+ return be16_to_cpu(cqe->wqe_counter);
+}
+
enum {
CQE_L4_HDR_TYPE_NONE = 0x0,
CQE_L4_HDR_TYPE_TCP_NO_ACK = 0x1,
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 9d91ce3..6060ca3 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -620,7 +620,7 @@ struct mlx5_ifc_odp_cap_bits {
enum {
MLX5_WQ_TYPE_LINKED_LIST = 0x0,
MLX5_WQ_TYPE_CYCLIC = 0x1,
- MLX5_WQ_TYPE_STRQ = 0x2,
+ MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ = 0x2,
};
enum {
@@ -750,7 +750,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 cqe_version[0x4];
u8 compact_address_vector[0x1];
- u8 reserved_at_200[0xe];
+ u8 striding_rq[0x1];
+ u8 reserved_at_201[0xd];
u8 drain_sigerr[0x1];
u8 cmdif_checksum[0x2];
u8 sigerr_cqe[0x1];
@@ -963,7 +964,13 @@ struct mlx5_ifc_wq_bits {
u8 reserved_at_118[0x3];
u8 log_wq_sz[0x5];
- u8 reserved_at_120[0x4e0];
+ u8 reserved_at_120[0x15];
+ u8 log_wqe_num_of_strides[0x3];
+ u8 two_byte_shift_en[0x1];
+ u8 reserved_at_139[0x4];
+ u8 log_wqe_stride_size[0x3];
+
+ u8 reserved_at_140[0x4c0];
struct mlx5_ifc_cmd_pas_bits pas[0];
};
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 11/13] net/mlx5e: Prefetch next RX CQE
From: Saeed Mahameed @ 2016-03-11 13:39 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Or Gerlitz, Eran Ben Elisha, Tal Alon, Tariq Toukan,
Jesper Dangaard Brouer, Saeed Mahameed
In-Reply-To: <1457703594-9482-1-git-send-email-saeedm@mellanox.com>
From: Tariq Toukan <tariqt@mellanox.com>
Performance optimization that prefetches the next RX CQE while
handling the current one.
Performance tested on ConnectX4-Lx 50G.
* Netperf single TCP stream:
- bw raise of 3-10% for various representative messages sizes.
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index aa7f90c..b53e9bd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -664,15 +664,19 @@ mpwrq_cqe_out:
int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget)
{
struct mlx5e_rq *rq = container_of(cq, struct mlx5e_rq, cq);
+ struct mlx5_cqe64 *next_cqe = mlx5e_get_cqe(cq);
+ struct mlx5_cqe64 *cqe;
int work_done;
for (work_done = 0; work_done < budget; work_done++) {
- struct mlx5_cqe64 *cqe = mlx5e_get_cqe(cq);
+ cqe = next_cqe;
if (!cqe)
break;
mlx5_cqwq_pop(&cq->wq);
+ next_cqe = mlx5e_get_cqe(cq);
+ prefetch(next_cqe);
rq->handle_rx_cqe(rq, cqe);
}
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 03/13] net/mlx5e: Allocate set of queue counters per netdev
From: Saeed Mahameed @ 2016-03-11 13:39 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Or Gerlitz, Eran Ben Elisha, Tal Alon, Tariq Toukan,
Jesper Dangaard Brouer, Rana Shahout, Saeed Mahameed
In-Reply-To: <1457703594-9482-1-git-send-email-saeedm@mellanox.com>
From: Rana Shahout <ranas@mellanox.com>
Connect all netdev RQs to this set of queue counters.
Also, add an "rx_out_of_buffer" counter to ethtool,
which indicates RX packet drops due to lack of receive
buffers.
Signed-off-by: Rana Shahout <ranas@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 11 +++++
.../net/ethernet/mellanox/mlx5/core/en_ethtool.c | 11 +++++
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 42 +++++++++++++++++++-
3 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 1f5cc1b..5ef91a9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -236,6 +236,15 @@ struct mlx5e_pport_stats {
__be64 RFC_2819_counters[NUM_RFC_2819_COUNTERS];
};
+static const char qcounter_stats_strings[][ETH_GSTRING_LEN] = {
+ "rx_out_of_buffer",
+};
+
+struct mlx5e_qcounter_stats {
+ u32 rx_out_of_buffer;
+#define NUM_Q_COUNTERS 1
+};
+
static const char rq_stats_strings[][ETH_GSTRING_LEN] = {
"packets",
"bytes",
@@ -293,6 +302,7 @@ struct mlx5e_sq_stats {
struct mlx5e_stats {
struct mlx5e_vport_stats vport;
struct mlx5e_pport_stats pport;
+ struct mlx5e_qcounter_stats qcnt;
};
struct mlx5e_params {
@@ -575,6 +585,7 @@ struct mlx5e_priv {
struct net_device *netdev;
struct mlx5e_stats stats;
struct mlx5e_tstamp tstamp;
+ u16 q_counter;
};
#define MLX5E_NET_IP_ALIGN 2
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 68834b7..39c1902 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -165,6 +165,8 @@ static const struct {
},
};
+#define MLX5E_NUM_Q_CNTRS(priv) (NUM_Q_COUNTERS * (!!priv->q_counter))
+
static int mlx5e_get_sset_count(struct net_device *dev, int sset)
{
struct mlx5e_priv *priv = netdev_priv(dev);
@@ -172,6 +174,7 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset)
switch (sset) {
case ETH_SS_STATS:
return NUM_VPORT_COUNTERS + NUM_PPORT_COUNTERS +
+ MLX5E_NUM_Q_CNTRS(priv) +
priv->params.num_channels * NUM_RQ_STATS +
priv->params.num_channels * priv->params.num_tc *
NUM_SQ_STATS;
@@ -200,6 +203,11 @@ static void mlx5e_get_strings(struct net_device *dev,
strcpy(data + (idx++) * ETH_GSTRING_LEN,
vport_strings[i]);
+ /* Q counters */
+ for (i = 0; i < MLX5E_NUM_Q_CNTRS(priv); i++)
+ strcpy(data + (idx++) * ETH_GSTRING_LEN,
+ qcounter_stats_strings[i]);
+
/* PPORT counters */
for (i = 0; i < NUM_PPORT_COUNTERS; i++)
strcpy(data + (idx++) * ETH_GSTRING_LEN,
@@ -240,6 +248,9 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev,
for (i = 0; i < NUM_VPORT_COUNTERS; i++)
data[idx++] = ((u64 *)&priv->stats.vport)[i];
+ for (i = 0; i < MLX5E_NUM_Q_CNTRS(priv); i++)
+ data[idx++] = ((u32 *)&priv->stats.qcnt)[i];
+
for (i = 0; i < NUM_PPORT_COUNTERS; i++)
data[idx++] = be64_to_cpu(((__be64 *)&priv->stats.pport)[i]);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index e0adb60..7fbe1ba 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -129,6 +129,17 @@ free_out:
kvfree(out);
}
+static void mlx5e_update_q_counter(struct mlx5e_priv *priv)
+{
+ struct mlx5e_qcounter_stats *qcnt = &priv->stats.qcnt;
+
+ if (!priv->q_counter)
+ return;
+
+ mlx5_core_query_out_of_buffer(priv->mdev, priv->q_counter,
+ &qcnt->rx_out_of_buffer);
+}
+
void mlx5e_update_stats(struct mlx5e_priv *priv)
{
struct mlx5_core_dev *mdev = priv->mdev;
@@ -250,6 +261,8 @@ void mlx5e_update_stats(struct mlx5e_priv *priv)
s->rx_csum_sw;
mlx5e_update_pport_counters(priv);
+ mlx5e_update_q_counter(priv);
+
free_out:
kvfree(out);
}
@@ -1055,6 +1068,7 @@ static void mlx5e_build_rq_param(struct mlx5e_priv *priv,
MLX5_SET(wq, wq, log_wq_stride, ilog2(sizeof(struct mlx5e_rx_wqe)));
MLX5_SET(wq, wq, log_wq_sz, priv->params.log_rq_size);
MLX5_SET(wq, wq, pd, priv->pdn);
+ MLX5_SET(rqc, rqc, counter_set_id, priv->q_counter);
param->wq.buf_numa_node = dev_to_node(&priv->mdev->pdev->dev);
param->wq.linear = 1;
@@ -2442,6 +2456,26 @@ static int mlx5e_create_mkey(struct mlx5e_priv *priv, u32 pdn,
return err;
}
+static void mlx5e_create_q_counter(struct mlx5e_priv *priv)
+{
+ struct mlx5_core_dev *mdev = priv->mdev;
+ int err;
+
+ err = mlx5_core_alloc_q_counter(mdev, &priv->q_counter);
+ if (err) {
+ mlx5_core_warn(mdev, "alloc queue counter failed, %d\n", err);
+ priv->q_counter = 0;
+ }
+}
+
+static void mlx5e_destroy_q_counter(struct mlx5e_priv *priv)
+{
+ if (!priv->q_counter)
+ return;
+
+ mlx5_core_dealloc_q_counter(priv->mdev, priv->q_counter);
+}
+
static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
{
struct net_device *netdev;
@@ -2527,13 +2561,15 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
goto err_destroy_tirs;
}
+ mlx5e_create_q_counter(priv);
+
mlx5e_init_eth_addr(priv);
mlx5e_vxlan_init(priv);
err = mlx5e_tc_init(priv);
if (err)
- goto err_destroy_flow_tables;
+ goto err_dealloc_q_counters;
#ifdef CONFIG_MLX5_CORE_EN_DCB
mlx5e_dcbnl_ieee_setets_core(priv, &priv->params.ets);
@@ -2556,7 +2592,8 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
err_tc_cleanup:
mlx5e_tc_cleanup(priv);
-err_destroy_flow_tables:
+err_dealloc_q_counters:
+ mlx5e_destroy_q_counter(priv);
mlx5e_destroy_flow_tables(priv);
err_destroy_tirs:
@@ -2605,6 +2642,7 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv)
unregister_netdev(netdev);
mlx5e_tc_cleanup(priv);
mlx5e_vxlan_cleanup(priv);
+ mlx5e_destroy_q_counter(priv);
mlx5e_destroy_flow_tables(priv);
mlx5e_destroy_tirs(priv);
mlx5e_destroy_rqt(priv, MLX5E_SINGLE_RQ_RQT);
--
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