@@ -268,6 +268,26 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac,return0;}+staticvoidbgmac_dma_rx_setup_desc(structbgmac*bgmac,+structbgmac_dma_ring*ring,intdesc_idx)+{+structbgmac_dma_desc*dma_desc=ring->cpu_base+desc_idx;+u32ctl0=0,ctl1=0;++if(desc_idx==ring->num_slots-1)+ctl0|=BGMAC_DESC_CTL0_EOT;+ctl1|=BGMAC_RX_BUF_SIZE&BGMAC_DESC_CTL1_LEN;+/* Is there any BGMAC device that requires extension? */+/* ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT) &+*B43_DMA64_DCTL1_ADDREXT_MASK;+*/++dma_desc->addr_low=cpu_to_le32(lower_32_bits(ring->slots[desc_idx].dma_addr));+dma_desc->addr_high=cpu_to_le32(upper_32_bits(ring->slots[desc_idx].dma_addr));+dma_desc->ctl0=cpu_to_le32(ctl0);+dma_desc->ctl1=cpu_to_le32(ctl1);+}+staticintbgmac_dma_rx_read(structbgmac*bgmac,structbgmac_dma_ring*ring,intweight){
It makes more sense to allocate new (empty) skb and pass it to the
hardware. That way we avoid copying whole packet into new skb which
should result in better performance.
---
drivers/net/ethernet/broadcom/bgmac.c | 74 ++++++++++++++++++++++++---------
1 file changed, 54 insertions(+), 20 deletions(-)
@@ -304,9 +304,9 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,structdevice*dma_dev=bgmac->core->dma_dev;structbgmac_slot_info*slot=&ring->slots[ring->start];structsk_buff*skb=slot->skb;-structsk_buff*new_skb;structbgmac_rx_header*rx;u16len,flags;+boolresync_skb=true;/* Unmap buffer to make it accessible to the CPU */dma_sync_single_for_cpu(dma_dev,slot->dma_addr,
@@ -317,36 +317,70 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,len=le16_to_cpu(rx->len);flags=le16_to_cpu(rx->flags);-/* Check for poison and drop or pass the packet */-if(len==0xdead&&flags==0xbeef){-bgmac_err(bgmac,"Found poisoned packet at slot %d, DMA issue!\n",-ring->start);-}else{+do{+/* Check for poisoned packet */+if(len==0xdead&&flags==0xbeef){+bgmac_err(bgmac,"Found poisoned packet at slot %d, DMA issue!\n",+ring->start);+break;+}+/* Omit CRC. */len-=ETH_FCS_LEN;-new_skb=netdev_alloc_skb_ip_align(bgmac->net_dev,len);-if(new_skb){+/* Use skb_copy for small packets only */+if(len>1){+dma_addr_told_dma_addr=slot->dma_addr;+interr;++/* Prepare new skb for further packets */+err=bgmac_dma_rx_skb_for_slot(bgmac,slot);+if(err){+bgmac_err(bgmac,"Couldn't allocate new skb for slot %d!\n",+ring->start);+bgmac->net_dev->stats.rx_dropped++;+break;+}+bgmac_dma_rx_setup_desc(bgmac,ring,+ring->start);++/* Unmap old skb, we'll pass it to the netfif */+dma_unmap_single(dma_dev,old_dma_addr,+BGMAC_RX_BUF_SIZE,+DMA_FROM_DEVICE);+resync_skb=false;++skb_put(skb,BGMAC_RX_FRAME_OFFSET+len);+skb_pull(skb,BGMAC_RX_FRAME_OFFSET);+}else{+structsk_buff*new_skb;++/* Poison the old skb */+rx->len=cpu_to_le16(0xdead);+rx->flags=cpu_to_le16(0xbeef);++new_skb=netdev_alloc_skb_ip_align(bgmac->net_dev,len);+if(!new_skb){+bgmac_err(bgmac,"Allocation of skb for copying packet failed!\n");+bgmac->net_dev->stats.rx_dropped++;+break;+}+skb_put(new_skb,len);skb_copy_from_linear_data_offset(skb,BGMAC_RX_FRAME_OFFSET,new_skb->data,len);-skb_checksum_none_assert(skb);-new_skb->protocol=-eth_type_trans(new_skb,bgmac->net_dev);-netif_receive_skb(new_skb);-handled++;-}else{-bgmac->net_dev->stats.rx_dropped++;-bgmac_err(bgmac,"Allocation of skb for copying packet failed!\n");+skb=new_skb;}-/* Poison the old skb */-rx->len=cpu_to_le16(0xdead);-rx->flags=cpu_to_le16(0xbeef);-}+skb_checksum_none_assert(skb);+skb->protocol=eth_type_trans(skb,bgmac->net_dev);+netif_receive_skb(skb);+handled++;+}while(0);/* Make it back accessible to the hardware */+if(resync_skb)dma_sync_single_for_device(dma_dev,slot->dma_addr,BGMAC_RX_BUF_SIZE,DMA_FROM_DEVICE);
It makes more sense to allocate new (empty) skb and pass it to the
hardware. That way we avoid copying whole packet into new skb which
should result in better performance.
I did some testing of this patch using "perf" tool and iperf -s
running on the OpenWrt machine (with bgmac supported hardware).
There are the results:
No network usage:
64.93% [kernel] [k] arch_cpu_idle
16.10% [kernel] [k] arch_local_irq_restore
11.52% [kernel] [k] cpu_startup_entry
Running iperf on PC: iperf -c 192.168.1.1
23.57% [kernel] [k] __copy_user_common
10.57% [kernel] [k] csum_partial
8.87% [kernel] [k] arch_cpu_idle
4.74% [kernel] [k] arch_local_irq_restore
4.30% [ip_tables] [k] ipt_do_table
2.91% [nf_conntrack] [k] nf_conntrack_in
2.44% [kernel] [k] __netif_receive_skb_core
2.36% [kernel] [k] r4k_dma_cache_inv
2.33% [nf_conntrack] [k] nf_conntrack_proto_fini
With 0002-bgmac-pass-received-packet-to-the-netif-instead-of-c.patch
14.83% [kernel] [k] __copy_user_common
14.81% [kernel] [k] csum_partial
4.24% [ip_tables] [k] ipt_do_table
3.69% [kernel] [k] arch_local_irq_restore
3.54% [kernel] [k] __netif_receive_skb_core
3.38% [kernel] [k] r4k_dma_cache_inv
3.24% [nf_conntrack] [k] nf_conntrack_in
2.95% [xt_conntrack] [k] 0x0000018c
2.88% [nf_conntrack] [k] nf_conntrack_proto_fini
2.58% [iptable_nat] [k] 0x00000008
2.32% [bgmac] [k] 0x00000d9c
2.18% [nf_conntrack_ipv4] [k] need_ipv4_conntrack
So you can see that __copy_user_common usage has really decreased with
this patch!
Unfortunately it didn't result in better performance... no idea why :(
--
Rafał
From: Felix Fietkau <hidden> Date: 2013-08-15 11:47:34
On 2013-08-15 1:36 PM, Rafał Miłecki wrote:
2013/8/11 Rafał Miłecki [off-list ref]:
quoted
It makes more sense to allocate new (empty) skb and pass it to the
hardware. That way we avoid copying whole packet into new skb which
should result in better performance.
I did some testing of this patch using "perf" tool and iperf -s
running on the OpenWrt machine (with bgmac supported hardware).
So you can see that __copy_user_common usage has really decreased with
this patch!
Unfortunately it didn't result in better performance... no idea why :(
Running iperf on the router is not useful as an indicator of routing
performance. Please focus on tests where you only push traffic through
the router, not directly to it.
- Felix
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
It makes more sense to allocate new (empty) skb and pass it to the
hardware. That way we avoid copying whole packet into new skb which
should result in better performance.
I did some testing of this patch using "perf" tool and iperf -s
running on the OpenWrt machine (with bgmac supported hardware).
So you can see that __copy_user_common usage has really decreased with
this patch!
Unfortunately it didn't result in better performance... no idea why :(
Running iperf on the router is not useful as an indicator of routing
performance. Please focus on tests where you only push traffic through
the router, not directly to it.
OK, so I started "iperf -s" on notebook plugged into WAN port, and
then played with "iperf -c" on notebook connected to LAN#2.
With some old 3.6.11 based OpenWrt build I got:
[ 4] 0.0-60.0 sec 690 MBytes 96.4 Mbits/sec
With very recent 3.10.4 based OpenWrt build:
[ 4] 0.0-60.0 sec 667 MBytes 93.2 Mbits/sec
After applying my patch on top of that 3.10.4:
[ 5] 0.0-60.0 sec 759 MBytes 106 Mbits/sec
And some dumps from "perf top":
3.10.4
6.75% [kernel] [k] __copy_user_common
6.73% [ip_tables] [k] ipt_do_table
4.33% [kernel] [k] arch_cpu_idle
3.96% [kernel] [k] arch_local_irq_restore
3.42% [bgmac] [k] 0x000007e0
3.35% [nf_conntrack] [k] nf_conntrack_proto_fini
2.72% [nf_conntrack] [k] nf_conntrack_in
2.50% [kernel] [k] __netif_receive_skb_core
2.42% [kernel] [k] r4k_dma_cache_inv
2.38% [kernel] [k] fib_table_lookup
2.20% [kernel] [k] dev_queue_xmit
2.11% [xt_conntrack] [k] 0x00000360
2.10% [kernel] [k] ip_route_input_noref
2.06% [nf_conntrack_ipv4] [k] need_ipv4_conntrack
3.10.4 + 0002-bgmac-pass-received-packet-to-the-netif-instead-of-c.patch
6.09% [ip_tables] [k] ipt_do_table
4.71% [kernel] [k] arch_cpu_idle
4.48% [bgmac] [k] 0x00000d7c
3.50% [nf_conntrack] [k] nf_conntrack_in
3.22% [kernel] [k] arch_local_irq_restore
3.16% [nf_conntrack] [k] nf_conntrack_proto_fini
2.88% [kernel] [k] __netif_receive_skb_core
2.78% [xt_conntrack] [k] 0x0000011c
2.69% [kernel] [k] r4k_dma_cache_inv
2.67% [iptable_nat] [k] 0x000002a0
2.36% [kernel] [k] ip_route_input_noref
2.27% [kernel] [k] ip_rcv
2.25% [nf_conntrack_ipv4] [k] need_ipv4_conntrack
2.23% [kernel] [k] nf_iterate
I've compiled bgmac into the kernel and it seems that the magic 0xd7c
was bgmac_poll.
I'm afraid this "perf top" output doesn't really tell us where to look
for optimizations :| I'll still try Felix ideas tomorrow, but I'm not
sure if they help, since there isn't __copy_user_common anymore in the
"perf top" output...
--
Rafał
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
From: Felix Fietkau <hidden> Date: 2013-08-19 04:36:27
On 2013-08-15 10:21 PM, Rafał Miłecki wrote:
2013/8/15 Felix Fietkau [off-list ref]:
quoted
On 2013-08-15 1:36 PM, Rafał Miłecki wrote:
quoted
2013/8/11 Rafał Miłecki [off-list ref]:
quoted
It makes more sense to allocate new (empty) skb and pass it to the
hardware. That way we avoid copying whole packet into new skb which
should result in better performance.
I did some testing of this patch using "perf" tool and iperf -s
running on the OpenWrt machine (with bgmac supported hardware).
So you can see that __copy_user_common usage has really decreased with
this patch!
Unfortunately it didn't result in better performance... no idea why :(
Running iperf on the router is not useful as an indicator of routing
performance. Please focus on tests where you only push traffic through
the router, not directly to it.
OK, so I started "iperf -s" on notebook plugged into WAN port, and
then played with "iperf -c" on notebook connected to LAN#2.
With some old 3.6.11 based OpenWrt build I got:
[ 4] 0.0-60.0 sec 690 MBytes 96.4 Mbits/sec
With very recent 3.10.4 based OpenWrt build:
[ 4] 0.0-60.0 sec 667 MBytes 93.2 Mbits/sec
After applying my patch on top of that 3.10.4:
[ 5] 0.0-60.0 sec 759 MBytes 106 Mbits/sec
And some dumps from "perf top":
3.10.4
6.75% [kernel] [k] __copy_user_common
6.73% [ip_tables] [k] ipt_do_table
4.33% [kernel] [k] arch_cpu_idle
3.96% [kernel] [k] arch_local_irq_restore
3.42% [bgmac] [k] 0x000007e0
3.35% [nf_conntrack] [k] nf_conntrack_proto_fini
2.72% [nf_conntrack] [k] nf_conntrack_in
2.50% [kernel] [k] __netif_receive_skb_core
2.42% [kernel] [k] r4k_dma_cache_inv
2.38% [kernel] [k] fib_table_lookup
2.20% [kernel] [k] dev_queue_xmit
2.11% [xt_conntrack] [k] 0x00000360
2.10% [kernel] [k] ip_route_input_noref
2.06% [nf_conntrack_ipv4] [k] need_ipv4_conntrack
3.10.4 + 0002-bgmac-pass-received-packet-to-the-netif-instead-of-c.patch
6.09% [ip_tables] [k] ipt_do_table
4.71% [kernel] [k] arch_cpu_idle
4.48% [bgmac] [k] 0x00000d7c
3.50% [nf_conntrack] [k] nf_conntrack_in
3.22% [kernel] [k] arch_local_irq_restore
3.16% [nf_conntrack] [k] nf_conntrack_proto_fini
2.88% [kernel] [k] __netif_receive_skb_core
2.78% [xt_conntrack] [k] 0x0000011c
2.69% [kernel] [k] r4k_dma_cache_inv
2.67% [iptable_nat] [k] 0x000002a0
2.36% [kernel] [k] ip_route_input_noref
2.27% [kernel] [k] ip_rcv
2.25% [nf_conntrack_ipv4] [k] need_ipv4_conntrack
2.23% [kernel] [k] nf_iterate
I've compiled bgmac into the kernel and it seems that the magic 0xd7c
was bgmac_poll.
I'm afraid this "perf top" output doesn't really tell us where to look
for optimizations :| I'll still try Felix ideas tomorrow, but I'm not
sure if they help, since there isn't __copy_user_common anymore in the
"perf top" output...
What's the CPU load while passing traffic without running perf?
Have you tested bridging performance?
- Felix
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
I'm afraid this "perf top" output doesn't really tell us where to look
for optimizations :| I'll still try Felix ideas tomorrow, but I'm not
sure if they help, since there isn't __copy_user_common anymore in the
"perf top" output...
What's the CPU load while passing traffic without running perf?
Do you mean connecting both machines to the same VLAN? Like 2 LAN
ports in the standard configuration? It gives me ~600Mb/s using
OpenWrt. It's pretty much the same performance I got with the original
firmware for transfer between 2 VLANs.
[ 5] local 192.168.1.218 port 5001 connected with 192.168.1.131 port 59463
[ 5] 0.0-60.0 sec 4.16 GBytes 596 Mbits/sec
--
Rafał
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel