* [PATCH 2/2] pcmcia: remove pcmcia_request_exclusive_irq
From: Arnd Bergmann @ 2014-11-20 15:21 UTC (permalink / raw)
To: netdev; +Cc: Jeff Kirsher, Roger Pao, linux-kernel, linux-pcmcia
In-Reply-To: <4353896.15JnC91eLO@wuerfel>
The last user of the deprecated pcmcia_request_exclusive_irq function,
was removed in 5f5316fcd08e ("am2150: Update nmclan_cs.c to use update
PCMCIA API"), so we can clean up the core code and remove the interface
and its documentation.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
Documentation/pcmcia/driver-changes.txt | 3 ---
drivers/pcmcia/pcmcia_resource.c | 39 ---------------------------------------
include/pcmcia/ds.h | 10 ----------
3 files changed, 0 insertions(+), 52 deletions(-)
---
The patch that removed the last user was merged in 3.18-rc1, so this
should be safe to apply independently now.
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt
index dd04361dd361..78355c4c268a 100644
--- a/Documentation/pcmcia/driver-changes.txt
+++ b/Documentation/pcmcia/driver-changes.txt
@@ -46,9 +46,6 @@ This file details changes in 2.6 which affect PCMCIA card driver authors:
- use pcmcia_request_irq(p_dev, handler_t); the PCMCIA core will
clean up automatically on calls to pcmcia_disable_device() or
device ejection.
- - drivers still not capable of IRQF_SHARED (or not telling us so) may
- use the deprecated pcmcia_request_exclusive_irq() for the time
- being; they might receive a shared IRQ nonetheless.
* no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33)
Instead of the cs_error() callback or the CS_CHECK() macro, please use
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index e8c19def1b0f..23a123da3dd7 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -712,45 +712,6 @@ int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
}
EXPORT_SYMBOL(pcmcia_request_irq);
-
-/**
- * pcmcia_request_exclusive_irq() - attempt to request an exclusive IRQ first
- * @p_dev: the associated PCMCIA device
- * @handler: IRQ handler to register
- *
- * pcmcia_request_exclusive_irq() is a wrapper around request_irq() which
- * attempts first to request an exclusive IRQ. If it fails, it also accepts
- * a shared IRQ, but prints out a warning. PCMCIA drivers should allow for
- * IRQ sharing and either use request_irq directly (then they need to call
- * free_irq() themselves, too), or the pcmcia_request_irq() function.
- */
-int __must_check
-__pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev,
- irq_handler_t handler)
-{
- int ret;
-
- if (!p_dev->irq)
- return -EINVAL;
-
- ret = request_irq(p_dev->irq, handler, 0, p_dev->devname, p_dev->priv);
- if (ret) {
- ret = pcmcia_request_irq(p_dev, handler);
- dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: "
- "request for exclusive IRQ could not be fulfilled.\n");
- dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver "
- "needs updating to supported shared IRQ lines.\n");
- }
- if (ret)
- dev_printk(KERN_INFO, &p_dev->dev, "request_irq() failed\n");
- else
- p_dev->_irq = 1;
-
- return ret;
-} /* pcmcia_request_exclusive_irq */
-EXPORT_SYMBOL(__pcmcia_request_exclusive_irq);
-
-
#ifdef CONFIG_PCMCIA_PROBE
/* mask of IRQs already reserved by other cards, we should avoid using them */
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index 2d56e428506c..3037157855f0 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -206,16 +206,6 @@ int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val);
/* device configuration */
int pcmcia_request_io(struct pcmcia_device *p_dev);
-int __must_check
-__pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev,
- irq_handler_t handler);
-static inline __must_check __deprecated int
-pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev,
- irq_handler_t handler)
-{
- return __pcmcia_request_exclusive_irq(p_dev, handler);
-}
-
int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
irq_handler_t handler);
^ permalink raw reply related
* Re: Question on bulk dequeue support in virtual drivers
From: Eric Dumazet @ 2014-11-20 15:26 UTC (permalink / raw)
To: James Yonan; +Cc: Linux Netdev List
In-Reply-To: <546DE110.8060607@openvpn.net>
On Thu, 2014-11-20 at 05:39 -0700, James Yonan wrote:
> Consider a tunneling driver that receives packets in ndo_start_xmit,
> encapsulates them in UDP, and forwards via ip_local_out. The
> ndo_start_xmit implementation can implement bulking by looking at
> skb->xmit_more. But then how to efficiently transmit the resulting
> bulked list of encapsulated packets via UDP, so that the packets both
> enter and leave the driver in bulked form? Is there an ip_local_out
> alternative for bulked skb lists?
There is no such thing. Quite frankly it wont happen. Consider IP stacks
and netfilter, there is no provision for batches (other than GSO/TSO)
xmit_more addresses a specific hardware problem, it is not an
alternative for batches.
xmit_more will happen in your case in the last step, from qdisc to
ethernet device.
^ permalink raw reply
* Re: [PATCH v2 net-next] tcp: make connect() mem charging friendly
From: Eric Dumazet @ 2014-11-20 15:33 UTC (permalink / raw)
To: David Miller; +Cc: ycheng, nuclearcat, netdev, ncardwell
In-Reply-To: <20141119.145741.1905980604994551607.davem@davemloft.net>
On Wed, 2014-11-19 at 14:57 -0500, David Miller wrote:
> From: Yuchung Cheng <ycheng@google.com>
> >
> > Thanks! this simplifies the code a lot.
>
> Agreed, applied, thanks everyone!
BTW, unless I am mistaken, it seems we can probably replace
memcpy_fromiovecend() by memcpy_fromiovec() and delete from
tcp_sendmsg() the annoying code skipping over the already consumed
bytes.
Something like this untested patch :
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index c239f4740d10b10b67ef4fa44c831851fb9e1dcf..227540eef9d0870721258f9ddbace27b417c619e 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1089,20 +1089,19 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb;
int iovlen, flags, err, copied = 0;
- int mss_now = 0, size_goal, copied_syn = 0, offset = 0;
+ int mss_now = 0, size_goal, copied_syn = 0;
bool sg;
long timeo;
lock_sock(sk);
flags = msg->msg_flags;
- if (flags & MSG_FASTOPEN) {
+ if (unlikely(flags & MSG_FASTOPEN)) {
err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size);
if (err == -EINPROGRESS && copied_syn > 0)
goto out;
else if (err)
goto out_err;
- offset = copied_syn;
}
timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
@@ -1151,15 +1150,6 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
unsigned char __user *from = iov->iov_base;
iov++;
- if (unlikely(offset > 0)) { /* Skip bytes copied in SYN */
- if (offset >= seglen) {
- offset -= seglen;
- continue;
- }
- seglen -= offset;
- from += offset;
- offset = 0;
- }
while (seglen > 0) {
int copy = 0;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index f5bd4bd3f7e669b3fd48a843d55e7313a30a3409..524e5b657e881a348f11def3f48f29a76f54fbab 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -3049,8 +3049,8 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
goto fallback;
syn_data->ip_summed = CHECKSUM_PARTIAL;
memcpy(syn_data->cb, syn->cb, sizeof(syn->cb));
- if (unlikely(memcpy_fromiovecend(skb_put(syn_data, space),
- fo->data->msg_iov, 0, space))) {
+ if (unlikely(memcpy_fromiovec(skb_put(syn_data, space),
+ fo->data->msg_iov, space))) {
kfree_skb(syn_data);
goto fallback;
}
^ permalink raw reply related
* [PATCH 1/1] net: brcm80211: Deletion of unnecessary checks before two function calls
From: SF Markus Elfring @ 2014-11-20 15:50 UTC (permalink / raw)
To: Arend van Spriel, Brett Rudley, Franky (Zhenhui) Lin,
Hante Meuleman, John W. Linville, linux-wireless,
brcm80211-dev-list, netdev
Cc: LKML, kernel-janitors, Julia Lawall
In-Reply-To: <5317A59D.4@users.sourceforge.net>
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 20 Nov 2014 16:42:51 +0100
The functions brcmu_pkt_buf_free_skb() and release_firmware() test whether
their argument is NULL and then return immediately. Thus the test around
the call is not needed.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 3 +--
drivers/net/wireless/brcm80211/brcmfmac/firmware.c | 3 +--
drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c | 3 +--
drivers/net/wireless/brcm80211/brcmsmac/main.c | 3 +--
4 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index f55f625..8ff7037 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -2539,8 +2539,7 @@ static void brcmf_sdio_bus_stop(struct device *dev)
brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
/* Clear any held glomming stuff */
- if (bus->glomd)
- brcmu_pkt_buf_free_skb(bus->glomd);
+ brcmu_pkt_buf_free_skb(bus->glomd);
brcmf_sdio_free_glom(bus);
/* Clear rx control and wake any waiters */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
index 8ea9f28..3a2d014 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
@@ -262,8 +262,7 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
fail:
brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
- if (fwctx->code)
- release_firmware(fwctx->code);
+ release_firmware(fwctx->code);
device_release_driver(fwctx->dev);
kfree(fwctx);
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
index 8f8b937..0cb00dc 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -506,8 +506,7 @@ static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
memcpy(buf, skb->data, (len < msgbuf->ioctl_resp_ret_len) ?
len : msgbuf->ioctl_resp_ret_len);
}
- if (skb)
- brcmu_pkt_buf_free_skb(skb);
+ brcmu_pkt_buf_free_skb(skb);
return msgbuf->ioctl_resp_status;
}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 1b47482..ce538a1 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -1009,8 +1009,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
if (txh)
trace_brcms_txdesc(&wlc->hw->d11core->dev, txh,
sizeof(*txh));
- if (p)
- brcmu_pkt_buf_free_skb(p);
+ brcmu_pkt_buf_free_skb(p);
}
if (dma && queue < NFIFO) {
--
2.1.3
^ permalink raw reply related
* Re: [patch net-next v2 02/10] net: introduce generic switch devices support
From: Andy Gospodarek @ 2014-11-20 15:55 UTC (permalink / raw)
To: Roopa Prabhu
Cc: Jiri Pirko, netdev, davem, nhorman, andy, tgraf, dborkman,
ogerlitz, jesse, pshelar, azhou, ben, stephen, jeffrey.t.kirsher,
vyasevic, xiyou.wangcong, john.r.fastabend, edumazet, jhs,
sfeldma, f.fainelli, linville, jasowang, ebiederm,
nicolas.dichtel, ryazanov.s.a, buytenh, aviadr, nbd,
alexei.starovoitov, Neil.Jerram, ronye, simon.horman,
alexander.h.duyck, john.ronciak, mleitner, shrijeet, bcrl
In-Reply-To: <546CA237.3010600@cumulusnetworks.com>
On Wed, Nov 19, 2014 at 05:59:19AM -0800, Roopa Prabhu wrote:
> On 11/19/14, 5:46 AM, Jiri Pirko wrote:
> >Wed, Nov 19, 2014 at 02:28:10PM CET, roopa@cumulusnetworks.com wrote:
> >>On 11/9/14, 2:51 AM, Jiri Pirko wrote:
> >>>The goal of this is to provide a possibility to support various switch
> >>>chips. Drivers should implement relevant ndos to do so. Now there is
> >>>only one ndo defined:
> >>>- for getting physical switch id is in place.
> >>>
> >>>Note that user can use random port netdevice to access the switch.
> >>>
> >>>Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> >>>---
> >>> Documentation/networking/switchdev.txt | 59 ++++++++++++++++++++++++++++++++++
> >>> MAINTAINERS | 7 ++++
> >>> include/linux/netdevice.h | 10 ++++++
> >>> include/net/switchdev.h | 30 +++++++++++++++++
> >>> net/Kconfig | 1 +
> >>> net/Makefile | 3 ++
> >>> net/switchdev/Kconfig | 13 ++++++++
> >>> net/switchdev/Makefile | 5 +++
> >>> net/switchdev/switchdev.c | 33 +++++++++++++++++++
> >>> 9 files changed, 161 insertions(+)
> >>> create mode 100644 Documentation/networking/switchdev.txt
> >>> create mode 100644 include/net/switchdev.h
> >>> create mode 100644 net/switchdev/Kconfig
> >>> create mode 100644 net/switchdev/Makefile
> >>> create mode 100644 net/switchdev/switchdev.c
> >>>
> >>>diff --git a/Documentation/networking/switchdev.txt b/Documentation/networking/switchdev.txt
> >>>new file mode 100644
> >>>index 0000000..98be76c
> >>>--- /dev/null
> >>>+++ b/Documentation/networking/switchdev.txt
> >>>@@ -0,0 +1,59 @@
> >>>+Switch (and switch-ish) device drivers HOWTO
> >>>+===========================
> >>>+
> >>>+Please note that the word "switch" is here used in very generic meaning.
> >>>+This include devices supporting L2/L3 but also various flow offloading chips,
> >>>+including switches embedded into SR-IOV NICs.
> >>>+
> >>>+Lets describe a topology a bit. Imagine the following example:
> >>>+
> >>>+ +----------------------------+ +---------------+
> >>>+ | SOME switch chip | | CPU |
> >>>+ +----------------------------+ +---------------+
> >>>+ port1 port2 port3 port4 MNGMNT | PCI-E |
> >>>+ | | | | | +---------------+
> >>>+ PHY PHY | | | | NIC0 NIC1
> >>>+ | | | | | |
> >>>+ | | +- PCI-E -+ | |
> >>>+ | +------- MII -------+ |
> >>>+ +------------- MII ------------+
> >>>+
> >>>+In this example, there are two independent lines between the switch silicon
> >>>+and CPU. NIC0 and NIC1 drivers are not aware of a switch presence. They are
> >>>+separate from the switch driver. SOME switch chip is by managed by a driver
> >>>+via PCI-E device MNGMNT. Note that MNGMNT device, NIC0 and NIC1 may be
> >>>+connected to some other type of bus.
> >>>+
> >>>+Now, for the previous example show the representation in kernel:
> >>>+
> >>>+ +----------------------------+ +---------------+
> >>>+ | SOME switch chip | | CPU |
> >>>+ +----------------------------+ +---------------+
> >>>+ sw0p0 sw0p1 sw0p2 sw0p3 MNGMNT | PCI-E |
> >>>+ | | | | | +---------------+
> >>>+ PHY PHY | | | | eth0 eth1
> >>>+ | | | | | |
> >>>+ | | +- PCI-E -+ | |
> >>>+ | +------- MII -------+ |
> >>>+ +------------- MII ------------+
> >>>+
> >>>+Lets call the example switch driver for SOME switch chip "SOMEswitch". This
> >>>+driver takes care of PCI-E device MNGMNT. There is a netdevice instance sw0pX
> >>>+created for each port of a switch. These netdevices are instances
> >>>+of "SOMEswitch" driver. sw0pX netdevices serve as a "representation"
> >>>+of the switch chip. eth0 and eth1 are instances of some other existing driver.
> >>>+
> >>>+The only difference of the switch-port netdevice from the ordinary netdevice
> >>>+is that is implements couple more NDOs:
> >>>+
> >>>+ ndo_sw_parent_get_id - This returns the same ID for two port netdevices
> >>>+ of the same physical switch chip. This is
> >>>+ mandatory to be implemented by all switch drivers
> >>>+ and serves the caller for recognition of a port
> >>>+ netdevice.
> >>>+ ndo_sw_parent_* - Functions that serve for a manipulation of the switch
> >>>+ chip itself (it can be though of as a "parent" of the
> >>>+ port, therefore the name). They are not port-specific.
> >>>+ Caller might use arbitrary port netdevice of the same
> >>>+ switch and it will make no difference.
> >>>+ ndo_sw_port_* - Functions that serve for a port-specific manipulation.
> >>>diff --git a/MAINTAINERS b/MAINTAINERS
> >>>index 3a41fb0..776e078 100644
> >>>--- a/MAINTAINERS
> >>>+++ b/MAINTAINERS
> >>>@@ -9003,6 +9003,13 @@ F: lib/swiotlb.c
> >>> F: arch/*/kernel/pci-swiotlb.c
> >>> F: include/linux/swiotlb.h
> >>>+SWITCHDEV
> >>>+M: Jiri Pirko <jiri@resnulli.us>
> >>>+L: netdev@vger.kernel.org
> >>>+S: Supported
> >>>+F: net/switchdev/
> >>>+F: include/net/switchdev.h
> >>>+
> >>> SYNOPSYS ARC ARCHITECTURE
> >>> M: Vineet Gupta <vgupta@synopsys.com>
> >>> S: Supported
> >>>diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> >>>index 71922e0..97eade9 100644
> >>>--- a/include/linux/netdevice.h
> >>>+++ b/include/linux/netdevice.h
> >>>@@ -1017,6 +1017,12 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
> >>> * performing GSO on a packet. The device returns true if it is
> >>> * able to GSO the packet, false otherwise. If the return value is
> >>> * false the stack will do software GSO.
> >>>+ *
> >>>+ * int (*ndo_sw_parent_id_get)(struct net_device *dev,
> >>>+ * struct netdev_phys_item_id *psid);
> >>>+ * Called to get an ID of the switch chip this port is part of.
> >>>+ * If driver implements this, it indicates that it represents a port
> >>>+ * of a switch chip.
> >>> */
> >>> struct net_device_ops {
> >>> int (*ndo_init)(struct net_device *dev);
> >>>@@ -1168,6 +1174,10 @@ struct net_device_ops {
> >>> int (*ndo_get_lock_subclass)(struct net_device *dev);
> >>> bool (*ndo_gso_check) (struct sk_buff *skb,
> >>> struct net_device *dev);
> >>>+#ifdef CONFIG_NET_SWITCHDEV
> >>>+ int (*ndo_sw_parent_id_get)(struct net_device *dev,
> >>>+ struct netdev_phys_item_id *psid);
> >>Can we keep the name generic and not include "sw" which implies switch here
> >>?.
> >>I understand that it is under CONFIG_NET_SWITCHDEV but we might find use for
> >>them in other offload scenarios in the future.
> >>This particular ndo can be just ndo_parent_id_get().
> >>And the others that do specific offloads can have "offload" in them if
> >>required..?.
> >
> >But this is for getting parent switch id, sw should be there.
>
> Since we have not figured out the details or namespace for switchd ids yet,
> its still some parent id to me.
>
> >If comes a
> >time when this might be reused to something else, we change it then.
> >This is internal api, easily changeable.
> also, "sw" seems more "software" than "switch".
I had voiced this same concern when we met and discussed this in
Dusseldorf. Let's move to another name such as 'hw' (since we really
are talking about hardware abstraction) or 'offload.' Just using 'sw'
is confusing as many will not read it as switch.
I'll be happy to post a fix based on your devel patches.
>
> >
> >>
> >>
> >>>+#endif
> >>> };
> >>> /**
> >>>diff --git a/include/net/switchdev.h b/include/net/switchdev.h
> >>>new file mode 100644
> >>>index 0000000..79bf9bd
> >>>--- /dev/null
> >>>+++ b/include/net/switchdev.h
> >>>@@ -0,0 +1,30 @@
> >>>+/*
> >>>+ * include/net/switchdev.h - Switch device API
> >>>+ * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us>
> >>>+ *
> >>>+ * This program is free software; you can redistribute it and/or modify
> >>>+ * it under the terms of the GNU General Public License as published by
> >>>+ * the Free Software Foundation; either version 2 of the License, or
> >>>+ * (at your option) any later version.
> >>>+ */
> >>>+#ifndef _LINUX_SWITCHDEV_H_
> >>>+#define _LINUX_SWITCHDEV_H_
> >>>+
> >>>+#include <linux/netdevice.h>
> >>>+
> >>>+#ifdef CONFIG_NET_SWITCHDEV
> >>>+
> >>>+int netdev_sw_parent_id_get(struct net_device *dev,
> >>>+ struct netdev_phys_item_id *psid);
> >>>+
> >>>+#else
> >>>+
> >>>+static inline int netdev_sw_parent_id_get(struct net_device *dev,
> >>>+ struct netdev_phys_item_id *psid)
> >>>+{
> >>>+ return -EOPNOTSUPP;
> >>>+}
> >>>+
> >>>+#endif
> >>>+
> >>>+#endif /* _LINUX_SWITCHDEV_H_ */
> >>>diff --git a/net/Kconfig b/net/Kconfig
> >>>index 99815b5..ff9ffc1 100644
> >>>--- a/net/Kconfig
> >>>+++ b/net/Kconfig
> >>>@@ -228,6 +228,7 @@ source "net/vmw_vsock/Kconfig"
> >>> source "net/netlink/Kconfig"
> >>> source "net/mpls/Kconfig"
> >>> source "net/hsr/Kconfig"
> >>>+source "net/switchdev/Kconfig"
> >>> config RPS
> >>> boolean
> >>>diff --git a/net/Makefile b/net/Makefile
> >>>index 7ed1970..95fc694 100644
> >>>--- a/net/Makefile
> >>>+++ b/net/Makefile
> >>>@@ -73,3 +73,6 @@ obj-$(CONFIG_OPENVSWITCH) += openvswitch/
> >>> obj-$(CONFIG_VSOCKETS) += vmw_vsock/
> >>> obj-$(CONFIG_NET_MPLS_GSO) += mpls/
> >>> obj-$(CONFIG_HSR) += hsr/
> >>>+ifneq ($(CONFIG_NET_SWITCHDEV),)
> >>>+obj-y += switchdev/
> >>>+endif
> >>>diff --git a/net/switchdev/Kconfig b/net/switchdev/Kconfig
> >>>new file mode 100644
> >>>index 0000000..1557545
> >>>--- /dev/null
> >>>+++ b/net/switchdev/Kconfig
> >>>@@ -0,0 +1,13 @@
> >>>+#
> >>>+# Configuration for Switch device support
> >>>+#
> >>>+
> >>>+config NET_SWITCHDEV
> >>>+ boolean "Switch (and switch-ish) device support (EXPERIMENTAL)"
> >>>+ depends on INET
> >>>+ ---help---
> >>>+ This module provides glue between core networking code and device
> >>>+ drivers in order to support hardware switch chips in very generic
> >>>+ meaning of the word "switch". This include devices supporting L2/L3 but
> >>>+ also various flow offloading chips, including switches embedded into
> >>>+ SR-IOV NICs.
> >>>diff --git a/net/switchdev/Makefile b/net/switchdev/Makefile
> >>>new file mode 100644
> >>>index 0000000..5ed63ed
> >>>--- /dev/null
> >>>+++ b/net/switchdev/Makefile
> >>>@@ -0,0 +1,5 @@
> >>>+#
> >>>+# Makefile for the Switch device API
> >>>+#
> >>>+
> >>>+obj-$(CONFIG_NET_SWITCHDEV) += switchdev.o
> >>>diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
> >>>new file mode 100644
> >>>index 0000000..5010f646
> >>>--- /dev/null
> >>>+++ b/net/switchdev/switchdev.c
> >>>@@ -0,0 +1,33 @@
> >>>+/*
> >>>+ * net/switchdev/switchdev.c - Switch device API
> >>>+ * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us>
> >>>+ *
> >>>+ * This program is free software; you can redistribute it and/or modify
> >>>+ * it under the terms of the GNU General Public License as published by
> >>>+ * the Free Software Foundation; either version 2 of the License, or
> >>>+ * (at your option) any later version.
> >>>+ */
> >>>+
> >>>+#include <linux/kernel.h>
> >>>+#include <linux/types.h>
> >>>+#include <linux/init.h>
> >>>+#include <linux/netdevice.h>
> >>>+#include <net/switchdev.h>
> >>>+
> >>>+/**
> >>>+ * netdev_sw_parent_id_get - Get ID of a switch
> >>>+ * @dev: port device
> >>>+ * @psid: switch ID
> >>>+ *
> >>>+ * Get ID of a switch this port is part of.
> >>>+ */
> >>>+int netdev_sw_parent_id_get(struct net_device *dev,
> >>>+ struct netdev_phys_item_id *psid)
> >>>+{
> >>>+ const struct net_device_ops *ops = dev->netdev_ops;
> >>>+
> >>>+ if (!ops->ndo_sw_parent_id_get)
> >>>+ return -EOPNOTSUPP;
> >>>+ return ops->ndo_sw_parent_id_get(dev, psid);
> >>>+}
> >>>+EXPORT_SYMBOL(netdev_sw_parent_id_get);
> >--
> >To unsubscribe from this list: send the line "unsubscribe netdev" in
> >the body of a message to majordomo@vger.kernel.org
> >More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH] net: team: expose sysfs attributes for each team option
From: Thomas Graf @ 2014-11-20 16:05 UTC (permalink / raw)
To: Hamad Kadmany
Cc: Cong Wang, Hamad Kadmany, Jiri Pirko, netdev, Daniel Borkmann
In-Reply-To: <546CECAD.1040402@redhat.com>
On 11/19/14 at 08:17pm, Daniel Borkmann wrote:
> On 11/19/2014 07:45 PM, Cong Wang wrote:
> >On Wed, Nov 19, 2014 at 4:28 AM, Hamad Kadmany <hkadmany@codeaurora.org> wrote:
> >>On Mon, November 17, 2014 1:02 pm, Jiri Pirko wrote:
> >>>
> >>>Nak.
> >>>
> >>>I don't like this patch. The plan for team was keep things simple and to
> >>>have single userspace api using netlink, as that is the correct way to
> >>>deal with things. Sysfs for this use-case is not. Please, use netlink api.
>
> +1
>
> >>Using team driver requires using libnl3. In Android based platforms, libnl3
> >> is not supported, and libnl3 license poses constraints in Android's user-space.
>
> Constraints?! libnl3 is LGPL ...
The behaviour on this particular topic is disappointing. Instead of
working with the community and using an existing library such as
libmnl or libnl Android chose to fork libnl3 and disregard the
community a couple of years ago.
The reasoning in this thread is the next episode of the same story.
Very disappointing.
^ permalink raw reply
* Re: [PATCH 00/10] net: phy: add device-type abstraction
From: Florian Fainelli @ 2014-11-20 16:18 UTC (permalink / raw)
To: Johan Hovold
Cc: David S. Miller, netdev, linux-kernel, Bruno Thomsen,
Sascha Hauer, Mark Rutland
In-Reply-To: <1416398363-32306-1-git-send-email-johan@kernel.org>
On 11/19/2014 03:59 AM, Johan Hovold wrote:
> This series adds device and device-type abstractions to the micrel
> driver, and enables support for RMII-reference clock selection for
> KSZ8081 and KSZ8091 devices.
>
> While adding support for more features for the Micrel PHYs mentioned
> above, it became apparent that the configuration space is much too large
> and that adding type-specific callbacks will simply not scale. Instead I
> added a driver_data field to struct phy_device, which can be used to
> store static device type data that can be parsed and acted on in
> generic driver callbacks. This allows a lot of duplicated code to be
> removed, and should make it much easier to add new features or deal with
> device-type quirks in the future.
>
> The series has been tested on a dual KSZ8081 setup. Further testing on
> other Micrel PHYs would be much appreciated.
>
> The recent commit a95a18afe4c8 ("phy/micrel: KSZ8031RNL RMII clock
> reconfiguration bug") currently prevents KSZ8031 PHYs from using the
> generic config-init. Bruno, who is the author of that patch, has agreed
> to test this series and some follow-up diagnostic patches to determine
> how best to incorporate these devices as well. I intend to send a
> follow-up patch that removes the custom 8031 config-init and documents
> this quirk, but the current series can be applied meanwhile.
>
> These patches are against net-next which contains some already merged
> prerequisite patches to the driver.
LGTM, thanks Johan!
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
>
> Johan
>
>
> Johan Hovold (10):
> net: phy: add static data field to struct phy_driver
> net: phy: micrel: add device-type abstraction
> net: phy: micrel: parse of nodes at probe
> net: phy: micrel: add has-broadcast-disable flag to type data
> net: phy: micrel: add generic clock-mode-select support
> net: phy: micrel: add support for clock-mode select to KSZ8081/KSZ8091
> dt/bindings: reformat micrel eth-phy documentation
> dt/bindings: add clock-select function property to micrel phy binding
> net: phy: micrel: refactor interrupt config
> net: phy: micrel: add copyright entry
>
> Documentation/devicetree/bindings/net/micrel.txt | 37 ++--
> drivers/net/phy/micrel.c | 262 ++++++++++++++---------
> include/linux/micrel_phy.h | 1 -
> include/linux/phy.h | 2 +
> 4 files changed, 184 insertions(+), 118 deletions(-)
>
^ permalink raw reply
* [PATCH net-next] tcp: remove from tcp_sendmsg() some fastopen code
From: Eric Dumazet @ 2014-11-20 16:23 UTC (permalink / raw)
To: David Miller; +Cc: ycheng, nuclearcat, netdev, ncardwell
In-Reply-To: <1416497628.8629.24.camel@edumazet-glaptop2.roam.corp.google.com>
From: Eric Dumazet <edumazet@google.com>
If we consume iovec bytes in tcp_send_syn_data(), we can remove
annoying fastopen code in tcp_sendmsg() skipping over the already
consumed bytes.
Also add an unlikely(flags & MSG_FASTOPEN), as most TCP sendmsg() do not
ask for FASTOPEN.
Tested:
Ran our 125 packetdrill fastopen tests
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/ipv4/tcp.c | 14 ++------------
net/ipv4/tcp_output.c | 4 ++--
2 files changed, 4 insertions(+), 14 deletions(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index c239f4740d10b10b67ef4fa44c831851fb9e1dcf..227540eef9d0870721258f9ddbace27b417c619e 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1089,20 +1089,19 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb;
int iovlen, flags, err, copied = 0;
- int mss_now = 0, size_goal, copied_syn = 0, offset = 0;
+ int mss_now = 0, size_goal, copied_syn = 0;
bool sg;
long timeo;
lock_sock(sk);
flags = msg->msg_flags;
- if (flags & MSG_FASTOPEN) {
+ if (unlikely(flags & MSG_FASTOPEN)) {
err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size);
if (err == -EINPROGRESS && copied_syn > 0)
goto out;
else if (err)
goto out_err;
- offset = copied_syn;
}
timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
@@ -1151,15 +1150,6 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
unsigned char __user *from = iov->iov_base;
iov++;
- if (unlikely(offset > 0)) { /* Skip bytes copied in SYN */
- if (offset >= seglen) {
- offset -= seglen;
- continue;
- }
- seglen -= offset;
- from += offset;
- offset = 0;
- }
while (seglen > 0) {
int copy = 0;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index f5bd4bd3f7e669b3fd48a843d55e7313a30a3409..524e5b657e881a348f11def3f48f29a76f54fbab 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -3049,8 +3049,8 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
goto fallback;
syn_data->ip_summed = CHECKSUM_PARTIAL;
memcpy(syn_data->cb, syn->cb, sizeof(syn->cb));
- if (unlikely(memcpy_fromiovecend(skb_put(syn_data, space),
- fo->data->msg_iov, 0, space))) {
+ if (unlikely(memcpy_fromiovec(skb_put(syn_data, space),
+ fo->data->msg_iov, space))) {
kfree_skb(syn_data);
goto fallback;
}
^ permalink raw reply related
* Re: [PATCH net-next 1/4] net: allow large number of rx queues
From: Pankaj Gupta @ 2014-11-20 16:31 UTC (permalink / raw)
To: Cong Wang
Cc: linux-kernel, netdev, David Miller, Jason Wang,
Michael S. Tsirkin, dgibson, vfalico, Eric Dumazet,
Vladislav Yasevich, Jerry Chu, wuzhy, Pavel Emelyanov,
Tom Herbert, bhutchings, xii, Stephen Hemminger,
Jiří Pírko, sergei shtylyov
In-Reply-To: <CAHA+R7MnLy=8uL_hSnx=BN2QTs2kvempTxtmSO6hjcS+E0yRwg@mail.gmail.com>
> On Tue, Nov 18, 2014 at 8:22 AM, Pankaj Gupta <pagupta@redhat.com> wrote:
> >
> > As vmalloc() adds overhead on a critical network path,
> > __GFP_REPEAT flag is used with kzalloc() to do this fallback
> > only when really needed.
> >
>
> Are you sure we need __GFP_REPEAT? We have vmalloc() as
> fallback of kmalloc() in many places of networking (grep kvfree),
> none of those I checked has this flag set.
Its there in netif_alloc_netdev_queues() function in same file.
Also, I found it some other places as well.
I think its good to have.
>
^ permalink raw reply
* [PATCH net-next v1 0/8] amd-xgbe: AMD XGBE driver updates 2014-11-20
From: Tom Lendacky @ 2014-11-20 17:03 UTC (permalink / raw)
To: netdev; +Cc: David Miller
The following series of patches includes functional updates to the
driver as well as some trivial changes.
- Add a read memory barrier in the Tx and Rx path after checking the
descriptor ownership bit
- Wait for the Tx engine to stop/suspend before issuing a stop command
- Implement a smatch tool suggestion to simplify an if statement
- Separate out Tx and Rx ring data fields into their own structures
- Add BQL support
- Remove an unused variable
- Change Tx coalescing support to operate on packet basis instead of
a descriptor basis
- Add support for the skb->xmit_more flag
This patch series is based on net-next.
---
Tom Lendacky (8):
amd-xgbe: Add a read memory barrier to Tx/Rx path
amd-xgbe: Tx engine must not be active before stopping it
amd-xgbe: Incorporate Smatch coding suggestion
amd-xgbe: Separate Tx/Rx ring data fields into new structs
amd-xgbe: Add BQL support
amd-xgbe: Remove unused variable
amd-xgbe: Perform Tx coalescing on a packet basis
amd-xgbe: Add support for the skb->xmit_more flag
drivers/net/ethernet/amd/xgbe/xgbe-common.h | 21 ++-
drivers/net/ethernet/amd/xgbe/xgbe-desc.c | 40 +++---
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 170 +++++++++++++++++++++------
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 112 ++++++++++++++----
drivers/net/ethernet/amd/xgbe/xgbe.h | 42 ++++++-
5 files changed, 289 insertions(+), 96 deletions(-)
--
Tom Lendacky
^ permalink raw reply
* [PATCH net-next v1 1/8] amd-xgbe: Add a read memory barrier to Tx/Rx path
From: Tom Lendacky @ 2014-11-20 17:03 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <20141120170320.15397.10583.stgit@tlendack-t1.amdoffice.net>
Add a read memory barrier to the Tx and Rx paths where the ownership
bit is checked to be sure that all descriptor fields are read after
having read the ownership bit for the descriptor.
This has not been an issue to date, but it's a good safe-guard to have.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +++
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 4 ++++
2 files changed, 7 insertions(+)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index f6014d3..9b1d9fa 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1558,6 +1558,9 @@ static int xgbe_dev_read(struct xgbe_channel *channel)
if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, OWN))
return 1;
+ /* Make sure descriptor fields are read after reading the OWN bit */
+ rmb();
+
#ifdef XGMAC_ENABLE_RX_DESC_DUMP
xgbe_dump_rx_desc(ring, rdesc, ring->cur);
#endif
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 0544931..eebb787 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -1791,6 +1791,10 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
if (!hw_if->tx_complete(rdesc))
break;
+ /* Make sure descriptor fields are read after reading the OWN
+ * bit */
+ rmb();
+
#ifdef XGMAC_ENABLE_TX_DESC_DUMP
xgbe_dump_tx_desc(ring, ring->dirty, 1, 0);
#endif
^ permalink raw reply related
* [PATCH net-next v1 2/8] amd-xgbe: Tx engine must not be active before stopping it
From: Tom Lendacky @ 2014-11-20 17:03 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <20141120170320.15397.10583.stgit@tlendack-t1.amdoffice.net>
If the Tx engine is told to stop while it is actively processing Tx
descriptors it is possible that the Tx descriptor(s) will not be closed
out properly. When the Tx engine is restarted this could result in the
driver being stuck on the improperly closed descriptor.
Update the driver to wait for the Tx engine to be in a stopped or
suspended state before issuing the stop command.
This has not been an issue to date, but it's a good safe-guard to have.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-common.h | 21 ++++++----
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 59 +++++++++++++++++++++++++++
drivers/net/ethernet/amd/xgbe/xgbe.h | 1
3 files changed, 74 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
index 2fe8fc7..75b08c6 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
@@ -125,9 +125,6 @@
#define DMA_AXIAWCR 0x3018
#define DMA_DSR0 0x3020
#define DMA_DSR1 0x3024
-#define DMA_DSR2 0x3028
-#define DMA_DSR3 0x302c
-#define DMA_DSR4 0x3030
/* DMA register entry bit positions and sizes */
#define DMA_AXIARCR_DRC_INDEX 0
@@ -158,10 +155,6 @@
#define DMA_AXIAWCR_TDC_WIDTH 4
#define DMA_AXIAWCR_TDD_INDEX 28
#define DMA_AXIAWCR_TDD_WIDTH 2
-#define DMA_DSR0_RPS_INDEX 8
-#define DMA_DSR0_RPS_WIDTH 4
-#define DMA_DSR0_TPS_INDEX 12
-#define DMA_DSR0_TPS_WIDTH 4
#define DMA_ISR_MACIS_INDEX 17
#define DMA_ISR_MACIS_WIDTH 1
#define DMA_ISR_MTLIS_INDEX 16
@@ -175,6 +168,20 @@
#define DMA_SBMR_UNDEF_INDEX 0
#define DMA_SBMR_UNDEF_WIDTH 1
+/* DMA register values */
+#define DMA_DSR_RPS_WIDTH 4
+#define DMA_DSR_TPS_WIDTH 4
+#define DMA_DSR_Q_WIDTH (DMA_DSR_RPS_WIDTH + DMA_DSR_TPS_WIDTH)
+#define DMA_DSR0_RPS_START 8
+#define DMA_DSR0_TPS_START 12
+#define DMA_DSRX_FIRST_QUEUE 3
+#define DMA_DSRX_INC 4
+#define DMA_DSRX_QPR 4
+#define DMA_DSRX_RPS_START 0
+#define DMA_DSRX_TPS_START 4
+#define DMA_TPS_STOPPED 0x00
+#define DMA_TPS_SUSPENDED 0x06
+
/* DMA channel register offsets
* Multiple channels can be active. The first channel has registers
* that begin at 0x3100. Each subsequent channel has registers that
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index 9b1d9fa..dcd0347 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -2453,6 +2453,47 @@ static void xgbe_config_mmc(struct xgbe_prv_data *pdata)
XGMAC_IOWRITE_BITS(pdata, MMC_CR, CR, 1);
}
+static void xgbe_prepare_tx_stop(struct xgbe_prv_data *pdata,
+ struct xgbe_channel *channel)
+{
+ unsigned int tx_dsr, tx_pos, tx_qidx;
+ unsigned int tx_status;
+ unsigned long tx_timeout;
+
+ /* Calculate the status register to read and the position within */
+ if (channel->queue_index < DMA_DSRX_FIRST_QUEUE) {
+ tx_dsr = DMA_DSR0;
+ tx_pos = (channel->queue_index * DMA_DSR_Q_WIDTH) +
+ DMA_DSR0_TPS_START;
+ } else {
+ tx_qidx = channel->queue_index - DMA_DSRX_FIRST_QUEUE;
+
+ tx_dsr = DMA_DSR1 + ((tx_qidx / DMA_DSRX_QPR) * DMA_DSRX_INC);
+ tx_pos = ((tx_qidx % DMA_DSRX_QPR) * DMA_DSR_Q_WIDTH) +
+ DMA_DSRX_TPS_START;
+ }
+
+ /* The Tx engine cannot be stopped if it is actively processing
+ * descriptors. Wait for the Tx engine to enter the stopped or
+ * suspended state. Don't wait forever though...
+ */
+ tx_timeout = jiffies + (XGBE_DMA_STOP_TIMEOUT * HZ);
+ while (time_before(jiffies, tx_timeout)) {
+ tx_status = XGMAC_IOREAD(pdata, tx_dsr);
+ tx_status = GET_BITS(tx_status, tx_pos, DMA_DSR_TPS_WIDTH);
+ if ((tx_status == DMA_TPS_STOPPED) ||
+ (tx_status == DMA_TPS_SUSPENDED))
+ break;
+
+ usleep_range(500, 1000);
+ }
+
+ if (!time_before(jiffies, tx_timeout))
+ netdev_info(pdata->netdev,
+ "timed out waiting for Tx DMA channel %u to stop\n",
+ channel->queue_index);
+}
+
static void xgbe_enable_tx(struct xgbe_prv_data *pdata)
{
struct xgbe_channel *channel;
@@ -2481,6 +2522,15 @@ static void xgbe_disable_tx(struct xgbe_prv_data *pdata)
struct xgbe_channel *channel;
unsigned int i;
+ /* Prepare for Tx DMA channel stop */
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->tx_ring)
+ break;
+
+ xgbe_prepare_tx_stop(pdata, channel);
+ }
+
/* Disable MAC Tx */
XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 0);
@@ -2572,6 +2622,15 @@ static void xgbe_powerdown_tx(struct xgbe_prv_data *pdata)
struct xgbe_channel *channel;
unsigned int i;
+ /* Prepare for Tx DMA channel stop */
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->tx_ring)
+ break;
+
+ xgbe_prepare_tx_stop(pdata, channel);
+ }
+
/* Disable MAC Tx */
XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 0);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index 901fb1f..46ce544 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -147,6 +147,7 @@
#define XGBE_MAX_DMA_CHANNELS 16
#define XGBE_MAX_QUEUES 16
+#define XGBE_DMA_STOP_TIMEOUT 5
/* DMA cache settings - Outer sharable, write-back, write-allocate */
#define XGBE_DMA_OS_AXDOMAIN 0x2
^ permalink raw reply related
* [PATCH net-next v1 3/8] amd-xgbe: Incorporate Smatch coding suggestion
From: Tom Lendacky @ 2014-11-20 17:03 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Dan Carpenter
In-Reply-To: <20141120170320.15397.10583.stgit@tlendack-t1.amdoffice.net>
The Smatch tool indicated that one of the if statements in xgbe-dev.c
could be rewritten to remove a redundant check for the 'err' variable
in an if statement.
Change the statement as suggested and add a comment to help clarify.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index dcd0347..72425ff 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1633,7 +1633,8 @@ static int xgbe_dev_read(struct xgbe_channel *channel)
etlt = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, ETLT);
DBGPR(" err=%u, etlt=%#x\n", err, etlt);
- if (!err || (err && !etlt)) {
+ if (!err || !etlt) {
+ /* No error if err is 0 or etlt is 0 */
if ((etlt == 0x09) &&
(netdev->features & NETIF_F_HW_VLAN_CTAG_RX)) {
XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
^ permalink raw reply related
* [PATCH net-next v1 4/8] amd-xgbe: Separate Tx/Rx ring data fields into new structs
From: Tom Lendacky @ 2014-11-20 17:03 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <20141120170320.15397.10583.stgit@tlendack-t1.amdoffice.net>
Move the Tx and Rx related fields within the xgbe_ring_data struct into
their own structs in order to more easily see what fields are used for
each operation.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-desc.c | 36 ++++++++++++++---------------
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 14 ++++++-----
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 28 +++++++++++------------
drivers/net/ethernet/amd/xgbe/xgbe.h | 22 +++++++++++++-----
4 files changed, 54 insertions(+), 46 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
index e6b9f54..3c7c386 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
@@ -335,11 +335,11 @@ static int xgbe_map_rx_buffer(struct xgbe_prv_data *pdata,
}
/* Set up the header page info */
- xgbe_set_buffer_data(&rdata->rx_hdr, &ring->rx_hdr_pa,
+ xgbe_set_buffer_data(&rdata->rx.hdr, &ring->rx_hdr_pa,
XGBE_SKB_ALLOC_SIZE);
/* Set up the buffer page info */
- xgbe_set_buffer_data(&rdata->rx_buf, &ring->rx_buf_pa,
+ xgbe_set_buffer_data(&rdata->rx.buf, &ring->rx_buf_pa,
pdata->rx_buf_size);
return 0;
@@ -451,31 +451,29 @@ static void xgbe_unmap_rdata(struct xgbe_prv_data *pdata,
rdata->skb = NULL;
}
- if (rdata->rx_hdr.pa.pages)
- put_page(rdata->rx_hdr.pa.pages);
+ if (rdata->rx.hdr.pa.pages)
+ put_page(rdata->rx.hdr.pa.pages);
- if (rdata->rx_hdr.pa_unmap.pages) {
- dma_unmap_page(pdata->dev, rdata->rx_hdr.pa_unmap.pages_dma,
- rdata->rx_hdr.pa_unmap.pages_len,
+ if (rdata->rx.hdr.pa_unmap.pages) {
+ dma_unmap_page(pdata->dev, rdata->rx.hdr.pa_unmap.pages_dma,
+ rdata->rx.hdr.pa_unmap.pages_len,
DMA_FROM_DEVICE);
- put_page(rdata->rx_hdr.pa_unmap.pages);
+ put_page(rdata->rx.hdr.pa_unmap.pages);
}
- if (rdata->rx_buf.pa.pages)
- put_page(rdata->rx_buf.pa.pages);
+ if (rdata->rx.buf.pa.pages)
+ put_page(rdata->rx.buf.pa.pages);
- if (rdata->rx_buf.pa_unmap.pages) {
- dma_unmap_page(pdata->dev, rdata->rx_buf.pa_unmap.pages_dma,
- rdata->rx_buf.pa_unmap.pages_len,
+ if (rdata->rx.buf.pa_unmap.pages) {
+ dma_unmap_page(pdata->dev, rdata->rx.buf.pa_unmap.pages_dma,
+ rdata->rx.buf.pa_unmap.pages_len,
DMA_FROM_DEVICE);
- put_page(rdata->rx_buf.pa_unmap.pages);
+ put_page(rdata->rx.buf.pa_unmap.pages);
}
- memset(&rdata->rx_hdr, 0, sizeof(rdata->rx_hdr));
- memset(&rdata->rx_buf, 0, sizeof(rdata->rx_buf));
+ memset(&rdata->tx, 0, sizeof(rdata->tx));
+ memset(&rdata->rx, 0, sizeof(rdata->rx));
- rdata->tso_header = 0;
- rdata->len = 0;
rdata->interrupt = 0;
rdata->mapped_as_page = 0;
@@ -534,7 +532,7 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
}
rdata->skb_dma = skb_dma;
rdata->skb_dma_len = packet->header_len;
- rdata->tso_header = 1;
+ rdata->tx.tso_header = 1;
offset = packet->header_len;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index 72425ff..2908ad1 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1085,10 +1085,10 @@ static void xgbe_rx_desc_reset(struct xgbe_ring_data *rdata)
* Set buffer 2 (hi) address to buffer dma address (hi) and
* set control bits OWN and INTE
*/
- rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->rx_hdr.dma));
- rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->rx_hdr.dma));
- rdesc->desc2 = cpu_to_le32(lower_32_bits(rdata->rx_buf.dma));
- rdesc->desc3 = cpu_to_le32(upper_32_bits(rdata->rx_buf.dma));
+ rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->rx.hdr.dma));
+ rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->rx.hdr.dma));
+ rdesc->desc2 = cpu_to_le32(lower_32_bits(rdata->rx.buf.dma));
+ rdesc->desc3 = cpu_to_le32(upper_32_bits(rdata->rx.buf.dma));
XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, INTE,
rdata->interrupt ? 1 : 0);
@@ -1586,8 +1586,8 @@ static int xgbe_dev_read(struct xgbe_channel *channel)
/* Get the header length */
if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, FD))
- rdata->hdr_len = XGMAC_GET_BITS_LE(rdesc->desc2,
- RX_NORMAL_DESC2, HL);
+ rdata->rx.hdr_len = XGMAC_GET_BITS_LE(rdesc->desc2,
+ RX_NORMAL_DESC2, HL);
/* Get the RSS hash */
if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, RSV)) {
@@ -1610,7 +1610,7 @@ static int xgbe_dev_read(struct xgbe_channel *channel)
}
/* Get the packet length */
- rdata->len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL);
+ rdata->rx.len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL);
if (!XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, LD)) {
/* Not all the data has been transferred for this packet */
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index eebb787..46ea423 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -1747,14 +1747,14 @@ static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata,
u8 *packet;
unsigned int copy_len;
- skb = netdev_alloc_skb_ip_align(netdev, rdata->rx_hdr.dma_len);
+ skb = netdev_alloc_skb_ip_align(netdev, rdata->rx.hdr.dma_len);
if (!skb)
return NULL;
- packet = page_address(rdata->rx_hdr.pa.pages) +
- rdata->rx_hdr.pa.pages_offset;
- copy_len = (rdata->hdr_len) ? rdata->hdr_len : *len;
- copy_len = min(rdata->rx_hdr.dma_len, copy_len);
+ packet = page_address(rdata->rx.hdr.pa.pages) +
+ rdata->rx.hdr.pa.pages_offset;
+ copy_len = (rdata->rx.hdr_len) ? rdata->rx.hdr_len : *len;
+ copy_len = min(rdata->rx.hdr.dma_len, copy_len);
skb_copy_to_linear_data(skb, packet, copy_len);
skb_put(skb, copy_len);
@@ -1900,13 +1900,13 @@ read_again:
}
if (!context) {
- put_len = rdata->len - len;
+ put_len = rdata->rx.len - len;
len += put_len;
if (!skb) {
dma_sync_single_for_cpu(pdata->dev,
- rdata->rx_hdr.dma,
- rdata->rx_hdr.dma_len,
+ rdata->rx.hdr.dma,
+ rdata->rx.hdr.dma_len,
DMA_FROM_DEVICE);
skb = xgbe_create_skb(pdata, rdata, &put_len);
@@ -1918,15 +1918,15 @@ read_again:
if (put_len) {
dma_sync_single_for_cpu(pdata->dev,
- rdata->rx_buf.dma,
- rdata->rx_buf.dma_len,
+ rdata->rx.buf.dma,
+ rdata->rx.buf.dma_len,
DMA_FROM_DEVICE);
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
- rdata->rx_buf.pa.pages,
- rdata->rx_buf.pa.pages_offset,
- put_len, rdata->rx_buf.dma_len);
- rdata->rx_buf.pa.pages = NULL;
+ rdata->rx.buf.pa.pages,
+ rdata->rx.buf.pa.pages_offset,
+ put_len, rdata->rx.buf.dma_len);
+ rdata->rx.buf.pa.pages = NULL;
}
}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index 46ce544..41ce6e3 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -271,6 +271,20 @@ struct xgbe_buffer_data {
unsigned int dma_len;
};
+/* Tx-related ring data */
+struct xgbe_tx_ring_data {
+ unsigned int tso_header; /* TSO header indicator */
+};
+
+/* Rx-related ring data */
+struct xgbe_rx_ring_data {
+ struct xgbe_buffer_data hdr; /* Header locations */
+ struct xgbe_buffer_data buf; /* Payload locations */
+
+ unsigned short hdr_len; /* Length of received header */
+ unsigned short len; /* Length of received packet */
+};
+
/* Structure used to hold information related to the descriptor
* and the packet associated with the descriptor (always use
* use the XGBE_GET_DESC_DATA macro to access this data from the ring)
@@ -282,13 +296,9 @@ struct xgbe_ring_data {
struct sk_buff *skb; /* Virtual address of SKB */
dma_addr_t skb_dma; /* DMA address of SKB data */
unsigned int skb_dma_len; /* Length of SKB DMA area */
- unsigned int tso_header; /* TSO header indicator */
- struct xgbe_buffer_data rx_hdr; /* Header locations */
- struct xgbe_buffer_data rx_buf; /* Payload locations */
-
- unsigned short hdr_len; /* Length of received header */
- unsigned short len; /* Length of received Rx packet */
+ struct xgbe_tx_ring_data tx; /* Tx-related data */
+ struct xgbe_rx_ring_data rx; /* Rx-related data */
unsigned int interrupt; /* Interrupt indicator */
^ permalink raw reply related
* [PATCH net-next v1 5/8] amd-xgbe: Add BQL support
From: Tom Lendacky @ 2014-11-20 17:03 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <20141120170320.15397.10583.stgit@tlendack-t1.amdoffice.net>
Call the appropriate BQL functions to track the number of bytes queued
during Tx processing and to track the number of packets and bytes
that have been transmitted during Tx complete processing.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 4 +++
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 43 +++++++++++++++++++++++++++++-
drivers/net/ethernet/amd/xgbe/xgbe.h | 5 +++
3 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index 2908ad1..78db5a6 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1500,6 +1500,10 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
/* Set LAST bit for the last descriptor */
XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, LD, 1);
+ /* Save the Tx info to report back during cleanup */
+ rdata->tx.packets = packet->tx_packets;
+ rdata->tx.bytes = packet->tx_bytes;
+
/* In case the Tx DMA engine is running, make sure everything
* is written to the descriptor(s) before setting the OWN bit
* for the first descriptor
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 46ea423..f963528 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -876,7 +876,10 @@ static int xgbe_start(struct xgbe_prv_data *pdata)
static void xgbe_stop(struct xgbe_prv_data *pdata)
{
struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct xgbe_channel *channel;
struct net_device *netdev = pdata->netdev;
+ struct netdev_queue *txq;
+ unsigned int i;
DBGPR("-->xgbe_stop\n");
@@ -890,6 +893,15 @@ static void xgbe_stop(struct xgbe_prv_data *pdata)
hw_if->disable_tx(pdata);
hw_if->disable_rx(pdata);
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->tx_ring)
+ continue;
+
+ txq = netdev_get_tx_queue(netdev, channel->queue_index);
+ netdev_tx_reset_queue(txq);
+ }
+
DBGPR("<--xgbe_stop\n");
}
@@ -1156,6 +1168,12 @@ static int xgbe_prep_tso(struct sk_buff *skb, struct xgbe_packet_data *packet)
packet->tcp_header_len, packet->tcp_payload_len);
DBGPR(" packet->mss=%u\n", packet->mss);
+ /* Update the number of packets that will ultimately be transmitted
+ * along with the extra bytes for each extra packet
+ */
+ packet->tx_packets = skb_shinfo(skb)->gso_segs;
+ packet->tx_bytes += (packet->tx_packets - 1) * packet->header_len;
+
return 0;
}
@@ -1184,6 +1202,9 @@ static void xgbe_packet_info(struct xgbe_prv_data *pdata,
context_desc = 0;
packet->rdesc_count = 0;
+ packet->tx_packets = 1;
+ packet->tx_bytes = skb->len;
+
if (xgbe_is_tso(skb)) {
/* TSO requires an extra descriptor if mss is different */
if (skb_shinfo(skb)->gso_size != ring->tx.cur_mss) {
@@ -1400,12 +1421,14 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
struct xgbe_channel *channel;
struct xgbe_ring *ring;
struct xgbe_packet_data *packet;
+ struct netdev_queue *txq;
unsigned long flags;
int ret;
DBGPR("-->xgbe_xmit: skb->len = %d\n", skb->len);
channel = pdata->channel + skb->queue_mapping;
+ txq = netdev_get_tx_queue(netdev, channel->queue_index);
ring = channel->tx_ring;
packet = &ring->packet_data;
@@ -1447,6 +1470,9 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
xgbe_prep_tx_tstamp(pdata, skb, packet);
+ /* Report on the actual number of bytes (to be) sent */
+ netdev_tx_sent_queue(txq, packet->tx_bytes);
+
/* Configure required descriptor fields for transmission */
hw_if->dev_xmit(channel);
@@ -1772,8 +1798,10 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
struct xgbe_ring_data *rdata;
struct xgbe_ring_desc *rdesc;
struct net_device *netdev = pdata->netdev;
+ struct netdev_queue *txq;
unsigned long flags;
int processed = 0;
+ unsigned int tx_packets = 0, tx_bytes = 0;
DBGPR("-->xgbe_tx_poll\n");
@@ -1781,6 +1809,8 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
if (!ring)
return 0;
+ txq = netdev_get_tx_queue(netdev, channel->queue_index);
+
spin_lock_irqsave(&ring->lock, flags);
while ((processed < XGBE_TX_DESC_MAX_PROC) &&
@@ -1799,6 +1829,11 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
xgbe_dump_tx_desc(ring, ring->dirty, 1, 0);
#endif
+ if (hw_if->is_last_desc(rdesc)) {
+ tx_packets += rdata->tx.packets;
+ tx_bytes += rdata->tx.bytes;
+ }
+
/* Free the SKB and reset the descriptor for re-use */
desc_if->unmap_rdata(pdata, rdata);
hw_if->tx_desc_reset(rdata);
@@ -1807,14 +1842,20 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
ring->dirty++;
}
+ if (!processed)
+ goto unlock;
+
+ netdev_tx_completed_queue(txq, tx_packets, tx_bytes);
+
if ((ring->tx.queue_stopped == 1) &&
(xgbe_tx_avail_desc(ring) > XGBE_TX_DESC_MIN_FREE)) {
ring->tx.queue_stopped = 0;
- netif_wake_subqueue(netdev, channel->queue_index);
+ netif_tx_wake_queue(txq);
}
DBGPR("<--xgbe_tx_poll: processed=%d\n", processed);
+unlock:
spin_unlock_irqrestore(&ring->lock, flags);
return processed;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index 41ce6e3..98504f1 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -243,6 +243,9 @@ struct xgbe_packet_data {
u32 rss_hash;
enum pkt_hash_types rss_hash_type;
+
+ unsigned int tx_packets;
+ unsigned int tx_bytes;
};
/* Common Rx and Tx descriptor mapping */
@@ -274,6 +277,8 @@ struct xgbe_buffer_data {
/* Tx-related ring data */
struct xgbe_tx_ring_data {
unsigned int tso_header; /* TSO header indicator */
+ unsigned int packets; /* BQL packet count */
+ unsigned int bytes; /* BQL byte count */
};
/* Rx-related ring data */
^ permalink raw reply related
* [PATCH net-next v1 6/8] amd-xgbe: Remove unused variable
From: Tom Lendacky @ 2014-11-20 17:03 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <20141120170320.15397.10583.stgit@tlendack-t1.amdoffice.net>
The tso_header variable in the xgbe_tx_ring_data structure is not used,
remove it.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-desc.c | 1 -
drivers/net/ethernet/amd/xgbe/xgbe.h | 1 -
2 files changed, 2 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
index 3c7c386..62cb4d3 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
@@ -532,7 +532,6 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
}
rdata->skb_dma = skb_dma;
rdata->skb_dma_len = packet->header_len;
- rdata->tx.tso_header = 1;
offset = packet->header_len;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index 98504f1..ec0d37a 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -276,7 +276,6 @@ struct xgbe_buffer_data {
/* Tx-related ring data */
struct xgbe_tx_ring_data {
- unsigned int tso_header; /* TSO header indicator */
unsigned int packets; /* BQL packet count */
unsigned int bytes; /* BQL byte count */
};
^ permalink raw reply related
* [PATCH net-next v1 7/8] amd-xgbe: Perform Tx coalescing on a packet basis
From: Tom Lendacky @ 2014-11-20 17:04 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <20141120170320.15397.10583.stgit@tlendack-t1.amdoffice.net>
The current form of Tx coalescing works on a descriptor basis instead
of on a packet basis and doesn't take into account TSO packets. Update
the Tx coalescing support to work on a packet basis, taking into
account the number of packets associated with a TSO transmit. Also,
only activate the Tx timer if a timer value is set.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 46 +++++++++++++++++-------------
1 file changed, 26 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index 78db5a6..b3d2433 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1334,7 +1334,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
struct xgbe_packet_data *packet = &ring->packet_data;
unsigned int csum, tso, vlan;
unsigned int tso_context, vlan_context;
- unsigned int tx_coalesce, tx_frames;
+ unsigned int tx_set_ic;
int start_index = ring->cur;
int i;
@@ -1357,10 +1357,26 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
else
vlan_context = 0;
- tx_coalesce = (pdata->tx_usecs || pdata->tx_frames) ? 1 : 0;
- tx_frames = pdata->tx_frames;
- if (tx_coalesce && !channel->tx_timer_active)
- ring->coalesce_count = 0;
+ /* Determine if an interrupt should be generated for this Tx:
+ * Interrupt:
+ * - Tx frame count exceeds the frame count setting
+ * - Addition of Tx frame count to the frame count since the
+ * last interrupt was set exceeds the frame count setting
+ * No interrupt:
+ * - No frame count setting specified (ethtool -C ethX tx-frames 0)
+ * - Addition of Tx frame count to the frame count since the
+ * last interrupt was set does not exceed the frame count setting
+ */
+ ring->coalesce_count += packet->tx_packets;
+ if (!pdata->tx_frames)
+ tx_set_ic = 0;
+ else if (packet->tx_packets > pdata->tx_frames)
+ tx_set_ic = 1;
+ else if ((ring->coalesce_count % pdata->tx_frames) <
+ packet->tx_packets)
+ tx_set_ic = 1;
+ else
+ tx_set_ic = 0;
rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
rdesc = rdata->rdesc;
@@ -1427,13 +1443,6 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
if (XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP))
XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, TTSE, 1);
- /* Set IC bit based on Tx coalescing settings */
- XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1);
- if (tx_coalesce && (!tx_frames ||
- (++ring->coalesce_count % tx_frames)))
- /* Clear IC bit */
- XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 0);
-
/* Mark it as First Descriptor */
XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, FD, 1);
@@ -1478,13 +1487,6 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, HL_B1L,
rdata->skb_dma_len);
- /* Set IC bit based on Tx coalescing settings */
- XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1);
- if (tx_coalesce && (!tx_frames ||
- (++ring->coalesce_count % tx_frames)))
- /* Clear IC bit */
- XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 0);
-
/* Set OWN bit */
XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1);
@@ -1500,6 +1502,10 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
/* Set LAST bit for the last descriptor */
XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, LD, 1);
+ /* Set IC bit based on Tx coalescing settings */
+ if (tx_set_ic)
+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1);
+
/* Save the Tx info to report back during cleanup */
rdata->tx.packets = packet->tx_packets;
rdata->tx.bytes = packet->tx_bytes;
@@ -1530,7 +1536,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
lower_32_bits(rdata->rdesc_dma));
/* Start the Tx coalescing timer */
- if (tx_coalesce && !channel->tx_timer_active) {
+ if (pdata->tx_usecs && !channel->tx_timer_active) {
channel->tx_timer_active = 1;
hrtimer_start(&channel->tx_timer,
ktime_set(0, pdata->tx_usecs * NSEC_PER_USEC),
^ permalink raw reply related
* [PATCH net-next v1 8/8] amd-xgbe: Add support for the skb->xmit_more flag
From: Tom Lendacky @ 2014-11-20 17:04 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <20141120170320.15397.10583.stgit@tlendack-t1.amdoffice.net>
Add support to delay telling the hardware about data that is ready to
be transmitted if the skb->xmit_more flag is set.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
drivers/net/ethernet/amd/xgbe/xgbe-desc.c | 5 +--
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 43 ++++++++++++++++++++---------
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 37 +++++++++++++++++++++----
drivers/net/ethernet/amd/xgbe/xgbe.h | 15 ++++++++++
4 files changed, 78 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
index 62cb4d3..51b68d1 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
@@ -378,7 +378,7 @@ static void xgbe_wrapper_tx_descriptor_init(struct xgbe_prv_data *pdata)
ring->cur = 0;
ring->dirty = 0;
- ring->tx.queue_stopped = 0;
+ memset(&ring->tx, 0, sizeof(ring->tx));
hw_if->tx_desc_init(channel);
}
@@ -422,8 +422,7 @@ static void xgbe_wrapper_rx_descriptor_init(struct xgbe_prv_data *pdata)
ring->cur = 0;
ring->dirty = 0;
- ring->rx.realloc_index = 0;
- ring->rx.realloc_threshold = 0;
+ memset(&ring->rx, 0, sizeof(ring->rx));
hw_if->rx_desc_init(channel);
}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index b3d2433..53f5f66 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1325,6 +1325,29 @@ static void xgbe_config_dcb_pfc(struct xgbe_prv_data *pdata)
xgbe_config_flow_control(pdata);
}
+static void xgbe_tx_start_xmit(struct xgbe_channel *channel,
+ struct xgbe_ring *ring)
+{
+ struct xgbe_prv_data *pdata = channel->pdata;
+ struct xgbe_ring_data *rdata;
+
+ /* Issue a poll command to Tx DMA by writing address
+ * of next immediate free descriptor */
+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_TDTR_LO,
+ lower_32_bits(rdata->rdesc_dma));
+
+ /* Start the Tx coalescing timer */
+ if (pdata->tx_usecs && !channel->tx_timer_active) {
+ channel->tx_timer_active = 1;
+ hrtimer_start(&channel->tx_timer,
+ ktime_set(0, pdata->tx_usecs * NSEC_PER_USEC),
+ HRTIMER_MODE_REL);
+ }
+
+ ring->tx.xmit_more = 0;
+}
+
static void xgbe_dev_xmit(struct xgbe_channel *channel)
{
struct xgbe_prv_data *pdata = channel->pdata;
@@ -1528,20 +1551,13 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
/* Make sure ownership is written to the descriptor */
wmb();
- /* Issue a poll command to Tx DMA by writing address
- * of next immediate free descriptor */
ring->cur++;
- rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
- XGMAC_DMA_IOWRITE(channel, DMA_CH_TDTR_LO,
- lower_32_bits(rdata->rdesc_dma));
-
- /* Start the Tx coalescing timer */
- if (pdata->tx_usecs && !channel->tx_timer_active) {
- channel->tx_timer_active = 1;
- hrtimer_start(&channel->tx_timer,
- ktime_set(0, pdata->tx_usecs * NSEC_PER_USEC),
- HRTIMER_MODE_REL);
- }
+ if (!packet->skb->xmit_more ||
+ netif_xmit_stopped(netdev_get_tx_queue(pdata->netdev,
+ channel->queue_index)))
+ xgbe_tx_start_xmit(channel, ring);
+ else
+ ring->tx.xmit_more = 1;
DBGPR(" %s: descriptors %u to %u written\n",
channel->name, start_index & (ring->rdesc_count - 1),
@@ -2802,6 +2818,7 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if)
hw_if->rx_desc_reset = xgbe_rx_desc_reset;
hw_if->is_last_desc = xgbe_is_last_desc;
hw_if->is_context_desc = xgbe_is_context_desc;
+ hw_if->tx_start_xmit = xgbe_tx_start_xmit;
/* For FLOW ctrl */
hw_if->config_tx_flow_control = xgbe_config_tx_flow_control;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index f963528..02c104d 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -225,6 +225,28 @@ static inline unsigned int xgbe_tx_avail_desc(struct xgbe_ring *ring)
return (ring->rdesc_count - (ring->cur - ring->dirty));
}
+static int xgbe_maybe_stop_tx_queue(struct xgbe_channel *channel,
+ struct xgbe_ring *ring, unsigned int count)
+{
+ struct xgbe_prv_data *pdata = channel->pdata;
+
+ if (count > xgbe_tx_avail_desc(ring)) {
+ DBGPR(" Tx queue stopped, not enough descriptors available\n");
+ netif_stop_subqueue(pdata->netdev, channel->queue_index);
+ ring->tx.queue_stopped = 1;
+
+ /* If we haven't notified the hardware because of xmit_more
+ * support, tell it now
+ */
+ if (ring->tx.xmit_more)
+ pdata->hw_if.tx_start_xmit(channel, ring);
+
+ return NETDEV_TX_BUSY;
+ }
+
+ return 0;
+}
+
static int xgbe_calc_rx_buf_size(struct net_device *netdev, unsigned int mtu)
{
unsigned int rx_buf_size;
@@ -1199,6 +1221,8 @@ static void xgbe_packet_info(struct xgbe_prv_data *pdata,
unsigned int len;
unsigned int i;
+ packet->skb = skb;
+
context_desc = 0;
packet->rdesc_count = 0;
@@ -1447,13 +1471,9 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
xgbe_packet_info(pdata, ring, skb, packet);
/* Check that there are enough descriptors available */
- if (packet->rdesc_count > xgbe_tx_avail_desc(ring)) {
- DBGPR(" Tx queue stopped, not enough descriptors available\n");
- netif_stop_subqueue(netdev, channel->queue_index);
- ring->tx.queue_stopped = 1;
- ret = NETDEV_TX_BUSY;
+ ret = xgbe_maybe_stop_tx_queue(channel, ring, packet->rdesc_count);
+ if (ret)
goto tx_netdev_return;
- }
ret = xgbe_prep_tso(skb, packet);
if (ret) {
@@ -1480,6 +1500,11 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
xgbe_print_pkt(netdev, skb, true);
#endif
+ /* Stop the queue in advance if there may not be enough descriptors */
+ xgbe_maybe_stop_tx_queue(channel, ring, XGBE_TX_MAX_DESCS);
+
+ ret = NETDEV_TX_OK;
+
tx_netdev_return:
spin_unlock_irqrestore(&ring->lock, flags);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index ec0d37a..eb33873 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -140,6 +140,17 @@
#define XGBE_TX_MAX_BUF_SIZE (0x3fff & ~(64 - 1))
+/* Descriptors required for maximum contigous TSO/GSO packet */
+#define XGBE_TX_MAX_SPLIT ((GSO_MAX_SIZE / XGBE_TX_MAX_BUF_SIZE) + 1)
+
+/* Maximum possible descriptors needed for an SKB:
+ * - Maximum number of SKB frags
+ * - Maximum descriptors for contiguous TSO/GSO packet
+ * - Possible context descriptor
+ * - Possible TSO header descriptor
+ */
+#define XGBE_TX_MAX_DESCS (MAX_SKB_FRAGS + XGBE_TX_MAX_SPLIT + 2)
+
#define XGBE_RX_MIN_BUF_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
#define XGBE_RX_BUF_ALIGN 64
#define XGBE_SKB_ALLOC_SIZE 256
@@ -225,6 +236,8 @@
struct xgbe_prv_data;
struct xgbe_packet_data {
+ struct sk_buff *skb;
+
unsigned int attributes;
unsigned int errors;
@@ -360,6 +373,7 @@ struct xgbe_ring {
union {
struct {
unsigned int queue_stopped;
+ unsigned int xmit_more;
unsigned short cur_mss;
unsigned short cur_vlan_ctag;
} tx;
@@ -523,6 +537,7 @@ struct xgbe_hw_if {
void (*tx_desc_reset)(struct xgbe_ring_data *);
int (*is_last_desc)(struct xgbe_ring_desc *);
int (*is_context_desc)(struct xgbe_ring_desc *);
+ void (*tx_start_xmit)(struct xgbe_channel *, struct xgbe_ring *);
/* For FLOW ctrl */
int (*config_tx_flow_control)(struct xgbe_prv_data *);
^ permalink raw reply related
* Re: mlx5: don't duplicate kvfree()
From: Or Gerlitz @ 2014-11-20 17:09 UTC (permalink / raw)
To: Al Viro, Eli Cohen
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
David S. Miller
In-Reply-To: <20141120081726.GK7996-3bDd1+5oDREiFSDQTTA3OLVCufUGDwFn@public.gmane.org>
On 11/20/2014 10:17 AM, Al Viro wrote:
> On Thu, Nov 20, 2014 at 08:13:57AM +0000, Al Viro wrote:
>> > 9 files changed, 21 insertions(+), 35 deletions(-)
> grr... 8 files changed, actually - that was from the diff that included mlx4
> bits. Patch split correctly and sent in two pieces, summary left as is ;-/
> Sorry about the confusion it might cause...
Al,
I think the best way to proceed here is to come up with mlx4 and mlx5
patches and get both of them in through netdev / net-nexttree, don't
worry about each of these drivers have a part which is also under
drivers/infiniband/hw -- it doesn't justify splitting in this case
Or.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" 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
* Re: [PATCH 1/1] net: Xilinx: Deletion of unnecessary checks before two function calls
From: Sören Brinkmann @ 2014-11-20 17:29 UTC (permalink / raw)
To: SF Markus Elfring
Cc: Michal Simek, netdev, linux-arm-kernel, LKML, kernel-janitors,
Julia Lawall
In-Reply-To: <546DF1A2.8090208@users.sourceforge.net>
On Thu, 2014-11-20 at 02:50PM +0100, SF Markus Elfring wrote:
> From: Markus Elfring <elfring@users.sourceforge.net>
> Date: Thu, 20 Nov 2014 14:47:12 +0100
>
> The functions kfree() and of_node_put() test whether their argument is NULL
> and then return immediately. Thus the test around the call is not needed.
>
> This issue was detected by using the Coccinelle software.
>
> Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
Reviewed-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
Sören
^ permalink raw reply
* Re: [PATCH] bonding: clear header_ops when last slave detached (v2)
From: Cong Wang @ 2014-11-20 17:34 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Wengang, netdev
In-Reply-To: <1416465685.8629.15.camel@edumazet-glaptop2.roam.corp.google.com>
On Wed, Nov 19, 2014 at 10:41 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Wed, 2014-11-19 at 14:26 -0800, Cong Wang wrote:
>> On Tue, Nov 18, 2014 at 11:00 PM, Wengang <wen.gang.wang@oracle.com> wrote:
>> >
>> > Yes, that's true. So the simplest way is move ipoib_header_ops to vmlinux.
>> >
>>
>> That is not an option. Perhaps you need RCU to protect the dev->header_ops
>> pointer.
>
> This _is_ a reasonable option, especially for stable kernels
>
> ipoib_hard_header() is 100 bytes or less. Adding infrastructure all over
> the kernel to be able to use RCU or module refcounting will cost much
> more.
I didn't look into ipoib_header_ops, thought it might have some dependency
on symbols. So _generally_ speaking, we can't do that, the dependency
chain could be very long. It could be an exception and good luck
to play with module symbols.
>
> Tell me why it is ok for eth_header_ops() being static (while its _much_
> bigger), and not for ipoib_header_ops. This looks pretty arbitrary to
> me.
>
Simple, eth_* is kinda of a builtin library now, too many drivers use them.
^ permalink raw reply
* Re: [patch net-next] i40e: remove dead fdb code
From: Jesse Brandeburg @ 2014-11-20 17:39 UTC (permalink / raw)
To: Jiri Pirko
Cc: linux.nics, e1000-devel, netdev, bruce.w.allan, john.ronciak,
davem
In-Reply-To: <1416489029-1929-1-git-send-email-jiri@resnulli.us>
On Thu, 20 Nov 2014 14:10:29 +0100
Jiri Pirko <jiri@resnulli.us> wrote:
> This code is not used now and also it contains some weird ifdefs. So
> remove it for now. It can be added when needed.
>
First, thanks for looking at our code.
but, NAK, the code just needs to have the #ifdefs removed.
In addition the fdb_del and fdb_dump functions are un-necessary and
were submitted by mistake.
I will draft up a patch today and send it (and Jeff can take it through
Jeff Kirsher's i40e tree, if thats okay with DaveM)
Thanks,
Jesse
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: [PATCH 1/1] net: brcm80211: Deletion of unnecessary checks before two function calls
From: Arend van Spriel @ 2014-11-20 18:04 UTC (permalink / raw)
To: SF Markus Elfring
Cc: Brett Rudley, Franky (Zhenhui) Lin, Hante Meuleman,
John W. Linville, linux-wireless, brcm80211-dev-list, netdev,
LKML, kernel-janitors, Julia Lawall
In-Reply-To: <546E0DC8.3050906@users.sourceforge.net>
On 11/20/14 16:50, SF Markus Elfring wrote:
> From: Markus Elfring<elfring@users.sourceforge.net>
> Date: Thu, 20 Nov 2014 16:42:51 +0100
>
> The functions brcmu_pkt_buf_free_skb() and release_firmware() test whether
> their argument is NULL and then return immediately. Thus the test around
> the call is not needed.
>
> This issue was detected by using the Coccinelle software.
Goodo for coccinelle and you for running it.
Acked-by: Arend van Spriel <arend@broadcom.com>
> Signed-off-by: Markus Elfring<elfring@users.sourceforge.net>
> ---
> drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 3 +--
> drivers/net/wireless/brcm80211/brcmfmac/firmware.c | 3 +--
> drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c | 3 +--
> drivers/net/wireless/brcm80211/brcmsmac/main.c | 3 +--
> 4 files changed, 4 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
> index f55f625..8ff7037 100644
> --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
> +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
> @@ -2539,8 +2539,7 @@ static void brcmf_sdio_bus_stop(struct device *dev)
> brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
>
> /* Clear any held glomming stuff */
> - if (bus->glomd)
> - brcmu_pkt_buf_free_skb(bus->glomd);
> + brcmu_pkt_buf_free_skb(bus->glomd);
> brcmf_sdio_free_glom(bus);
>
> /* Clear rx control and wake any waiters */
> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
> index 8ea9f28..3a2d014 100644
> --- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
> +++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
> @@ -262,8 +262,7 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
>
> fail:
> brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
> - if (fwctx->code)
> - release_firmware(fwctx->code);
> + release_firmware(fwctx->code);
> device_release_driver(fwctx->dev);
> kfree(fwctx);
> }
> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
> index 8f8b937..0cb00dc 100644
> --- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
> +++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
> @@ -506,8 +506,7 @@ static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
> memcpy(buf, skb->data, (len< msgbuf->ioctl_resp_ret_len) ?
> len : msgbuf->ioctl_resp_ret_len);
> }
> - if (skb)
> - brcmu_pkt_buf_free_skb(skb);
> + brcmu_pkt_buf_free_skb(skb);
>
> return msgbuf->ioctl_resp_status;
> }
> diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
> index 1b47482..ce538a1 100644
> --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
> +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
> @@ -1009,8 +1009,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
> if (txh)
> trace_brcms_txdesc(&wlc->hw->d11core->dev, txh,
> sizeof(*txh));
> - if (p)
> - brcmu_pkt_buf_free_skb(p);
> + brcmu_pkt_buf_free_skb(p);
> }
>
> if (dma&& queue< NFIFO) {
^ permalink raw reply
* Re: mlx5: don't duplicate kvfree()
From: Al Viro @ 2014-11-20 18:51 UTC (permalink / raw)
To: Or Gerlitz
Cc: Eli Cohen, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
David S. Miller
In-Reply-To: <546E204B.5080106-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
On Thu, Nov 20, 2014 at 07:09:31PM +0200, Or Gerlitz wrote:
> On 11/20/2014 10:17 AM, Al Viro wrote:
> >On Thu, Nov 20, 2014 at 08:13:57AM +0000, Al Viro wrote:
> >>> 9 files changed, 21 insertions(+), 35 deletions(-)
> >grr... 8 files changed, actually - that was from the diff that included mlx4
> >bits. Patch split correctly and sent in two pieces, summary left as is ;-/
> >Sorry about the confusion it might cause...
> Al,
>
> I think the best way to proceed here is to come up with mlx4 and
> mlx5 patches and get both of them in through netdev / net-nexttree,
> don't worry about each of these drivers have a part which is also
> under drivers/infiniband/hw -- it doesn't justify splitting in this
> case
Both had been sent to netdev today (and ACKed by respective drivers'
maintainers). I'd certainly prefer not to put them through vfs.git,
but beyond that I really don't care which tree do those go into...
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" 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
* [PATCH net-next] tcp: Remove some spurious dropped packet profile hits from the passive connection accept path
From: Rick Jones @ 2014-11-20 18:58 UTC (permalink / raw)
To: netdev; +Cc: davem
From: Rick Jones <rick.jones2@hp.com>
When a system is the passive accepter of many connections, for example
when the target of a netperf TCP_CC or TCP_CRR test, or as say a web
server, the discard of the skb containing the TCP SYN being processed
for the LISTEN endpoint should be a consume_skb() rather than a kfree_skb()
to avoid cluttering a dropped packet profile.
Signed-off-by: Rick Jones <rick.jones2@hp.com>
---
perf top -a -g -e skb:kfree_sk output from a system which is the target
of a netperf TCP_CC test
before:
- 100.00% 100.00% [kernel] [k] kfree_skb
- kfree_skb
+ 68.68% sk_stream_kill_queues
+ 31.32% tcp_rcv_state_process
after:
- 100.00% 100.00% [kernel] [k] kfree_skb
- kfree_skb
99.89% sk_stream_kill_queues
Presumably, the consume_skb() versus kfree_skb() could be made conditional
on there actually being data in the TCP SYN segment, but the odds of there
actually being data seemed low enough to not warrant it.
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index d91436b..999b0a4 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5624,8 +5624,12 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
* against this problem. So, we drop the data
* in the interest of security over speed unless
* it's still in use.
+ *
+ * 99 times out of 10, there won't actually be any
+ * data and so we aren't really dropping anything.
+ * So, we consume_skb() rather than kfree_skb().
*/
- kfree_skb(skb);
+ consume_skb(skb);
return 0;
}
goto discard;
^ 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