* [PATCH net-next v2 1/2] enic: implement frag allocator
From: Govindarajulu Varadarajan @ 2015-02-11 12:59 UTC (permalink / raw)
To: davem, netdev; +Cc: benve, ssujith, Govindarajulu Varadarajan
In-Reply-To: <1423659558-32523-1-git-send-email-_govind@gmx.com>
This patch implements frag allocator for rq buffer. This is based on
__alloc_page_frag & __page_frag_refill implementation in net/core/skbuff.c
In addition to frag allocation from order(3) page in __alloc_page_frag,
we also maintain dma address of the page. While allocating a frag for rx buffer
we return va + offset for virtual address of the frag, and pa + offset for
dma address of the frag. This reduces the number of calls to dma_map()
by 1/3 for 9k mtu and by 1/20 for 1500 mtu.
__alloc_page_frag is limited to max buffer size of PAGE_SIZE, i.e 4096 in most
of the cases. So 9k buffer allocation goes through kmalloc which return
page of order 2, 16k. We waste 7k bytes for every 9k buffer.
we maintain dma_count variable which is incremented when we allocate a frag.
enic_unmap_dma will decrement the dma_count and unmap it when there is no user
of that page in rx ring.
This reduces the memory utilization for 9k mtu by 33%.
Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
---
drivers/net/ethernet/cisco/enic/enic.h | 15 +++
drivers/net/ethernet/cisco/enic/enic_main.c | 155 +++++++++++++++++++++++-----
drivers/net/ethernet/cisco/enic/vnic_rq.c | 13 +++
drivers/net/ethernet/cisco/enic/vnic_rq.h | 2 +
4 files changed, 161 insertions(+), 24 deletions(-)
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index 84b6a2b..0f3b6327 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -20,6 +20,11 @@
#ifndef _ENIC_H_
#define _ENIC_H_
+#include <linux/if.h>
+#include <linux/if_link.h>
+#include <linux/if_ether.h>
+#include <linux/netdevice.h>
+
#include "vnic_enet.h"
#include "vnic_dev.h"
#include "vnic_wq.h"
@@ -191,6 +196,16 @@ struct enic {
struct vnic_gen_stats gen_stats;
};
+#define ENIC_ALLOC_ORDER PAGE_ALLOC_COSTLY_ORDER
+
+struct enic_alloc_cache {
+ struct page_frag frag;
+ unsigned int pagecnt_bias;
+ int dma_count;
+ void *va;
+ dma_addr_t pa;
+};
+
static inline struct device *enic_get_dev(struct enic *enic)
{
return &(enic->pdev->dev);
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 9cbe038..841571f 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -950,6 +950,105 @@ nla_put_failure:
return -EMSGSIZE;
}
+struct enic_alloc_cache *enic_page_refill(struct enic *enic, size_t sz,
+ gfp_t gfp)
+{
+ struct enic_alloc_cache *ec;
+ gfp_t gfp_comp = gfp | __GFP_COMP | __GFP_NOWARN | __GFP_NORETRY;
+ u8 order = ENIC_ALLOC_ORDER;
+
+ ec = kzalloc(sizeof(*ec), GFP_ATOMIC);
+ if (unlikely(!ec))
+ goto no_ec;
+ ec->frag.page = alloc_pages_node(NUMA_NO_NODE, gfp_comp, order);
+ if (unlikely(!ec->frag.page)) {
+ order = get_order(sz);
+ ec->frag.page = alloc_pages_node(NUMA_NO_NODE, gfp, order);
+ if (!ec->frag.page)
+ goto free_ec;
+ }
+
+ ec->frag.size = (PAGE_SIZE << order);
+ ec->va = page_address(ec->frag.page);
+ ec->pa = pci_map_single(enic->pdev, ec->va, ec->frag.size,
+ PCI_DMA_FROMDEVICE);
+ if (unlikely(enic_dma_map_check(enic, ec->pa)))
+ goto free_page;
+ atomic_add(ec->frag.size - 1, &ec->frag.page->_count);
+ ec->pagecnt_bias = ec->frag.size;
+ ec->frag.offset = ec->frag.size;
+
+ return ec;
+
+free_page:
+ __free_pages(ec->frag.page, order);
+free_ec:
+ kfree(ec);
+no_ec:
+ return NULL;
+}
+
+struct enic_alloc_cache *enic_alloc_frag(struct vnic_rq *rq, size_t sz)
+{
+ struct enic *enic = vnic_dev_priv(rq->vdev);
+ struct enic_alloc_cache *ec = rq->ec;
+ int offset;
+
+ if (unlikely(!ec)) {
+refill:
+ ec = enic_page_refill(enic, sz, GFP_ATOMIC);
+ rq->ec = ec;
+
+ if (unlikely(!ec))
+ return NULL;
+ }
+
+ offset = ec->frag.offset - sz;
+ if (offset < 0) {
+ if (!atomic_sub_and_test(ec->pagecnt_bias,
+ &ec->frag.page->_count)) {
+ /* rq cleanup service has processed all the frags
+ * belonging to this page. Since page->_count is not 0
+ * and ec->dma_count is 0 these frags should be in
+ * stack. We should unmap the page here.
+ */
+ if (!ec->dma_count) {
+ pci_unmap_single(enic->pdev, ec->pa,
+ ec->frag.size,
+ PCI_DMA_FROMDEVICE);
+ kfree(ec);
+ } else {
+ /* frags from this page are still in rx queue. Let the
+ * rx cleanup service unmap the page in enic_unmap_dma.
+ */
+ ec->pagecnt_bias = 0;
+ }
+ goto refill;
+ }
+ WARN_ON(ec->dma_count);
+ atomic_set(&ec->frag.page->_count, ec->frag.size);
+ ec->pagecnt_bias = ec->frag.size;
+ offset = ec->frag.size - sz;
+ }
+ ec->pagecnt_bias--;
+ ec->dma_count++;
+ ec->frag.offset = offset;
+
+ return ec;
+}
+
+void enic_unmap_dma(struct enic *enic, struct enic_alloc_cache *ec)
+{
+ /* enic_alloc_frag is done using this page. We should be free to unmap
+ * the page if there are no pending frags in the queue.
+ */
+ if (!--ec->dma_count && !ec->pagecnt_bias) {
+ pci_unmap_single(enic->pdev, ec->pa, ec->frag.size,
+ PCI_DMA_FROMDEVICE);
+ kfree(ec);
+ }
+}
+
static void enic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf)
{
struct enic *enic = vnic_dev_priv(rq->vdev);
@@ -957,8 +1056,7 @@ static void enic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf)
if (!buf->os_buf)
return;
- pci_unmap_single(enic->pdev, buf->dma_addr,
- buf->len, PCI_DMA_FROMDEVICE);
+ enic_unmap_dma(enic, buf->ec);
dev_kfree_skb_any(buf->os_buf);
buf->os_buf = NULL;
}
@@ -968,10 +1066,12 @@ static int enic_rq_alloc_buf(struct vnic_rq *rq)
struct enic *enic = vnic_dev_priv(rq->vdev);
struct net_device *netdev = enic->netdev;
struct sk_buff *skb;
- unsigned int len = netdev->mtu + VLAN_ETH_HLEN;
+ unsigned int len;
unsigned int os_buf_index = 0;
dma_addr_t dma_addr;
struct vnic_rq_buf *buf = rq->to_use;
+ struct enic_alloc_cache *ec;
+ void *va;
if (buf->os_buf) {
enic_queue_rq_desc(rq, buf->os_buf, os_buf_index, buf->dma_addr,
@@ -979,21 +1079,33 @@ static int enic_rq_alloc_buf(struct vnic_rq *rq)
return 0;
}
- skb = netdev_alloc_skb_ip_align(netdev, len);
- if (!skb)
- return -ENOMEM;
- dma_addr = pci_map_single(enic->pdev, skb->data, len,
- PCI_DMA_FROMDEVICE);
- if (unlikely(enic_dma_map_check(enic, dma_addr))) {
- dev_kfree_skb(skb);
- return -ENOMEM;
- }
+ len = netdev->mtu + VLAN_ETH_HLEN + NET_IP_ALIGN + NET_SKB_PAD;
+ len = SKB_DATA_ALIGN(len) +
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
- enic_queue_rq_desc(rq, skb, os_buf_index,
- dma_addr, len);
+ ec = enic_alloc_frag(rq, len);
+ if (unlikely(!ec))
+ goto alloc_fail;
+ va = ec->va + ec->frag.offset;
+ skb = build_skb(va, len);
+ if (unlikely(!skb)) {
+ ec->pagecnt_bias++;
+ ec->frag.offset += len;
+ ec->dma_count--;
+
+ goto alloc_fail;
+ }
+ skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
+ dma_addr = ec->pa + ec->frag.offset + NET_SKB_PAD + NET_IP_ALIGN;
+ buf->ec = ec;
+ enic_queue_rq_desc(rq, skb, os_buf_index, dma_addr,
+ netdev->mtu + VLAN_ETH_HLEN);
return 0;
+
+alloc_fail:
+ return -ENOMEM;
}
static void enic_intr_update_pkt_size(struct vnic_rx_bytes_counter *pkt_size,
@@ -1016,8 +1128,6 @@ static bool enic_rxcopybreak(struct net_device *netdev, struct sk_buff **skb,
new_skb = netdev_alloc_skb_ip_align(netdev, len);
if (!new_skb)
return false;
- pci_dma_sync_single_for_cpu(enic->pdev, buf->dma_addr, len,
- DMA_FROM_DEVICE);
memcpy(new_skb->data, (*skb)->data, len);
*skb = new_skb;
@@ -1065,8 +1175,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
enic->rq_truncated_pkts++;
}
- pci_unmap_single(enic->pdev, buf->dma_addr, buf->len,
- PCI_DMA_FROMDEVICE);
+ enic_unmap_dma(enic, buf->ec);
dev_kfree_skb_any(skb);
buf->os_buf = NULL;
@@ -1077,11 +1186,11 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
/* Good receive
*/
-
+ pci_dma_sync_single_for_cpu(enic->pdev, buf->dma_addr,
+ bytes_written, DMA_FROM_DEVICE);
if (!enic_rxcopybreak(netdev, &skb, buf, bytes_written)) {
buf->os_buf = NULL;
- pci_unmap_single(enic->pdev, buf->dma_addr, buf->len,
- PCI_DMA_FROMDEVICE);
+ enic_unmap_dma(enic, buf->ec);
}
prefetch(skb->data - NET_IP_ALIGN);
@@ -1122,9 +1231,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
/* Buffer overflow
*/
-
- pci_unmap_single(enic->pdev, buf->dma_addr, buf->len,
- PCI_DMA_FROMDEVICE);
+ enic_unmap_dma(enic, buf->ec);
dev_kfree_skb_any(skb);
buf->os_buf = NULL;
}
diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.c b/drivers/net/ethernet/cisco/enic/vnic_rq.c
index 36a2ed6..c31669f 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_rq.c
+++ b/drivers/net/ethernet/cisco/enic/vnic_rq.c
@@ -26,6 +26,7 @@
#include "vnic_dev.h"
#include "vnic_rq.h"
+#include "enic.h"
static int vnic_rq_alloc_bufs(struct vnic_rq *rq)
{
@@ -199,6 +200,18 @@ void vnic_rq_clean(struct vnic_rq *rq,
rq->ring.desc_avail++;
}
+ if (rq->ec) {
+ struct enic *enic = vnic_dev_priv(rq->vdev);
+ struct enic_alloc_cache *ec = rq->ec;
+
+ WARN_ON(ec->dma_count);
+ pci_unmap_single(enic->pdev, ec->pa, ec->frag.size,
+ PCI_DMA_FROMDEVICE);
+ atomic_sub(ec->pagecnt_bias - 1, &ec->frag.page->_count);
+ __free_pages(ec->frag.page, get_order(ec->frag.size));
+ kfree(ec);
+ rq->ec = NULL;
+ }
/* Use current fetch_index as the ring starting point */
fetch_index = ioread32(&rq->ctrl->fetch_index);
diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.h b/drivers/net/ethernet/cisco/enic/vnic_rq.h
index 8111d52..2e4815a 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_rq.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_rq.h
@@ -73,6 +73,7 @@ struct vnic_rq_buf {
unsigned int index;
void *desc;
uint64_t wr_id;
+ struct enic_alloc_cache *ec;
};
struct vnic_rq {
@@ -100,6 +101,7 @@ struct vnic_rq {
unsigned int bpoll_state;
spinlock_t bpoll_lock;
#endif /* CONFIG_NET_RX_BUSY_POLL */
+ struct enic_alloc_cache *ec;
};
static inline unsigned int vnic_rq_desc_avail(struct vnic_rq *rq)
--
2.3.0
^ permalink raw reply related
* [PATCH net-next v2 0/2] improve rq buff allocation and reduce dma mapping
From: Govindarajulu Varadarajan @ 2015-02-11 12:59 UTC (permalink / raw)
To: davem, netdev; +Cc: benve, ssujith, Govindarajulu Varadarajan
The following series tries to address these two problem in rq buff allocation.
* Memory wastage because of large 9k allocation using kmalloc:
For 9k mtu buffer, netdev_alloc_skb_ip_align internally calls kmalloc for
size > 4096. In case of 9k buff, kmalloc returns pages for order 2, 16k.
And we use only ~9k of 16k. 7k memory wasted. Using the frag the frag
allocator in patch 1/2, we can allocate three 9k buffs in a 32k page size.
Typical enic configuration has 8 rq, and desc ring of size 4096.
Thats 8 * 4096 * (16*1024) = 512 MB. Using this frag allocator:
8 * 4096 * (32*1024/3) = 341 MB. Thats 171 MB of memory save.
* frequent dma_map() calls:
we call dma_map() for every buff we allocate. When iommu is on, This is very
cpu time consuming. From my testing, most of the cpu cycles are wasted
spinning on spin_lock_irqsave(&iovad->iova_rbtree_lock, flags) in
intel_map_page() .. -> ..__alloc_and_insert_iova_range()
With this patch, we call dma_map() once for 32k page. i.e once for every three
9k desc, and once every twenty 1500 bytes desc.
Here are testing result with 8 rq, 4096 ring size and 9k mtu. irq of each rq
is affinitized with different CPU. Ran iperf with 32 threads. Link is 10G.
iommu is on.
CPU utilization throughput
without patch 100% 1.8 Gbps
with patch 13% 9.8 Gbps
v2:
Remove changing order facility
Govindarajulu Varadarajan (2):
enic: implement frag allocator
enic: Add rq allocation failure stats
drivers/net/ethernet/cisco/enic/enic.h | 15 +++
drivers/net/ethernet/cisco/enic/enic_ethtool.c | 2 +
drivers/net/ethernet/cisco/enic/enic_main.c | 158 +++++++++++++++++++++----
drivers/net/ethernet/cisco/enic/vnic_rq.c | 13 ++
drivers/net/ethernet/cisco/enic/vnic_rq.h | 2 +
drivers/net/ethernet/cisco/enic/vnic_stats.h | 2 +
6 files changed, 168 insertions(+), 24 deletions(-)
--
2.3.0
^ permalink raw reply
* Re: [PATCH v3 linux-trace 1/8] tracing: attach eBPF programs to tracepoints and syscalls
From: Steven Rostedt @ 2015-02-11 12:51 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Ingo Molnar, Namhyung Kim, Arnaldo Carvalho de Melo, Jiri Olsa,
Masami Hiramatsu, Linux API, Network Development, LKML,
Linus Torvalds, Peter Zijlstra, Eric W. Biederman
In-Reply-To: <CAMEtUuxizvHF09y_vU-c+L=n16tqWDqJPTybGB1a_OqN7p+jsA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, 10 Feb 2015 22:33:05 -0800
Alexei Starovoitov <ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org> wrote:
> fair enough.
> Something like TRACE_MARKER(arg1, arg2) that prints
> it was hit without accessing the args would be enough.
> Without any args it is indeed a 'fast kprobe' only.
> Debug info would still be needed to access
> function arguments.
> On x64 function entry point and x64 abi make it easy
> to access args, but i386 or kprobe in the middle
> lose visibility when debug info is not available.
> TRACE_MARKER (with few key args that function
> is operating on) is enough to achieve roughly the same
> as kprobe without debug info.
Actually, what about a TRACE_EVENT_DEBUG(), that has a few args and
possibly a full trace event layout.
The difference would be that the trace events do not show up unless you
have "trace_debug" on the command line. This should prevent
applications from depending on them.
I could even do the nasty dmesg output like I do with trace_printk()s,
that would definitely keep a production kernel from adding it by
default.
When trace_debug is not there, the trace points could still be accessed
but perhaps only via bpf, or act like a simple trace marker.
Note, if you need ids, I rather have them in another directory than
tracefs. Make a eventfs perhaps that holds these. I rather keep tracefs
simple.
This is something that needs to probably be discussed at bit.
-- Steve
^ permalink raw reply
* [PATCH] netfilter: ipset: fix boolreturn.cocci warnings
From: kbuild test robot @ 2015-02-11 12:33 UTC (permalink / raw)
To: Jozsef Kadlecsik
Cc: kbuild-all, Pablo Neira Ayuso, Patrick McHardy, netfilter-devel,
coreteam, netdev, linux-kernel
In-Reply-To: <201502112043.OvntWCjd%fengguang.wu@intel.com>
net/netfilter/xt_set.c:196:9-10: WARNING: return of 0/1 in function 'set_match_v3' with return type bool
net/netfilter/xt_set.c:242:9-10: WARNING: return of 0/1 in function 'set_match_v4' with return type bool
Return statements in functions returning bool should use
true/false instead of 1/0.
Generated by: scripts/coccinelle/misc/boolreturn.cocci
CC: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---
xt_set.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/net/netfilter/xt_set.c
+++ b/net/netfilter/xt_set.c
@@ -193,7 +193,7 @@ set_match_v3(const struct sk_buff *skb,
return ret;
if (!match_counter0(opt.ext.packets, &info->packets))
- return 0;
+ return false;
return match_counter0(opt.ext.bytes, &info->bytes);
}
@@ -239,7 +239,7 @@ set_match_v4(const struct sk_buff *skb,
return ret;
if (!match_counter(opt.ext.packets, &info->packets))
- return 0;
+ return false;
return match_counter(opt.ext.bytes, &info->bytes);
}
^ permalink raw reply
* Re: [bisected regression] e1000e: "Detected Hardware Unit Hang"
From: Jeff Kirsher @ 2015-02-11 11:34 UTC (permalink / raw)
To: Thomas Jarosch, Aaron Brown
Cc: e1000-devel, 'Linux Netdev List', Eric Dumazet
In-Reply-To: <2609782.Mryft1leMQ@storm>
[-- Attachment #1.1: Type: text/plain, Size: 765 bytes --]
On Wed, 2015-02-11 at 12:23 +0100, Thomas Jarosch wrote:
> Hi Jeff,
>
> On Thursday, 15. January 2015 06:59:13 Jeff Kirsher wrote:
> > > Sure, you basically reverted my patch.
> > >
> > > You are not the first to report a problem caused by this patch.
> > >
> > > This patch is known to have uncovered some driver bugs.
> > >
> > > We are not going to revert it. We are going to fix the real bugs.
> > >
> > > Thanks
> >
> > Agreed, we are looking into issue Thomas.
>
> any news from the Intel labs what might be going on here?
>
> We started seeing those hangs on "MSI B85M ECO" boards, too,
> though it's way more sporadic there.
I have not heard anything, so I have added Aaron Brown to see if he has
any additional information.
[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
[-- Attachment #2: Type: text/plain, Size: 441 bytes --]
------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
[-- Attachment #3: Type: text/plain, Size: 257 bytes --]
_______________________________________________
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: [bisected regression] e1000e: "Detected Hardware Unit Hang"
From: Thomas Jarosch @ 2015-02-11 11:23 UTC (permalink / raw)
To: Jeff Kirsher, 'Linux Netdev List'; +Cc: Eric Dumazet, e1000-devel
In-Reply-To: <1421333953.2632.22.camel@jtkirshe-mobl>
Hi Jeff,
On Thursday, 15. January 2015 06:59:13 Jeff Kirsher wrote:
> > Sure, you basically reverted my patch.
> >
> > You are not the first to report a problem caused by this patch.
> >
> > This patch is known to have uncovered some driver bugs.
> >
> > We are not going to revert it. We are going to fix the real bugs.
> >
> > Thanks
>
> Agreed, we are looking into issue Thomas.
any news from the Intel labs what might be going on here?
We started seeing those hangs on "MSI B85M ECO" boards, too,
though it's way more sporadic there.
Thanks,
Thomas
^ permalink raw reply
* Re: [PATCH 3/3] stmmac: Add AXI burst length support to platform device.
From: Chen Baozi @ 2015-02-11 11:11 UTC (permalink / raw)
To: Mark Rutland
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20150210114837.GC6659@leverpostej>
On Tue, Feb 10, 2015 at 11:48:37AM +0000, Mark Rutland wrote:
> > On Mon, Feb 09, 2015 at 12:04:43PM +0000, Mark Rutland wrote:
> > > On Sat, Feb 07, 2015 at 05:07:16AM +0000, Chen Baozi wrote:
> > > > The AXI Bus Mode Register controls the AXI master behavior. It is mainly
> > > > used to control the burst splitting and the number of outstanding requests.
> > > > This register is present and valid only in GMAC-AXI configuration. The old
> > > > driver only supports this feature on PCI devices. This patch adds an
> > > > 'snps,apl' properties in DT to enable it on platform devices.
> > > >
> > > > Signed-off-by: Chen Baozi <chenbaozi@kylinos.com.cn>
> > > > ---
> > > > Documentation/devicetree/bindings/net/stmmac.txt | 1 +
> > > > drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 +
> > > > 2 files changed, 2 insertions(+)
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt
> > > > index c41afd9..8f3c834 100644
> > > > --- a/Documentation/devicetree/bindings/net/stmmac.txt
> > > > +++ b/Documentation/devicetree/bindings/net/stmmac.txt
> > > > @@ -43,6 +43,7 @@ Optional properties:
> > > > available this clock is used for programming the Timestamp Addend Register.
> > > > If not passed then the system clock will be used and this is fine on some
> > > > platforms.
> > > > +- snps,abl: AXI Burst Length
> > >
> > > This is not a good name (though I see it follows "snps,pbl", which is
> > > also not a good name)...
> >
> > Any idea for a better name?
>
> Perhaps snps,axi-burst-length ?
>
> > > Why does this need to be in the DT? Is this required for correctness? Or
> > > performance?
> >
> > This is required for correctness. Otherwise, the driver would write
> > '0' to the register by default, which makes the driver not work.
>
> What does that mean at the HW level? If that won't work in all cases
> why does the driver do that?
According to the manual, this is used to select the burst length on AXI
master interface. The register is optional and valid only in GMAC-AXI
configuration. IMHO, not all cases require the driver to set this
register. So I just put it in the 'optional properties', in case some
devices depend on that.
Cheers,
Baozi.
^ permalink raw reply
* under certain conditions netlink will not report adding a new ipv6 address
From: Radu Benea @ 2015-02-11 10:50 UTC (permalink / raw)
To: netdev
Hello.
I found that the netlink monitoring interface does not report adding a new ipv6 address unless:
- the interface is up
- the network cable is plugged in
Deleting the ipv6 address is reported even in these conditions.
Only tested this with e1000e since it's the only network adapter I have.
To test this just turn the network interface down, add an ipv6 address, then remove it... you will only see the deladdr message.
Example test commands:
ip link set dev devname down
ip -6 addr add 2001::5 dev devname
ip -6 addr del 2001::5 dev devname
Sample test code below.
#include <string.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <stdio.h>
#include <unistd.h>
int main(int, char * [])
{
struct sockaddr_nl sa;
int fd;
int len;
char buf[4096];
struct iovec iov = { buf, sizeof(buf) };
struct msghdr msg;
struct nlmsghdr *nh;
memset(&sa, 0, sizeof(sa));
sa.nl_family = AF_NETLINK;
sa.nl_pid = getpid();
sa.nl_groups = RTMGRP_IPV6_IFADDR;
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
bind(fd, (struct sockaddr *)&sa, sizeof(sa));
while (1) {
msg = {&sa, sizeof(sa), &iov, 1, NULL, 0, 0};
len = recvmsg(fd, &msg, 0);
for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) {
/* The end of multipart message. */
switch (nh->nlmsg_type) {
case RTM_NEWADDR:
printf("Received newaddr from netlink monitor\n");
break;
case RTM_DELADDR:
printf("Received deladdr from netlink monitor\n");
break;
default:
printf("Received unexpected message type %d from netlink monitor\n", nh->nlmsg_type);
break;
}
}
}
}
^ permalink raw reply
* [PATCH] drivers/net: Use setup_timer and mod_timer
From: Vaishali Thakkar @ 2015-02-11 10:29 UTC (permalink / raw)
To: David S. Miller
Cc: Wilfried Klaebe, Felipe Balbi, Justin van Wijngaarden, netdev,
linux-kernel
This patch introduces the use of functions setup_timer
and mod_timer.
This is done using Coccinelle and semantic patch used
for this as follows:
// <smpl>
@@
expression x,y,z,a,b;
@@
-init_timer (&x);
+setup_timer (&x, y, z);
+mod_timer (&a, b);
-x.function = y;
-x.data = z;
-x.expires = b;
-add_timer(&a);
// </smpl>
Signed-off-by: Vaishali Thakkar <vthakkar1994@gmail.com>
---
drivers/net/ethernet/3com/3c589_cs.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/3com/3c589_cs.c b/drivers/net/ethernet/3com/3c589_cs.c
index f18647c..c5a3205 100644
--- a/drivers/net/ethernet/3com/3c589_cs.c
+++ b/drivers/net/ethernet/3com/3c589_cs.c
@@ -518,11 +518,8 @@ static int el3_open(struct net_device *dev)
netif_start_queue(dev);
tc589_reset(dev);
- init_timer(&lp->media);
- lp->media.function = media_check;
- lp->media.data = (unsigned long) dev;
- lp->media.expires = jiffies + HZ;
- add_timer(&lp->media);
+ setup_timer(&lp->media, media_check, (unsigned long)dev);
+ mod_timer(&lp->media, jiffies + HZ);
dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
dev->name, inw(dev->base_addr + EL3_STATUS));
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v3 linux-trace 1/8] tracing: attach eBPF programs to tracepoints and syscalls
From: Peter Zijlstra @ 2015-02-11 10:28 UTC (permalink / raw)
To: Steven Rostedt
Cc: Alexei Starovoitov, Ingo Molnar, Namhyung Kim,
Arnaldo Carvalho de Melo, Jiri Olsa, Masami Hiramatsu, Linux API,
Network Development, LKML, Linus Torvalds,
ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <20150210165359.34cc53d9-f9ZlEuEWxVcJvu8Pb33WZ0EMvNT87kid@public.gmane.org>
On Tue, Feb 10, 2015 at 04:53:59PM -0500, Steven Rostedt wrote:
> > >> In the future we might add a tracepoint and pass a single
> > >> pointer to interesting data struct to it. bpf programs will walk
> > >> data structures 'as safe modules' via bpf_fetch*() methods
> > >> without exposing it as ABI.
> > >
> > > Will this work if that structure changes? When the field we are looking
> > > for no longer exists?
> >
> > bpf_fetch*() is the same mechanism as perf probe.
> > If there is a mistake by user space tools, the program
> > will be reading some junk, but it won't be crashing.
>
> But what if the userspace tool depends on that value returning
> something meaningful. If it was meaningful in the past, it will have to
> be meaningful in the future, even if the internals of the kernel make
> it otherwise.
We're compiling the BPF stuff against the 'current' kernel headers
right? So would enforcing module versioning not be sufficient?
We already break out-of-tree modules without a second thought, the
module interface is not guaranteed. They just need to cope with it.
Anything using the kernel headers to look into the kernel guts should be
bound to the same rules.
So if we think of BFP stuff as out-of-tree modules, and treat them the
same, I see no problem.
I'm sure some BFP 'scripts' will turn in the same right mess that
out-of-tree modules are, with endless #ifdef version checks, but hey,
not my problem ;-)
^ permalink raw reply
* [PATCH] drivers: net: xgene: Make xgene_enet_of_match depend on CONFIG_OF
From: Geert Uytterhoeven @ 2015-02-11 10:25 UTC (permalink / raw)
To: David S. Miller, Iyappan Subramanian, Keyur Chudgar, Feng Kan
Cc: netdev, linux-kernel, Geert Uytterhoeven
If CONFIG_NET_XGENE=y but CONFIG_OF=n:
drivers/net/ethernet/apm/xgene/xgene_enet_main.c:1033: warning: ‘xgene_enet_of_match’ defined but not used
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 44b15373d6b3e628..4de62b210c85bab8 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -1030,12 +1030,14 @@ static const struct acpi_device_id xgene_enet_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, xgene_enet_acpi_match);
#endif
+#ifdef CONFIG_OF
static struct of_device_id xgene_enet_of_match[] = {
{.compatible = "apm,xgene-enet",},
{},
};
MODULE_DEVICE_TABLE(of, xgene_enet_of_match);
+#endif
static struct platform_driver xgene_enet_driver = {
.driver = {
--
1.9.1
^ permalink raw reply related
* [PATCH] openvswitch: Add missing initialization in validate_and_copy_set_tun()
From: Geert Uytterhoeven @ 2015-02-11 10:23 UTC (permalink / raw)
To: David S. Miller, Pravin Shelar, Thomas Graf
Cc: netdev, dev, linux-kernel, Geert Uytterhoeven
net/openvswitch/flow_netlink.c: In function ‘validate_and_copy_set_tun’:
net/openvswitch/flow_netlink.c:1749: warning: ‘err’ may be used uninitialized in this function
If ipv4_tun_from_nlattr() returns a different positive value than
OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS, err will be uninitialized, and
validate_and_copy_set_tun() may return an undefined value instead of a
zero success indicator. Initialize err to zero to fix this.
Fixes: 1dd144cf5b4b47e1 ("openvswitch: Support VXLAN Group Policy extension")
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
net/openvswitch/flow_netlink.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index 993281e6278dc829..3829328c5a7648bf 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -1746,7 +1746,7 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
struct sw_flow_key key;
struct ovs_tunnel_info *tun_info;
struct nlattr *a;
- int err, start, opts_type;
+ int err = 0, start, opts_type;
ovs_match_init(&match, &key, NULL);
opts_type = ipv4_tun_from_nlattr(nla_data(attr), &match, false, log);
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v3 linux-trace 1/8] tracing: attach eBPF programs to tracepoints and syscalls
From: Peter Zijlstra @ 2015-02-11 10:15 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Steven Rostedt, Ingo Molnar, Namhyung Kim,
Arnaldo Carvalho de Melo, Jiri Olsa, Masami Hiramatsu, Linux API,
Network Development, LKML, Linus Torvalds, Eric W. Biederman
In-Reply-To: <CAMEtUuzY_Po=WtFEFg1aqzJ8dEF4rHGcWDsaS44KYgACMNPPgA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, Feb 10, 2015 at 04:22:50PM -0800, Alexei Starovoitov wrote:
> > It would need to do more that that. It may have to calculate the value
> > that it returns, as the internal value may be different with different
> > kernels.
>
> back to 'prio'... the 'prio' accessible from the program
> should be the same 'prio' that we're storing inside task_struct.
Its not, task_struct::prio is an entirely different value than the one
used in sched_param::sched_priority / sched_attr::sched_priority.
And the 'problem' is, prio is only relevant to SCHED_RR/SCHED_FIFO
tasks, we have more classes.
> No extra conversions.
We're not going to add runtime/space overhead to the kernel just because
someone might maybe someday trace the kernel.
That leaves the option of either tracing the kernel internal value and
userspace will just have to deal with it, or making the tracepoint more
expensive by having it do the conversion.
Now the big question is, what do we do when we add/extend a scheduling
class and have more parameters? We cannot change the tracepoint because
userspace assumes format. And I simply refuse to add a second -- because
that will end up being a third and fourth etc.. -- tracepoint right next
to it with a different layout.
Note that we just did add a class, we grew SCHED_DEADLINE a few releases
ago, and that has 3 parameters (or 6 depending on how you look at it).
You currently cannot 'debug' that with the existing tracepoints.
In short, I loathe traceevents, they're more trouble than they're worth.
Now I do love the infrastructure, its very useful debugging, but that's
all with local hacks that will never see the light of day.
^ permalink raw reply
* Re: [PATCH] ath9k_htc: add adaptive usb receive flow control to repair soft lockup with monitor mode
From: Yuwei Zheng @ 2015-02-10 0:36 UTC (permalink / raw)
To: Kalle Valo
Cc: linux-kernel, ath9k-devel, linux-wireless, ath9k-devel, netdev,
zhengyuwei
In-Reply-To: <87oap0n6rv.fsf@kamboji.qca.qualcomm.com>
On 三, 2015-02-11 at 11:20 +0200, Kalle Valo wrote:
> Yuwei Zheng <yuweizheng@139.com> writes:
>
> > The ath9k_hif_usb_rx_cb function excute on the interrupt context, and ath9k_rx_tasklet excute
> > on the soft irq context. In other words, the ath9k_hif_usb_rx_cb have more chance to excute than
> > ath9k_rx_tasklet. So in the worst condition, the rx.rxbuf receive list is always full,
> > and the do {}while(true) loop will not be break. The kernel get a soft lockup panic.
> >
> > [59011.007210] BUG: soft lockup - CPU#0 stuck for 23s!
> > [kworker/0:0:30609]
> > [59011.030560] BUG: scheduling while atomic: kworker/0:0/30609/0x40010100
> > [59013.804486] BUG: scheduling while atomic: kworker/0:0/30609/0x40010100
> > [59013.858522] Kernel panic - not syncing: softlockup: hung tasks
> >
> > [59014.038891] Exception stack(0xdf4bbc38 to 0xdf4bbc80)
> > [59014.046834] bc20: de57b950 60000113
> > [59014.059579] bc40: 00000000 bb32bb32 60000113 de57b948 de57b500 dc7bb440 df4bbcd0 00000000
> > [59014.072337] bc60: de57b950 60000113 df4bbcd0 df4bbc80 c04c259d c04c25a0 60000133 ffffffff
> > [59014.085233] [<c04c28db>] (__irq_svc+0x3b/0x5c) from [<c04c25a0>] (_raw_spin_unlock_irqrestore+0xc/0x10)
> > [59014.100437] [<c04c25a0>] (_raw_spin_unlock_irqrestore+0xc/0x10) from [<bf9c2089>] (ath9k_rx_tasklet+0x290/0x490 [ath9k_htc])
> > [59014.118267] [<bf9c2089>] (ath9k_rx_tasklet+0x290/0x490 [ath9k_htc]) from [<c0036d23>] (tasklet_action+0x3b/0x98)
> > [59014.134132] [<c0036d23>] (tasklet_action+0x3b/0x98) from [<c0036709>] (__do_softirq+0x99/0x16c)
> > [59014.147784] [<c0036709>] (__do_softirq+0x99/0x16c) from [<c00369f7>] (irq_exit+0x5b/0x5c)
> > [59014.160653] [<c00369f7>] (irq_exit+0x5b/0x5c) from [<c000cfc3>] (handle_IRQ+0x37/0x78)
> > [59014.173124] [<c000cfc3>] (handle_IRQ+0x37/0x78) from [<c00085df>] (omap3_intc_handle_irq+0x5f/0x68)
> > [59014.187225] [<c00085df>] (omap3_intc_handle_irq+0x5f/0x68) from [<c04c28db>](__irq_svc+0x3b/0x5c)
> >
> > This bug can be see with low performance board, such as uniprocessor beagle bone board. Add some debug message in the ath9k_hif_usb_rx_cb
> > function may trigger this bug quickly.
> >
> > Signed-off-by: Yuwei Zheng <yuweizheng@139.com>
>
> The word wrapping is still wrong, please limit the line length to 72
> chars or so. This is the second time I'm mentioning that. Also add v2,
> v3 and so on when you send new versions of the patch, otherwise I will
> not know what version I should use. And even better if you add a
> changelog after "---" line.
>
> Documentation/SubmittingPatches should tell you all this.
>
I have modified and resubmited as you suggest.
Thanks.
^ permalink raw reply
* Re: [PATCH v3 linux-trace 1/8] tracing: attach eBPF programs to tracepoints and syscalls
From: Peter Zijlstra @ 2015-02-11 9:45 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Steven Rostedt, Ingo Molnar, Namhyung Kim,
Arnaldo Carvalho de Melo, Jiri Olsa, Masami Hiramatsu, Linux API,
Network Development, LKML, Linus Torvalds, Eric W. Biederman
In-Reply-To: <CAMEtUuzY_Po=WtFEFg1aqzJ8dEF4rHGcWDsaS44KYgACMNPPgA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, Feb 10, 2015 at 04:22:50PM -0800, Alexei Starovoitov wrote:
> well, ->prio and ->pid are already printed by sched tracepoints
> and their meaning depends on scheduler. So users taking that
> into account.
Right, so trace_events were/are root only, and root 'should' be in the
root pid namespace, and therefore pid magically works.
And I'm not sure, but I don't think the 'nested' root available from
containers should have access to ftrace, so that should not be an issue.
Perf tries real hard to present PERF_SAMPLE_PID data in the pid
namespace of the task that created the event.
As to prio; yes this is a prime example of suck, I would love to change
that but cannot :-(. The only solace I have is that everybody who is
relying on it is broken.
There is a very good reason I'm against adding more tracepoints to the
scheduler, its a nightmare.
^ permalink raw reply
* Re: [PATCH v3 linux-trace 1/8] tracing: attach eBPF programs to tracepoints and syscalls
From: Peter Zijlstra @ 2015-02-11 9:33 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Steven Rostedt, Ingo Molnar, Namhyung Kim,
Arnaldo Carvalho de Melo, Jiri Olsa, Masami Hiramatsu, Linux API,
Network Development, LKML, Linus Torvalds, Eric W. Biederman
In-Reply-To: <CAMEtUuzY_Po=WtFEFg1aqzJ8dEF4rHGcWDsaS44KYgACMNPPgA@mail.gmail.com>
On Tue, Feb 10, 2015 at 04:22:50PM -0800, Alexei Starovoitov wrote:
> >> not all tools use libtraceevent.
> >> gdb calls perf_event_open directly:
> >> https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/nat/linux-btrace.c
> >> and parses PERF_RECORD_SAMPLE as a binary.
> >> In this case it's branch records, but I think we never said anywhere
> >> that PERF_SAMPLE_IP | PERF_SAMPLE_ADDR should come
> >> in this particular order.
> >
> > What particular order? Note, that's a hardware event, not a software
> > one.
>
> yes, but gdb assumes that 'u64 ip' precedes, 'u64 addr'
> when attr.sample_type = IP | ADDR whereas this is an
> internal order of 'if' statements inside perf_output_sample()...
This is indeed promised in the data layout description in
include/uapi/linux/perf_event.h.
There is no other way to find where fields are; perf relies on
predetermined order of fields coupled with the requested field bitmask.
So we promise the order: id, ip, pid, tid, time, addr,.. etc.
So if you request IP and ADDR but none of the other fields, then you
know your sample will start with IP and then contain ADDR.
The traceevent thing has a debug/trace-fs format description of fields
that is supposed to be used.
^ permalink raw reply
* [PATCH] et131x: use msecs_to_jiffies for conversions
From: Nicholas Mc Guire @ 2015-02-11 9:27 UTC (permalink / raw)
To: Mark Einon; +Cc: David S. Miller, netdev, linux-kernel, Nicholas Mc Guire
This is only an API consolidation and should make things more readable.
Converting milliseconds to jiffies by "val * HZ / 1000" is technically
OK but msecs_to_jiffies(val) is the cleaner solution and handles all
corner cases correctly. This is a minor API cleanup only.
Signed-off-by: Nicholas Mc Guire <hofrat@osadl.org>
---
Patch was compile-tested only for x86_64_defconfig + CONFIG_ET131X=m
Patch is against 3.19.0 (localversion-next is -next-20150211)
drivers/net/ethernet/agere/et131x.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/agere/et131x.c b/drivers/net/ethernet/agere/et131x.c
index 384dc16..9e78bc7 100644
--- a/drivers/net/ethernet/agere/et131x.c
+++ b/drivers/net/ethernet/agere/et131x.c
@@ -3127,7 +3127,8 @@ static void et131x_error_timer_handler(unsigned long data)
}
/* This is a periodic timer, so reschedule */
- mod_timer(&adapter->error_timer, jiffies + TX_ERROR_PERIOD * HZ / 1000);
+ mod_timer(&adapter->error_timer, jiffies +
+ msecs_to_jiffies(TX_ERROR_PERIOD));
}
static void et131x_adapter_memory_free(struct et131x_adapter *adapter)
@@ -3647,7 +3648,8 @@ static int et131x_open(struct net_device *netdev)
/* Start the timer to track NIC errors */
init_timer(&adapter->error_timer);
- adapter->error_timer.expires = jiffies + TX_ERROR_PERIOD * HZ / 1000;
+ adapter->error_timer.expires = jiffies +
+ msecs_to_jiffies(TX_ERROR_PERIOD);
adapter->error_timer.function = et131x_error_timer_handler;
adapter->error_timer.data = (unsigned long)adapter;
add_timer(&adapter->error_timer);
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH] ath9k_htc: add adaptive usb receive flow control to repair soft lockup with monitor mode
From: Kalle Valo @ 2015-02-11 9:20 UTC (permalink / raw)
To: Yuwei Zheng
Cc: linux-kernel, ath9k-devel, linux-wireless, ath9k-devel, netdev,
zhengyuwei
In-Reply-To: <1423506672-6686-1-git-send-email-yuweizheng@139.com>
Yuwei Zheng <yuweizheng@139.com> writes:
> The ath9k_hif_usb_rx_cb function excute on the interrupt context, and ath9k_rx_tasklet excute
> on the soft irq context. In other words, the ath9k_hif_usb_rx_cb have more chance to excute than
> ath9k_rx_tasklet. So in the worst condition, the rx.rxbuf receive list is always full,
> and the do {}while(true) loop will not be break. The kernel get a soft lockup panic.
>
> [59011.007210] BUG: soft lockup - CPU#0 stuck for 23s!
> [kworker/0:0:30609]
> [59011.030560] BUG: scheduling while atomic: kworker/0:0/30609/0x40010100
> [59013.804486] BUG: scheduling while atomic: kworker/0:0/30609/0x40010100
> [59013.858522] Kernel panic - not syncing: softlockup: hung tasks
>
> [59014.038891] Exception stack(0xdf4bbc38 to 0xdf4bbc80)
> [59014.046834] bc20: de57b950 60000113
> [59014.059579] bc40: 00000000 bb32bb32 60000113 de57b948 de57b500 dc7bb440 df4bbcd0 00000000
> [59014.072337] bc60: de57b950 60000113 df4bbcd0 df4bbc80 c04c259d c04c25a0 60000133 ffffffff
> [59014.085233] [<c04c28db>] (__irq_svc+0x3b/0x5c) from [<c04c25a0>] (_raw_spin_unlock_irqrestore+0xc/0x10)
> [59014.100437] [<c04c25a0>] (_raw_spin_unlock_irqrestore+0xc/0x10) from [<bf9c2089>] (ath9k_rx_tasklet+0x290/0x490 [ath9k_htc])
> [59014.118267] [<bf9c2089>] (ath9k_rx_tasklet+0x290/0x490 [ath9k_htc]) from [<c0036d23>] (tasklet_action+0x3b/0x98)
> [59014.134132] [<c0036d23>] (tasklet_action+0x3b/0x98) from [<c0036709>] (__do_softirq+0x99/0x16c)
> [59014.147784] [<c0036709>] (__do_softirq+0x99/0x16c) from [<c00369f7>] (irq_exit+0x5b/0x5c)
> [59014.160653] [<c00369f7>] (irq_exit+0x5b/0x5c) from [<c000cfc3>] (handle_IRQ+0x37/0x78)
> [59014.173124] [<c000cfc3>] (handle_IRQ+0x37/0x78) from [<c00085df>] (omap3_intc_handle_irq+0x5f/0x68)
> [59014.187225] [<c00085df>] (omap3_intc_handle_irq+0x5f/0x68) from [<c04c28db>](__irq_svc+0x3b/0x5c)
>
> This bug can be see with low performance board, such as uniprocessor beagle bone board. Add some debug message in the ath9k_hif_usb_rx_cb
> function may trigger this bug quickly.
>
> Signed-off-by: Yuwei Zheng <yuweizheng@139.com>
The word wrapping is still wrong, please limit the line length to 72
chars or so. This is the second time I'm mentioning that. Also add v2,
v3 and so on when you send new versions of the patch, otherwise I will
not know what version I should use. And even better if you add a
changelog after "---" line.
Documentation/SubmittingPatches should tell you all this.
--
Kalle Valo
^ permalink raw reply
* Re: Throughput regression with `tcp: refine TSO autosizing`
From: Michal Kazior @ 2015-02-11 8:57 UTC (permalink / raw)
To: Johannes Berg
Cc: Eric Dumazet, Neal Cardwell, linux-wireless, Network Development,
Eyal Perry
In-Reply-To: <1423577962.2215.2.camel-cdvu00un1VgdHxzADdlk8Q@public.gmane.org>
On 10 February 2015 at 15:19, Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org> wrote:
> On Tue, 2015-02-10 at 11:33 +0100, Michal Kazior wrote:
>
>> + if (msdu->sk) {
>> + ewma_add(&ar->tx_delay_us,
>> + ktime_to_ns(ktime_sub(ktime_get(), skb_cb->stamp)) /
>> + NSEC_PER_USEC);
>> +
>> + ACCESS_ONCE(msdu->sk->sk_tx_completion_delay_cushion) =
>> + (ewma_read(&ar->tx_delay_us) *
>> + msdu->sk->sk_pacing_rate) >> 20;
>> + }
>
> To some extent, every wifi driver is going to have this problem. Perhaps
> we should do this in mac80211?
Good point. I was actually thinking about it. I can try cooking a
patch unless you want to do it yourself :-)
Michał
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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: Throughput regression with `tcp: refine TSO autosizing`
From: Michal Kazior @ 2015-02-11 8:33 UTC (permalink / raw)
To: Eric Dumazet
Cc: Neal Cardwell, linux-wireless, Network Development, Eyal Perry
In-Reply-To: <1423574079.28434.21.camel@edumazet-glaptop2.roam.corp.google.com>
On 10 February 2015 at 14:14, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Tue, 2015-02-10 at 11:33 +0100, Michal Kazior wrote:
>> ath10k_core_napi_dummy_poll, 64);
>> + ewma_init(&ar->tx_delay_us, 16384, 8);
>
>
> 1) 16384 factor might be too big.
>
> 2) a weight of 8 seems too low given aggregation values used in wifi.
>
> On 32bit arches, the max range for ewma value would be 262144 usec,
> a quarter of a second...
>
> You could use a factor of 64 instead, and a weight of 16.
64/16 seems to work fine as well.
On a related note: I still wonder how to get single TCP flow to reach
line rate with ath10k (it still doesn't; I reach line rate with
multiple flows only). Isn't the tcp_limit_output_bytes just too small
for devices like Wi-Fi where you can send aggregates of even 64*3*1500
bytes long in a single shot and you can't expect even a single
tx-completion of it to come in before its transmitted entirely? You
effectively operate with bursts of traffic.
Some numbers:
ath10k w/o cushion w/o aggregation 1 flow: UDP 65mbps, TCP 30mbps
ath10k w/ cushion w/o aggregation 1 flow: UDP 65mbps, TCP 59mbps
ath10k w/o cushion w/ aggregation 1 flow: UDP 650mbps, TCP 250mbps
ath10k w/ cushion w/ aggregation 1 flow: UDP 650mbps, TCP 250mbps
ath10k w/o cushion w/ aggregation 5 flows: UDP 650mbps, TCP 250mbps
ath10k w/ cushion w/ aggregation 5 flows: UDP 650mbps, TCP 600mbps
"w/o aggregation" means forcing ath10k to use 1 A-MSDU and 1 A-MPDU
per aggregate so latencies due to aggregation itself should be pretty
much nil.
If I set tcp_limit_output_bytes to 700K+ I can get ath10k w/ cushion
w/ aggregation to reach 600mbps on a single flow.
Michał
^ permalink raw reply
* [PATCH] net: wireless: libertas: debugfs.c: remove unnecessary check before calling debugfs_remove
From: Bas Peters @ 2015-02-11 8:33 UTC (permalink / raw)
To: kvalo
Cc: Bas Peters, linville, johannes.berg, dcbw, libertas-dev,
linux-wireless, netdev, linux-kernel
Debugfs_remove will check for error or NULL for us, so it is not
necessary to do this here.
Signed-off-by: Bas Peters <baspeters93@gmail.com>
---
drivers/net/wireless/libertas/debugfs.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index cc6a0a5..26cbf1d 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -742,8 +742,7 @@ void lbs_debugfs_init(void)
void lbs_debugfs_remove(void)
{
- if (lbs_dir)
- debugfs_remove(lbs_dir);
+ debugfs_remove(lbs_dir);
}
void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev)
--
2.1.0
^ permalink raw reply related
* Re: [RFC PATCH 00/29] net: VRF support
From: Shmulik Ladkani @ 2015-02-11 7:42 UTC (permalink / raw)
To: roopa
Cc: David Ahern, netdev, ebiederm, Dinesh Dutt, Vipin Kumar,
Nicolas Dichtel, hannes, Eyal Birger
In-Reply-To: <54D8D84A.2080203@cumulusnetworks.com>
On Mon, 09 Feb 2015 07:54:50 -0800 roopa <roopa@cumulusnetworks.com> wrote:
> On 2/5/15, 10:10 PM, Shmulik Ladkani wrote:
> > On Thu, 05 Feb 2015 15:12:57 -0800 roopa <roopa@cumulusnetworks.com> wrote:
> >> We have been playing with ip rules to implement vrfs. And the blocker
> >> today is that we cannot bind a socket to a vrf (routing tables in this
> >> case).
> >
> > One option would be using SO_MARK sockopt on that socket, and have an ip
> > rule which matches this mark to point to your table.
> > I don't know your exact use-cases, but you can play around with that
> > idea.
>
> yes, SO_MARK and 'ip rule fwmark' is an option to bind tx from a socket
> to a table. But, There are more things that will be needed on the rx side.
> and at this point we are not considering netfilter marking of the
> ingress packets so haven't been following this option
In the past we've implemented small-scale L3 segmentation using multiple
tables, without using netfilter marking.
We've used 'iif' rules for rx (as application knows its interface-to-vrf
mapping, it may provision 'iif' rules to point to the appropriate table).
For locally originated traffic, SO_MARK and 'mark' rules were used.
An 'ingress-netdevice to mark' mapping would make such solution less
awkward, but one might claim such mapping is not generic as it leaks
application specific knowledge and logic into the network stack.
Also, the downside of using multiple-tables based solution might
probably be lack of scalability, as the amount of ip rules in such a
scheme grows linearily with number of L3 segments.
Regards,
Shmulik
^ permalink raw reply
* [PATCH net-next 3/3] r8152: support setting rx coalesce
From: Hayes Wang @ 2015-02-11 6:46 UTC (permalink / raw)
To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang
In-Reply-To: <1394712342-15778-137-Taiwan-albertk@realtek.com>
Support setting the rx coalesce. Then someone could change the rx
agg timeout value through ethtool.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
drivers/net/usb/r8152.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index c5301ca..e4e7238 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3660,6 +3660,61 @@ out:
return ret;
}
+static int rtl8152_get_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coalesce)
+{
+ struct r8152 *tp = netdev_priv(netdev);
+
+ switch (tp->version) {
+ case RTL_VER_01:
+ case RTL_VER_02:
+ return -EOPNOTSUPP;
+ default:
+ break;
+ }
+
+ coalesce->rx_coalesce_usecs = tp->coalesce;
+
+ return 0;
+}
+
+static int rtl8152_set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coalesce)
+{
+ struct r8152 *tp = netdev_priv(netdev);
+ int ret;
+
+ switch (tp->version) {
+ case RTL_VER_01:
+ case RTL_VER_02:
+ return -EOPNOTSUPP;
+ default:
+ break;
+ }
+
+ if (coalesce->rx_coalesce_usecs > COALESCE_SLOW)
+ return -EINVAL;
+
+ ret = usb_autopm_get_interface(tp->intf);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&tp->control);
+
+ if (tp->coalesce != coalesce->rx_coalesce_usecs) {
+ tp->coalesce = coalesce->rx_coalesce_usecs;
+
+ if (netif_running(tp->netdev) && netif_carrier_ok(netdev))
+ r8153_set_rx_early_timeout(tp);
+ }
+
+ mutex_unlock(&tp->control);
+
+ usb_autopm_put_interface(tp->intf);
+
+ return ret;
+}
+
static struct ethtool_ops ops = {
.get_drvinfo = rtl8152_get_drvinfo,
.get_settings = rtl8152_get_settings,
@@ -3673,6 +3728,8 @@ static struct ethtool_ops ops = {
.get_strings = rtl8152_get_strings,
.get_sset_count = rtl8152_get_sset_count,
.get_ethtool_stats = rtl8152_get_ethtool_stats,
+ .get_coalesce = rtl8152_get_coalesce,
+ .set_coalesce = rtl8152_set_coalesce,
.get_eee = rtl_ethtool_get_eee,
.set_eee = rtl_ethtool_set_eee,
};
--
2.1.0
^ permalink raw reply related
* [PATCH net-next 2/3] r8152: change rx early size when the mtu is changed
From: Hayes Wang @ 2015-02-11 6:46 UTC (permalink / raw)
To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang
In-Reply-To: <1394712342-15778-137-Taiwan-albertk@realtek.com>
The rx early size is calculated with the mtu, so it has to be
re-calculated when the mtu is changed.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
drivers/net/usb/r8152.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index b043c7f..c5301ca 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3724,6 +3724,7 @@ out:
static int rtl8152_change_mtu(struct net_device *dev, int new_mtu)
{
struct r8152 *tp = netdev_priv(dev);
+ int ret;
switch (tp->version) {
case RTL_VER_01:
@@ -3736,9 +3737,22 @@ static int rtl8152_change_mtu(struct net_device *dev, int new_mtu)
if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU)
return -EINVAL;
+ ret = usb_autopm_get_interface(tp->intf);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&tp->control);
+
dev->mtu = new_mtu;
- return 0;
+ if (netif_running(dev) && netif_carrier_ok(dev))
+ r8153_set_rx_early_size(tp);
+
+ mutex_unlock(&tp->control);
+
+ usb_autopm_put_interface(tp->intf);
+
+ return ret;
}
static const struct net_device_ops rtl8152_netdev_ops = {
--
2.1.0
^ permalink raw reply related
* [PATCH net-next 1/3] r8152: separate USB_RX_EARLY_AGG
From: Hayes Wang @ 2015-02-11 6:46 UTC (permalink / raw)
To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang
In-Reply-To: <1394712342-15778-137-Taiwan-albertk@realtek.com>
Separate USB_RX_EARLY_AGG into USB_RX_EARLY_TIMEOUT and USB_RX_EARLY_SIZE.
Replace r8153_set_rx_agg() with r8153_set_rx_early_timeout() and
r8153_set_rx_early_size().
Set the default timeout value according to the USB speed.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
drivers/net/usb/r8152.c | 55 ++++++++++++++++++++++++++-----------------------
1 file changed, 29 insertions(+), 26 deletions(-)
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 5980ac6..b043c7f 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -97,7 +97,8 @@
#define USB_TX_AGG 0xd40a
#define USB_RX_BUF_TH 0xd40c
#define USB_USB_TIMER 0xd428
-#define USB_RX_EARLY_AGG 0xd42c
+#define USB_RX_EARLY_TIMEOUT 0xd42c
+#define USB_RX_EARLY_SIZE 0xd42e
#define USB_PM_CTRL_STATUS 0xd432
#define USB_TX_DMA 0xd434
#define USB_TOLERANCE 0xd490
@@ -325,10 +326,10 @@
/* USB_MISC_0 */
#define PCUT_STATUS 0x0001
-/* USB_RX_EARLY_AGG */
-#define EARLY_AGG_SUPPER 0x0e832981
-#define EARLY_AGG_HIGH 0x0e837a12
-#define EARLY_AGG_SLOW 0x0e83ffff
+/* USB_RX_EARLY_TIMEOUT */
+#define COALESCE_SUPER 85000U
+#define COALESCE_HIGH 250000U
+#define COALESCE_SLOW 524280U
/* USB_WDT11_CTRL */
#define TIMER11_EN 0x0001
@@ -578,6 +579,7 @@ struct r8152 {
u32 saved_wolopts;
u32 msg_enable;
u32 tx_qlen;
+ u32 coalesce;
u16 ocp_base;
u8 *intr_buff;
u8 version;
@@ -2114,28 +2116,21 @@ static int rtl8152_enable(struct r8152 *tp)
return rtl_enable(tp);
}
-static void r8153_set_rx_agg(struct r8152 *tp)
+static void r8153_set_rx_early_timeout(struct r8152 *tp)
{
- u8 speed;
+ u32 ocp_data;
- speed = rtl8152_get_speed(tp);
- if (speed & _1000bps) {
- if (tp->udev->speed == USB_SPEED_SUPER) {
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
- RX_THR_SUPPER);
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
- EARLY_AGG_SUPPER);
- } else {
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
- RX_THR_HIGH);
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
- EARLY_AGG_HIGH);
- }
- } else {
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_SLOW);
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
- EARLY_AGG_SLOW);
- }
+ ocp_data = tp->coalesce / 8;
+ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_TIMEOUT, ocp_data);
+}
+
+static void r8153_set_rx_early_size(struct r8152 *tp)
+{
+ struct net_device *dev = tp->netdev;
+ u32 ocp_data;
+
+ ocp_data = (agg_buf_sz - dev->mtu - VLAN_ETH_HLEN - VLAN_HLEN) / 4;
+ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, ocp_data);
}
static int rtl8153_enable(struct r8152 *tp)
@@ -2145,7 +2140,8 @@ static int rtl8153_enable(struct r8152 *tp)
set_tx_qlen(tp);
rtl_set_eee_plus(tp);
- r8153_set_rx_agg(tp);
+ r8153_set_rx_early_timeout(tp);
+ r8153_set_rx_early_size(tp);
return rtl_enable(tp);
}
@@ -3911,6 +3907,13 @@ static int rtl8152_probe(struct usb_interface *intf,
tp->mii.reg_num_mask = 0x1f;
tp->mii.phy_id = R8152_PHY_ID;
+ if (udev->speed == USB_SPEED_SUPER)
+ tp->coalesce = COALESCE_SUPER;
+ else if (udev->speed == USB_SPEED_HIGH)
+ tp->coalesce = COALESCE_HIGH;
+ else
+ tp->coalesce = COALESCE_SLOW;
+
intf->needs_remote_wakeup = 1;
tp->rtl_ops.init(tp);
--
2.1.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox