* Re: [PATCH] net: sk == 0xffffffff fix - not for commit
From: Andrew Ruder @ 2014-01-17 0:01 UTC (permalink / raw)
To: Andrzej Pietrasiewicz
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA, Kyungmin Park, Felipe Balbi,
Greg Kroah-Hartman, Marek Szyprowski, Michal Nazarewicz,
David S. Miller, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, Patrick McHardy, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1386589672-5830-1-git-send-email-andrzej.p-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
On Mon, Dec 09, 2013 at 12:47:52PM +0100, Andrzej Pietrasiewicz wrote:
> With g_ether loaded the sk occasionally becomes 0xffffffff.
> It happens usually after transferring few hundreds of kilobytes to few
> tens of megabytes. If sk is 0xffffffff then dereferencing it causes
> kernel panic.
Don't know if this is relevant but I had this very similar stack trace
come up a few days ago (below). I am working on a PXA 270/xscale with
gcc version 4.8.2 (Buildroot 2013.11-rc1-00028-gf388663). Going to try
to see if I can reproduce it a little more readily before I start trying
to narrow down what is causing it.
===
Unable to handle kernel NULL pointer dereference at virtual address 00000011
pgd = d18e0000
[00000011] *pgd=a6d03831, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1] PREEMPT ARM
Modules linked in: zeusvirt(O) zeus16550(O) 8390p ipv6
CPU: 0 PID: 2365 Comm: sshd Tainted: G O 3.12.0+ #201
task: d7216f00 ti: d7144000 task.ti: d7144000
PC is at tcp_v4_early_demux+0xe8/0x154
LR is at __inet_lookup_established+0x1bc/0x2e0
pc : [<c0341cfc>] lr : [<c0329bd8>] psr: a0000013
sp : d7145b20 ip : d7145ae8 fp : d7145b44
r10: c0576c28 r9 : 00000008 r8 : d7998800
r7 : d7063800 r6 : c6cf2480 r5 : ffffffff r4 : c6cf2480
r3 : c02ec018 r2 : d7145ad0 r1 : d7b66a28 r0 : ffffffff
Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: 0000397f Table: b18e0000 DAC: 00000015
Process sshd (pid: 2365, stack limit = 0xd71441c8)
Stack: (0xd7145b20 to 0xd7146000)
5b20: 17bf3f0a 00000016 00000003 c0026d90 d71f4634 d71f4600 d7145b6c d7145b48
5b40: c03211b4 c0341c20 000005ea d7bb0538 d7063800 00000034 d71f4600 c6cf2480
5b60: d7145b9c d7145b70 c03218dc c0321158 00001001 00000000 c0576c1c 00000000
5b80: c0577e84 c0576c14 00000000 00000000 d7145be4 d7145ba0 c02fae04 c03215d4
5ba0: c0590330 c057fc08 d7145bfc c6cf2480 c02571a0 c0576c28 000007e1 c05a3dc0
5bc0: 00000000 00000001 c05a3d60 c05a3d74 c05a3d60 c05a3d68 d7145bfc d7145be8
5be0: c02fb990 c02fa8f0 c05a3dc0 00000000 d7145c24 d7145c00 c02fc46c c02fb968
5c00: c02fc3dc c05a3dc0 c05a3d60 00000001 0000012c 00000040 d7145c64 d7145c28
5c20: c02fbcd0 c02fc3e8 00000000 d78af3c0 d7145c5c 00008d99 00000000 00000001
5c40: c05a81f0 00000003 00000100 3fa57e1c d7144028 c05a81ec d7145cb4 d7145c68
5c60: c0026a44 c02fbc10 d7145c8c d7145c78 c00538dc c0056ce4 00000000 00008d98
5c80: 00400100 0000000a c0228594 60000093 c0590330 00000000 d7145d54 00000001
5ca0: d7bb0480 000005b4 d7145ccc d7145cb8 c0026ca4 c00268f4 00000000 d7144010
5cc0: d7145ce4 d7145cd0 c0026f58 c0026c58 000000ab 0000001a d7145d04 d7145ce8
5ce0: c000f7d0 c0026ed0 00140000 d7145d20 a0000013 ffffffff d7145d1c d7145d08
5d00: c00085bc c000f768 c02f0048 c00ca7d8 d7145d7c d7145d20 c03a7dc0 c0008590
5d20: 000118ed 00000000 c05a474c c05d41cc d7bb0180 d18ed800 d7801080 000006a3
5d40: 00000001 d7bb0480 000005b4 d7145d7c d7145d80 d7145d68 c02f0048 c00ca7d8
5d60: a0000013 ffffffff c05a4738 d7bb0180 d7145dac d7145d80 c02f0048 c00ca7b0
5d80: 00000001 00c63fc0 d7b66a00 d7b66a00 00004040 000005b4 00000000 d7b66a00
5da0: d7145dcc d7145db0 c032e340 c02effd0 d7145e98 00004040 0008c414 00000000
5dc0: d7145e54 d7145dd0 c032f368 c032e310 d7145e24 c02ea81c c03a6040 c03a9c6c
5de0: 00000000 00000000 d7145ee8 00000000 000005b4 00000000 d7b66adc 00000000
5e00: 00000000 d7144000 00001854 000005b4 000027ec 00000040 d7116d80 000005b4
5e20: 00000000 00000000 d7145e6c d7b66a00 d7145ee8 d7145e98 00004040 00004040
5e40: 00004040 00020000 d7145e74 d7145e58 c03526c8 c032eb0c d7145e78 d7116d80
5e60: d7145ee0 d7116d80 d7145ed4 d7145e78 c02e63a4 c0352688 c05a3dc0 d7142000
5e80: 00000040 00004040 d76701c0 d7145ee0 00000000 d7145e98 00000000 00000000
5ea0: d7145ee0 00000001 00000000 00000000 00000040 d7145ee8 c6cf2900 00000000
5ec0: 00000000 d7145f78 d7145f44 d7145ed8 c00d1c64 c02e62e4 00000000 00000000
5ee0: 00089c28 00004040 d7116d80 00000000 00000000 d7145e78 d7216f00 00000000
5f00: 00000000 00000000 00000000 00000000 00004040 00000000 00000000 00000000
5f20: 00089c28 d7116d80 00089c28 d7145f78 00004040 00089c28 d7145f74 d7145f48
5f40: c00d23a0 c00d1bf4 00000000 00000000 00000000 00000000 d7116d80 00000000
5f60: 00089c28 00004040 d7145fa4 d7145f78 c00d2948 c00d22c0 00000000 00000000
5f80: beed167c 00000003 000614dc 00000004 c000ea28 d7144000 00000000 d7145fa8
5fa0: c000e7e0 c00d2908 beed167c 00000003 00000003 00089c28 00004040 beed167c
5fc0: beed167c 00000003 000614dc 00000004 00089c28 00060a88 0000093e beed17a0
5fe0: beed167c beed1648 00029910 b6dc821c 60000010 00000003 ffffffff ffffffff
[<c0341cfc>] (tcp_v4_early_demux+0xe8/0x154) from [<c03211b4>] (ip_rcv_finish+0x68/0x2c0)
[<c03211b4>] (ip_rcv_finish+0x68/0x2c0) from [<c03218dc>] (ip_rcv+0x314/0x398)
[<c03218dc>] (ip_rcv+0x314/0x398) from [<c02fae04>] (__netif_receive_skb_core+0x520/0x5d8)
[<c02fae04>] (__netif_receive_skb_core+0x520/0x5d8) from [<c02fb990>] (__netif_receive_skb+0x34/0x88)
[<c02fb990>] (__netif_receive_skb+0x34/0x88) from [<c02fc46c>] (process_backlog+0x90/0x148)
[<c02fc46c>] (process_backlog+0x90/0x148) from [<c02fbcd0>] (net_rx_action+0xcc/0x258)
[<c02fbcd0>] (net_rx_action+0xcc/0x258) from [<c0026a44>] (__do_softirq+0x15c/0x2e0)
[<c0026a44>] (__do_softirq+0x15c/0x2e0) from [<c0026ca4>] (do_softirq+0x58/0x64)
[<c0026ca4>] (do_softirq+0x58/0x64) from [<c0026f58>] (irq_exit+0x94/0xf0)
[<c0026f58>] (irq_exit+0x94/0xf0) from [<c000f7d0>] (handle_IRQ+0x74/0x90)
[<c000f7d0>] (handle_IRQ+0x74/0x90) from [<c00085bc>] (ichp_handle_irq+0x38/0x40)
[<c00085bc>] (ichp_handle_irq+0x38/0x40) from [<c03a7dc0>] (__irq_svc+0x40/0x6c)
Exception stack(0xd7145d20 to 0xd7145d68)
5d20: 000118ed 00000000 c05a474c c05d41cc d7bb0180 d18ed800 d7801080 000006a3
5d40: 00000001 d7bb0480 000005b4 d7145d7c d7145d80 d7145d68 c02f0048 c00ca7d8
5d60: a0000013 ffffffff
[<c03a7dc0>] (__irq_svc+0x40/0x6c) from [<c00ca7d8>] (ksize+0x34/0xc8)
[<c00ca7d8>] (ksize+0x34/0xc8) from [<c02f0048>] (__alloc_skb+0x84/0x15c)
[<c02f0048>] (__alloc_skb+0x84/0x15c) from [<c032e340>] (sk_stream_alloc_skb+0x3c/0x108)
[<c032e340>] (sk_stream_alloc_skb+0x3c/0x108) from [<c032f368>] (tcp_sendmsg+0x868/0xd34)
[<c032f368>] (tcp_sendmsg+0x868/0xd34) from [<c03526c8>] (inet_sendmsg+0x4c/0x78)
[<c03526c8>] (inet_sendmsg+0x4c/0x78) from [<c02e63a4>] (sock_aio_write+0xcc/0xdc)
[<c02e63a4>] (sock_aio_write+0xcc/0xdc) from [<c00d1c64>] (do_sync_write+0x7c/0xa0)
[<c00d1c64>] (do_sync_write+0x7c/0xa0) from [<c00d23a0>] (vfs_write+0xec/0x194)
[<c00d23a0>] (vfs_write+0xec/0x194) from [<c00d2948>] (SyS_write+0x4c/0x7c)
[<c00d2948>] (SyS_write+0x4c/0x7c) from [<c000e7e0>] (ret_fast_syscall+0x0/0x2c)
Code: 0a000019 e59f306c e5845010 e5843068 (e5d53012)
---[ end trace 5a028e59aa5bc81a ]---
Kernel panic - not syncing: Fatal exception in interrupt
===
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" 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 v2 1/2] net/mlx4_core: clean up cq_res_start_move_to()
From: David Miller @ 2014-01-17 0:05 UTC (permalink / raw)
To: pebolle; +Cc: ogerlitz, jackm, ronye, hadarh, netdev, linux-kernel
In-Reply-To: <1389728736.28068.8.camel@x220>
From: Paul Bolle <pebolle@tiscali.nl>
Date: Tue, 14 Jan 2014 20:45:36 +0100
> Building resource_tracker.o triggers a GCC warning:
> drivers/net/ethernet/mellanox/mlx4/resource_tracker.c: In function 'mlx4_HW2SW_CQ_wrapper':
> drivers/net/ethernet/mellanox/mlx4/resource_tracker.c:3019:16: warning: 'cq' may be used uninitialized in this function [-Wmaybe-uninitialized]
> atomic_dec(&cq->mtt->ref_count);
> ^
>
> This is a false positive. But a cleanup of cq_res_start_move_to() can
> help GCC here. The code currently uses a switch statement where an
> if/else construct would do too, since only two of the switch's four
> cases can ever occur. Dropping that switch makes the warning go away.
>
> While we're at it, add some missing braces.
>
> Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
Applied.
^ permalink raw reply
* Re: [PATCH v2 2/2] net/mlx4_core: clean up srq_res_start_move_to()
From: David Miller @ 2014-01-17 0:05 UTC (permalink / raw)
To: pebolle; +Cc: ogerlitz, jackm, ronye, hadarh, netdev, linux-kernel
In-Reply-To: <1389728812.28068.9.camel@x220>
From: Paul Bolle <pebolle@tiscali.nl>
Date: Tue, 14 Jan 2014 20:46:52 +0100
> Building resource_tracker.o triggers a GCC warning:
> drivers/net/ethernet/mellanox/mlx4/resource_tracker.c: In function 'mlx4_HW2SW_SRQ_wrapper':
> drivers/net/ethernet/mellanox/mlx4/resource_tracker.c:3202:17: warning: 'srq' may be used uninitialized in this function [-Wmaybe-uninitialized]
> atomic_dec(&srq->mtt->ref_count);
> ^
>
> This is a false positive. But a cleanup of srq_res_start_move_to() can
> help GCC here. The code currently uses a switch statement where a plain
> if/else would do, since only two of the switch's four cases can ever
> occur. Dropping that switch makes the warning go away.
>
> While we're at it, add some missing braces, and convert state to the
> correct type.
>
> Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
Applied.
^ permalink raw reply
* Re: [PATCH net-next v2 2/2] bonding: try to enable SG features when adding a new, slave
From: David Miller @ 2014-01-17 0:07 UTC (permalink / raw)
To: dingtianhong; +Cc: fubar, vfalico, edumazet, netdev
In-Reply-To: <52D4FCB3.9000408@huawei.com>
From: Ding Tianhong <dingtianhong@huawei.com>
Date: Tue, 14 Jan 2014 17:00:35 +0800
> The commit b0ce3508(bonding: allow TSO being set on bonding master)
> has make the TSO being set for bond dev, but in some situation, if
> the slave did not set the NETIF_F_SG features yet, the bond master
> will miss the TSO features in netdev_fix_features because the TSO is
> depended on SG.
>
> If the slave hw support SG features, but not set yet, I will try to
> open it when enslave the dev, better for performance.
>
> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
I really don't think we should force enable device features in slaves
that perhaps the user intentionally disabled, or perhaps the driver has
a reason to disable by default (lower performance, etc.)
I'm not applying this series, sorry.
^ permalink raw reply
* Re: [PATCH-next v2] net/ipv4: don't use module_init in non-modular gre_offload
From: David Miller @ 2014-01-17 0:09 UTC (permalink / raw)
To: eric.dumazet; +Cc: paul.gortmaker, netdev, edumazet
In-Reply-To: <1389909911.31367.425.camel@edumazet-glaptop2.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 16 Jan 2014 14:05:11 -0800
> On Wed, 2014-01-15 at 11:19 -0500, Paul Gortmaker wrote:
>> Recent commit 438e38fadca2f6e57eeecc08326c8a95758594d4
>> ("gre_offload: statically build GRE offloading support") added
>> new module_init/module_exit calls to the gre_offload.c file.
> ...
>> Cc: Eric Dumazet <edumazet@google.com>
>> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
>> ---
>>
>> v2: dump gre_offload_exit entirely as suggested by Eric.
>
> Acked-by: Eric Dumazet <edumazet@google.com>
Applied, thank you.
^ permalink raw reply
* Re: i40e sym version file
From: David Miller @ 2014-01-17 0:15 UTC (permalink / raw)
To: shannon.nelson; +Cc: stephen, jeffrey.t.kirsher, netdev, aaron.f.brown
In-Reply-To: <FC41C24E35F18A40888AACA1A36F3E418A1C521E@FMSMSX102.amr.corp.intel.com>
From: "Nelson, Shannon" <shannon.nelson@intel.com>
Date: Wed, 15 Jan 2014 16:22:07 +0000
> Ooo, ick, that shouldn't be there. Jeff is on sabbatical and Aaron
> is covering, I'll work with Aaron to find what happened and get it
> straightened out.
I've removed this file from the net-next tree.
^ permalink raw reply
* Re: [PATCH net-next v3 0/3] pf_packet updates
From: David Miller @ 2014-01-17 0:17 UTC (permalink / raw)
To: dborkman; +Cc: netdev
In-Reply-To: <1389799536-23750-1-git-send-email-dborkman@redhat.com>
From: Daniel Borkmann <dborkman@redhat.com>
Date: Wed, 15 Jan 2014 16:25:33 +0100
> Changelog:
>
> v1->v2:
> - put assignments under bind lock in patch 1
> - added 2 more relevant patches
>
> v2->v3:
> - made refcnt unsigned in patch 3
> - rest unchanged
Series applied, thanks Daniel.
^ permalink raw reply
* [PATCH v7 0/4] Add ethernet support for r7s72100
From: Simon Horman @ 2014-01-17 0:22 UTC (permalink / raw)
To: David S. Miller, netdev, linux-sh
Cc: linux-arm-kernel, Magnus Damm, Sergei Shtylyov, Simon Horman
Hi,
this series adds ethernet support to sh-pfc for the r7s72100 SoC.
This series is based on a merge of:
* The topic/r7s72100-v3.13-rc8-20140115 tag in my renesas tree
* net-next
- Head revision: 08c93cd99b2f31ba9
("Merge branch 'for-davem' of git://gitorious.org/linux-can/linux-can-next")
The first two patches, targeted at net-next, also applies cleanly there.
Changes since v6
* Update change log of:
- sh_eth: Use bool as return type of sh_eth_is_gether()
Changes since v5
* Address feedback from Joe Perches and Sergei Shtylyov as detailed
in the changelogs of:
- sh_eth: Use bool as return type of sh_eth_is_gether()
- sh_eth: Add support for r7s72100
Changes since v4
* Addressed feedback from Sergei Shtylyov as detailed in the changelog
of "sh_eth: Add support for r7s72100"
* Rebase
Changes since v3
* Use bool as return type of sh_eth_is_gether()
and sh_eth_is_rz_fast_ether()
* Correct coding style in sh_eth_get_stats()
Changes since v2
* Trivial rebase
* Dropped "RFC" from subject
Changes since v1 are noted in the changelog of each patch.
Simon Horman (4):
sh_eth: Use bool as return type of sh_eth_is_gether()
sh_eth: Add support for r7s72100
ARM: shmobile: r7s72100: Add clock for r7s72100-ether
ARM: shmobile: genmai: Enable r7s72100-ether
arch/arm/mach-shmobile/board-genmai.c | 21 +++++
arch/arm/mach-shmobile/clock-r7s72100.c | 4 +
drivers/net/ethernet/renesas/sh_eth.c | 131 +++++++++++++++++++++++++++++---
drivers/net/ethernet/renesas/sh_eth.h | 3 +-
4 files changed, 146 insertions(+), 13 deletions(-)
--
1.8.4
^ permalink raw reply
* [PATCH v7 net-next 2/4] sh_eth: Add support for r7s72100
From: Simon Horman @ 2014-01-17 0:22 UTC (permalink / raw)
To: David S. Miller, netdev, linux-sh
Cc: linux-arm-kernel, Magnus Damm, Sergei Shtylyov, Simon Horman
In-Reply-To: <1389918150-19058-1-git-send-email-horms+renesas@verge.net.au>
The r7s72100 SoC includes a fast ethernet controller.
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Acked-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
---
Dave, please consider this for net-next.
v7
* No change
v6
* As suggested by Sergei Shtylyov
- Update changelog
- Position sh_eth_offset_fast_rz above sh_eth_offset_fast_rcar
- Place [TR]X[NA]LCR0 in a separate group in sh_eth_offset_fast_rz
- Simplify logic of sh_eth_is_rz_fast_ether
- Add comma after and in comment.
v5
* As suggested by Sergei Shtylyov
- Add the following missing registers to sh_eth_offset_fast_rz:
RFLR, [TR]X[NA]LCR0.
- Set the following in r7s72100_data: no_psr, no_ade, hw_crc.
- Use EDTRR_TRNS_GETHER instead of adding EDTRR_TRNS_RZ_ETHER.
- Position SH_ETH_REG_FAST_RZ before SH_ETH_REG_FAST_RCAR.
- Do not remove ',' from before 'and' in EDSR comment
v4
* As requested by David Miller
- Use a boolean for the return value of sh_eth_is_rz_fast_ether()
- Correct coding style in sh_eth_get_stats()
v3
* No change
v2
* As suggested by Magnus Damm and Sergei Shtylyov
- r7s72100 ethernet is not gigabit so do not refer to it as such
* As suggested by Magnus Damm
- As RZ specific register layout rather than using the gigabit layout
which includes registers that do not exist on this chip.
* As suggested by Sergei Shtylyov
- Do not use sh_eth_chip_reset_r8a7740 as it accesses non-existent
RMII registers. Instead use sh_eth_chip_reset.
- Do not use sh_eth_set_rate_gether as it accesses non-existent registers.
- Do not use reserved LCHNG bit of ECSR
- Do not use reserved LCHNGIP bit of ECSIPR
- Document that R8A779x also needs a 16 bit shift of the RFS bits
- Do not document that the R7S72100 has GECMR, it does not
---
drivers/net/ethernet/renesas/sh_eth.c | 124 ++++++++++++++++++++++++++++++++--
drivers/net/ethernet/renesas/sh_eth.h | 3 +-
2 files changed, 119 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index f12a929..a21be4a 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -144,6 +144,65 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
[FWALCR1] = 0x00b4,
};
+static const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = {
+ [EDSR] = 0x0000,
+ [EDMR] = 0x0400,
+ [EDTRR] = 0x0408,
+ [EDRRR] = 0x0410,
+ [EESR] = 0x0428,
+ [EESIPR] = 0x0430,
+ [TDLAR] = 0x0010,
+ [TDFAR] = 0x0014,
+ [TDFXR] = 0x0018,
+ [TDFFR] = 0x001c,
+ [RDLAR] = 0x0030,
+ [RDFAR] = 0x0034,
+ [RDFXR] = 0x0038,
+ [RDFFR] = 0x003c,
+ [TRSCER] = 0x0438,
+ [RMFCR] = 0x0440,
+ [TFTR] = 0x0448,
+ [FDR] = 0x0450,
+ [RMCR] = 0x0458,
+ [RPADIR] = 0x0460,
+ [FCFTR] = 0x0468,
+ [CSMR] = 0x04E4,
+
+ [ECMR] = 0x0500,
+ [RFLR] = 0x0508,
+ [ECSR] = 0x0510,
+ [ECSIPR] = 0x0518,
+ [PIR] = 0x0520,
+ [APR] = 0x0554,
+ [MPR] = 0x0558,
+ [PFTCR] = 0x055c,
+ [PFRCR] = 0x0560,
+ [TPAUSER] = 0x0564,
+ [MAHR] = 0x05c0,
+ [MALR] = 0x05c8,
+ [CEFCR] = 0x0740,
+ [FRECR] = 0x0748,
+ [TSFRCR] = 0x0750,
+ [TLFRCR] = 0x0758,
+ [RFCR] = 0x0760,
+ [MAFCR] = 0x0778,
+
+ [ARSTR] = 0x0000,
+ [TSU_CTRST] = 0x0004,
+ [TSU_VTAG0] = 0x0058,
+ [TSU_ADSBSY] = 0x0060,
+ [TSU_TEN] = 0x0064,
+ [TSU_ADRH0] = 0x0100,
+ [TSU_ADRL0] = 0x0104,
+ [TSU_ADRH31] = 0x01f8,
+ [TSU_ADRL31] = 0x01fc,
+
+ [TXNLCR0] = 0x0080,
+ [TXALCR0] = 0x0084,
+ [RXNLCR0] = 0x0088,
+ [RXALCR0] = 0x008C,
+};
+
static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = {
[ECMR] = 0x0300,
[RFLR] = 0x0308,
@@ -315,6 +374,11 @@ static bool sh_eth_is_gether(struct sh_eth_private *mdp)
return mdp->reg_offset == sh_eth_offset_gigabit;
}
+static bool sh_eth_is_rz_fast_ether(struct sh_eth_private *mdp)
+{
+ return mdp->reg_offset == sh_eth_offset_fast_rz;
+}
+
static void sh_eth_select_mii(struct net_device *ndev)
{
u32 value = 0x0;
@@ -698,6 +762,38 @@ static struct sh_eth_cpu_data r8a7740_data = {
.shift_rd0 = 1,
};
+/* R7S72100 */
+static struct sh_eth_cpu_data r7s72100_data = {
+ .chip_reset = sh_eth_chip_reset,
+ .set_duplex = sh_eth_set_duplex,
+
+ .register_type = SH_ETH_REG_FAST_RZ,
+
+ .ecsr_value = ECSR_ICD,
+ .ecsipr_value = ECSIPR_ICDIP,
+ .eesipr_value = 0xff7f009f,
+
+ .tx_check = EESR_TC1 | EESR_FTC,
+ .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
+ EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
+ EESR_TDE | EESR_ECI,
+ .fdr_value = 0x0000070f,
+ .rmcr_value = RMCR_RNC,
+
+ .no_psr = 1,
+ .apr = 1,
+ .mpr = 1,
+ .tpauser = 1,
+ .hw_swap = 1,
+ .rpadir = 1,
+ .rpadir_value = 2 << 16,
+ .no_trimd = 1,
+ .no_ade = 1,
+ .hw_crc = 1,
+ .tsu = 1,
+ .shift_rd0 = 1,
+};
+
static struct sh_eth_cpu_data sh7619_data = {
.register_type = SH_ETH_REG_FAST_SH3_SH2,
@@ -764,7 +860,7 @@ static int sh_eth_reset(struct net_device *ndev)
struct sh_eth_private *mdp = netdev_priv(ndev);
int ret = 0;
- if (sh_eth_is_gether(mdp)) {
+ if (sh_eth_is_gether(mdp) || sh_eth_is_rz_fast_ether(mdp)) {
sh_eth_write(ndev, EDSR_ENALL, EDSR);
sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER,
EDMR);
@@ -875,7 +971,7 @@ static void read_mac_address(struct net_device *ndev, unsigned char *mac)
static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp)
{
- if (sh_eth_is_gether(mdp))
+ if (sh_eth_is_gether(mdp) || sh_eth_is_rz_fast_ether(mdp))
return EDTRR_TRNS_GETHER;
else
return EDTRR_TRNS_ETHER;
@@ -1038,7 +1134,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
/* Rx descriptor address set */
if (i == 0) {
sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR);
- if (sh_eth_is_gether(mdp))
+ if (sh_eth_is_gether(mdp) ||
+ sh_eth_is_rz_fast_ether(mdp))
sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
}
}
@@ -1059,7 +1156,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
if (i == 0) {
/* Tx descriptor address set */
sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
- if (sh_eth_is_gether(mdp))
+ if (sh_eth_is_gether(mdp) ||
+ sh_eth_is_rz_fast_ether(mdp))
sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
}
}
@@ -1306,9 +1404,9 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
/* In case of almost all GETHER/ETHERs, the Receive Frame State
* (RFS) bits in the Receive Descriptor 0 are from bit 9 to
- * bit 0. However, in case of the R8A7740's GETHER, the RFS
- * bits are from bit 25 to bit 16. So, the driver needs right
- * shifting by 16.
+ * bit 0. However, in case of the R8A7740, R8A779x, and
+ * R7S72100 the RFS bits are from bit 25 to bit 16. So, the
+ * driver needs right shifting by 16.
*/
if (mdp->cd->shift_rd0)
desc_status >>= 16;
@@ -2058,6 +2156,9 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
+ if (sh_eth_is_rz_fast_ether(mdp))
+ return &ndev->stats;
+
pm_runtime_get_sync(&mdp->pdev->dev);
ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR);
@@ -2439,6 +2540,11 @@ static int sh_eth_vlan_rx_kill_vid(struct net_device *ndev,
/* SuperH's TSU register init function */
static void sh_eth_tsu_init(struct sh_eth_private *mdp)
{
+ if (sh_eth_is_rz_fast_ether(mdp)) {
+ sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */
+ return;
+ }
+
sh_eth_tsu_write(mdp, 0, TSU_FWEN0); /* Disable forward(0->1) */
sh_eth_tsu_write(mdp, 0, TSU_FWEN1); /* Disable forward(1->0) */
sh_eth_tsu_write(mdp, 0, TSU_FCM); /* forward fifo 3k-3k */
@@ -2558,6 +2664,9 @@ static const u16 *sh_eth_get_register_offset(int register_type)
case SH_ETH_REG_GIGABIT:
reg_offset = sh_eth_offset_gigabit;
break;
+ case SH_ETH_REG_FAST_RZ:
+ reg_offset = sh_eth_offset_fast_rz;
+ break;
case SH_ETH_REG_FAST_RCAR:
reg_offset = sh_eth_offset_fast_rcar;
break;
@@ -2796,6 +2905,7 @@ static struct platform_device_id sh_eth_id_table[] = {
{ "sh7757-ether", (kernel_ulong_t)&sh7757_data },
{ "sh7757-gether", (kernel_ulong_t)&sh7757_data_giga },
{ "sh7763-gether", (kernel_ulong_t)&sh7763_data },
+ { "r7s72100-ether", (kernel_ulong_t)&r7s72100_data },
{ "r8a7740-gether", (kernel_ulong_t)&r8a7740_data },
{ "r8a777x-ether", (kernel_ulong_t)&r8a777x_data },
{ "r8a7790-ether", (kernel_ulong_t)&r8a779x_data },
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index 0fe35b7..6075915 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -155,6 +155,7 @@ enum {
enum {
SH_ETH_REG_GIGABIT,
+ SH_ETH_REG_FAST_RZ,
SH_ETH_REG_FAST_RCAR,
SH_ETH_REG_FAST_SH4,
SH_ETH_REG_FAST_SH3_SH2
@@ -169,7 +170,7 @@ enum {
/* Register's bits
*/
-/* EDSR : sh7734, sh7757, sh7763, and r8a7740 only */
+/* EDSR : sh7734, sh7757, sh7763, r8a7740, and r7s72100 only */
enum EDSR_BIT {
EDSR_ENT = 0x01, EDSR_ENR = 0x02,
};
--
1.8.4
^ permalink raw reply related
* [PATCH v7 4/4] ARM: shmobile: genmai: Enable r7s72100-ether
From: Simon Horman @ 2014-01-17 0:22 UTC (permalink / raw)
To: David S. Miller, netdev, linux-sh
Cc: linux-arm-kernel, Magnus Damm, Sergei Shtylyov, Simon Horman,
Simon Horman
In-Reply-To: <1389918150-19058-1-git-send-email-horms+renesas@verge.net.au>
Signed-off-by: Simon Horman <horms@verge.net.au>
Acked-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
---
Dave, I am planning to take this change through my tree.
v3 - v7
* No change
v2
* As suggested by Magnus Damm and Sergei Shtylyov
- r7s72100 ethernet is not gigabit so do not refer to it as such
* As suggested by Sergei Shtylyov
- set no_ether_link as there is no LINK signal documented
in the manual
---
arch/arm/mach-shmobile/board-genmai.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/arch/arm/mach-shmobile/board-genmai.c b/arch/arm/mach-shmobile/board-genmai.c
index 3e92e3c..a1f6fe1 100644
--- a/arch/arm/mach-shmobile/board-genmai.c
+++ b/arch/arm/mach-shmobile/board-genmai.c
@@ -20,15 +20,36 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/sh_eth.h>
#include <mach/common.h>
+#include <mach/irqs.h>
#include <mach/r7s72100.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+/* Ether */
+static const struct sh_eth_plat_data ether_pdata __initconst = {
+ .phy = 0x00, /* PD60610 */
+ .edmac_endian = EDMAC_LITTLE_ENDIAN,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .no_ether_link = 1
+};
+
+static const struct resource ether_resources[] __initconst = {
+ DEFINE_RES_MEM(0xe8203000, 0x800),
+ DEFINE_RES_MEM(0xe8204800, 0x200),
+ DEFINE_RES_IRQ(gic_iid(359)),
+};
+
static void __init genmai_add_standard_devices(void)
{
r7s72100_clock_init();
r7s72100_add_dt_devices();
+
+ platform_device_register_resndata(&platform_bus, "r7s72100-ether", -1,
+ ether_resources,
+ ARRAY_SIZE(ether_resources),
+ ðer_pdata, sizeof(ether_pdata));
}
static const char * const genmai_boards_compat_dt[] __initconst = {
--
1.8.4
^ permalink raw reply related
* [PATCH v7 net-next 1/4] sh_eth: Use bool as return type of sh_eth_is_gether()
From: Simon Horman @ 2014-01-17 0:22 UTC (permalink / raw)
To: David S. Miller, netdev, linux-sh
Cc: linux-arm-kernel, Magnus Damm, Sergei Shtylyov, Simon Horman
In-Reply-To: <1389918150-19058-1-git-send-email-horms+renesas@verge.net.au>
Return a boolean from sh_eth_is_gether() and refactor it as a one-liner.
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
Dave, please consider this for net-next.
v7
* Updated changelog
v6
* Simplify logic as suggested by Joe Perches
v5
* No change
v4
* First post
---
drivers/net/ethernet/renesas/sh_eth.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index ba1f6c9..f12a929 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -310,12 +310,9 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
[TSU_ADRL31] = 0x01fc,
};
-static int sh_eth_is_gether(struct sh_eth_private *mdp)
+static bool sh_eth_is_gether(struct sh_eth_private *mdp)
{
- if (mdp->reg_offset == sh_eth_offset_gigabit)
- return 1;
- else
- return 0;
+ return mdp->reg_offset == sh_eth_offset_gigabit;
}
static void sh_eth_select_mii(struct net_device *ndev)
--
1.8.4
^ permalink raw reply related
* [PATCH v7 3/4] ARM: shmobile: r7s72100: Add clock for r7s72100-ether
From: Simon Horman @ 2014-01-17 0:22 UTC (permalink / raw)
To: David S. Miller, netdev, linux-sh
Cc: linux-arm-kernel, Magnus Damm, Sergei Shtylyov, Simon Horman
In-Reply-To: <1389918150-19058-1-git-send-email-horms+renesas@verge.net.au>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Acked-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
---
Dave, I am planning to take this change through my tree.
v6 - v7
* No change
v5
* Rebase
v3 - v4
* No change
v2
* As suggested by Sergei Shtylyov
- Add MSTP74 to beginning of enum on a line by itself
* As suggested by Magnus Damm
- r7s72100 ethernet is not gigabit so do not refer to it as such
---
arch/arm/mach-shmobile/clock-r7s72100.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/mach-shmobile/clock-r7s72100.c b/arch/arm/mach-shmobile/clock-r7s72100.c
index dd8ce87..0242ca5 100644
--- a/arch/arm/mach-shmobile/clock-r7s72100.c
+++ b/arch/arm/mach-shmobile/clock-r7s72100.c
@@ -27,6 +27,7 @@
#define FRQCR2 0xfcfe0014
#define STBCR3 0xfcfe0420
#define STBCR4 0xfcfe0424
+#define STBCR7 0xfcfe0430
#define STBCR9 0xfcfe0438
#define PLL_RATE 30
@@ -146,6 +147,7 @@ struct clk div4_clks[DIV4_NR] = {
};
enum { MSTP97, MSTP96, MSTP95, MSTP94,
+ MSTP74,
MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40,
MSTP33, MSTP_NR };
@@ -154,6 +156,7 @@ static struct clk mstp_clks[MSTP_NR] = {
[MSTP96] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 6, 0), /* RIIC1 */
[MSTP95] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 5, 0), /* RIIC2 */
[MSTP94] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 4, 0), /* RIIC3 */
+ [MSTP74] = SH_CLK_MSTP8(&peripheral1_clk, STBCR7, 4, 0), /* Ether */
[MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */
[MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */
[MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */
@@ -180,6 +183,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("fcfee400.i2c", &mstp_clks[MSTP96]),
CLKDEV_DEV_ID("fcfee800.i2c", &mstp_clks[MSTP95]),
CLKDEV_DEV_ID("fcfeec00.i2c", &mstp_clks[MSTP94]),
+ CLKDEV_DEV_ID("r7s72100-ether", &mstp_clks[MSTP74]),
CLKDEV_CON_ID("mtu2_fck", &mstp_clks[MSTP33]),
/* ICK */
--
1.8.4
^ permalink raw reply related
* Re: [PATCH] dm9000: fix a lot of checkpatch issues
From: David Miller @ 2014-01-17 0:23 UTC (permalink / raw)
To: 21cnbao
Cc: nikita, grinberg, jg1.han, mugunthanvnm, netdev, workgroup.linux,
Baohua.Song
In-Reply-To: <1389799906-2260-1-git-send-email-21cnbao@gmail.com>
From: Barry Song <21cnbao@gmail.com>
Date: Wed, 15 Jan 2014 23:31:46 +0800
> From: Barry Song <Baohua.Song@csr.com>
>
> recently, dm9000 codes have many checkpatch errors and warnings:
..
> This patch fixes important errors in it.
>
> Signed-off-by: Barry Song <Baohua.Song@csr.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] bnad: code cleanup
From: David Miller @ 2014-01-17 0:23 UTC (permalink / raw)
To: stephen; +Cc: rmody, netdev
In-Reply-To: <20140115082421.5d2fdfc3@nehalam.linuxnetplumber.net>
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Wed, 15 Jan 2014 08:24:21 -0800
> Use 'make namespacecheck' to code that could be declared static.
> After that remove code that is not being used.
>
> Compile tested only.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] vxge: make local functions static
From: David Miller @ 2014-01-17 0:23 UTC (permalink / raw)
To: stephen; +Cc: jdmason, netdev
In-Reply-To: <20140115082854.34b56f21@nehalam.linuxnetplumber.net>
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Wed, 15 Jan 2014 08:28:54 -0800
> Remove unused function vxge_hw_vpath_vid_get
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Applied.
^ permalink raw reply
* Re: [PATCH net-next v3 1/2] net: Add skb_get_hash_raw
From: David Miller @ 2014-01-17 0:23 UTC (permalink / raw)
To: therbert; +Cc: netdev
In-Reply-To: <alpine.DEB.2.02.1401150853090.14881@tomh.mtv.corp.google.com>
From: Tom Herbert <therbert@google.com>
Date: Wed, 15 Jan 2014 08:57:54 -0800 (PST)
> Function to just return skb->rxhash without checking to see if it needs
> to be recomputed.
>
> Signed-off-by: Tom Herbert <therbert@google.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next v3 2/2] net: Check skb->rxhash in gro_receive
From: David Miller @ 2014-01-17 0:23 UTC (permalink / raw)
To: therbert; +Cc: netdev
In-Reply-To: <alpine.DEB.2.02.1401150853400.14933@tomh.mtv.corp.google.com>
From: Tom Herbert <therbert@google.com>
Date: Wed, 15 Jan 2014 08:58:06 -0800 (PST)
> When initializing a gro_list for a packet, first check the rxhash of
> the incoming skb against that of the skb's in the list. This should be
> a very strong inidicator of whether the flow is going to be matched,
> and potentially allows a lot of other checks to be short circuited.
> Use skb_hash_raw so that we don't force the hash to be calculated.
>
> Tested by running netperf 200 TCP_STREAMs between two machines with
> GRO, HW rxhash, and 1G. Saw no performance degration, slight reduction
> of time in dev_gro_receive.
>
> Signed-off-by: Tom Herbert <therbert@google.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next v2] xen-netfront: add support for IPv6 offloads
From: David Miller @ 2014-01-17 0:23 UTC (permalink / raw)
To: paul.durrant
Cc: netdev, xen-devel, konrad.wilk, boris.ostrovsky, david.vrabel
In-Reply-To: <1389807033-11105-1-git-send-email-paul.durrant@citrix.com>
From: Paul Durrant <paul.durrant@citrix.com>
Date: Wed, 15 Jan 2014 17:30:33 +0000
> This patch adds support for IPv6 checksum offload and GSO when those
> features are available in the backend.
>
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next 0/2] r6040: misc fixes
From: David Miller @ 2014-01-17 0:24 UTC (permalink / raw)
To: florian; +Cc: netdev
In-Reply-To: <1389819866-32142-1-git-send-email-florian@openwrt.org>
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 15 Jan 2014 13:04:24 -0800
> Here are two small fixes, patch 1 could potentially be backported to stable
> trees since it affects MDIO operations.
Both applied, thanks.
^ permalink raw reply
* Re: suspicious RCU usage in net/ipv4/ip_tunnel.c:80
From: Cong Wang @ 2014-01-17 0:26 UTC (permalink / raw)
To: paulmck; +Cc: Eric Dumazet, Tom Herbert, netdev
In-Reply-To: <20140114045316.GV10038@linux.vnet.ibm.com>
On Mon, Jan 13, 2014 at 8:53 PM, Paul E. McKenney
<paulmck@linux.vnet.ibm.com> wrote:
> OK, I'll bite... This code invokes dst_release() which looks to me
> like it dereferences this pointer:
>
Yeah, sure, my point is it doesn't dereference the pointer when it holds
the spin_lock. I read rcu_dereference_protected() as "deference the rcu
pointer when we protected by ...", but we dereference it after the lock is
released. :)
@Eric, will you submit your patch as a formal one? I already tested it.
Thanks.
^ permalink raw reply
* [PATCH net-next v2 1/3] random32: add prandom_u32_max and convert open coded users
From: Hannes Frederic Sowa @ 2014-01-17 0:28 UTC (permalink / raw)
To: netdev; +Cc: Daniel Borkmann, Jakub Zawadzki, Eric Dumazet, linux-kernel
In-Reply-To: <1389918519-23779-1-git-send-email-hannes@stressinduktion.org>
From: Daniel Borkmann <dborkman@redhat.com>
Many functions have open coded a function that returns a random
number in range [0,N-1]. Under the assumption that we have a PRNG
such as taus113 with being well distributed in [0, ~0U] space,
we can implement such a function as uword t = (n*m')>>32, where
m' is a random number obtained from PRNG, n the right open interval
border and t our resulting random number, with n,m',t in u32 universe.
Lets go with Joe and simply call it prandom_u32_max(), although
technically we have an right open interval endpoint, but that we
have documented. Other users can further be migrated to the new
prandom_u32_max() function later on; for now, we need to make sure
to migrate reciprocal_divide() users for the reciprocal_divide()
follow-up fixup since their function signatures are going to change.
Joint work with Hannes Frederic Sowa.
Cc: Jakub Zawadzki <darkjames-ws@darkjames.pl>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
drivers/net/team/team_mode_random.c | 8 +-------
include/linux/random.h | 19 ++++++++++++++++++-
net/packet/af_packet.c | 2 +-
net/sched/sch_choke.c | 9 +--------
4 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/drivers/net/team/team_mode_random.c b/drivers/net/team/team_mode_random.c
index 7f032e2..cd2f692 100644
--- a/drivers/net/team/team_mode_random.c
+++ b/drivers/net/team/team_mode_random.c
@@ -13,20 +13,14 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/skbuff.h>
-#include <linux/reciprocal_div.h>
#include <linux/if_team.h>
-static u32 random_N(unsigned int N)
-{
- return reciprocal_divide(prandom_u32(), N);
-}
-
static bool rnd_transmit(struct team *team, struct sk_buff *skb)
{
struct team_port *port;
int port_index;
- port_index = random_N(team->en_port_count);
+ port_index = prandom_u32_max(team->en_port_count);
port = team_get_port_by_index_rcu(team, port_index);
if (unlikely(!port))
goto drop;
diff --git a/include/linux/random.h b/include/linux/random.h
index 4002b3d..f763a63 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -8,7 +8,6 @@
#include <uapi/linux/random.h>
-
extern void add_device_randomness(const void *, unsigned int);
extern void add_input_randomness(unsigned int type, unsigned int code,
unsigned int value);
@@ -38,6 +37,24 @@ struct rnd_state {
u32 prandom_u32_state(struct rnd_state *state);
void prandom_bytes_state(struct rnd_state *state, void *buf, int nbytes);
+/**
+ * prandom_u32_max - returns a random number in interval [0, ep_ro), the
+ * upper interval endpoint is right-open. This is useful
+ * when requesting a random index of an array containing
+ * ep_ro elements, for example.
+ *
+ * @ep_ro: right open interval endpoint
+ *
+ * Returns a pseduo-random number that is in interval [0, ep_ro). Note
+ * that the result depends on PRNG being well distributed in [0, ~0U]
+ * u32 space. Here we use maximally equidistributed combined Tausworthe
+ * generator, that is, prandom_u32().
+ */
+static inline u32 prandom_u32_max(u32 ep_ro)
+{
+ return (u32)(((u64) prandom_u32() * ep_ro) >> 32);
+}
+
/*
* Handle minimum values for seeds
*/
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 279467b..91daa01 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1247,7 +1247,7 @@ static unsigned int fanout_demux_rnd(struct packet_fanout *f,
struct sk_buff *skb,
unsigned int num)
{
- return reciprocal_divide(prandom_u32(), num);
+ return prandom_u32_max(num);
}
static unsigned int fanout_demux_rollover(struct packet_fanout *f,
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c
index ddd73cb..2aee028 100644
--- a/net/sched/sch_choke.c
+++ b/net/sched/sch_choke.c
@@ -14,7 +14,6 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
-#include <linux/reciprocal_div.h>
#include <linux/vmalloc.h>
#include <net/pkt_sched.h>
#include <net/inet_ecn.h>
@@ -77,12 +76,6 @@ struct choke_sched_data {
struct sk_buff **tab;
};
-/* deliver a random number between 0 and N - 1 */
-static u32 random_N(unsigned int N)
-{
- return reciprocal_divide(prandom_u32(), N);
-}
-
/* number of elements in queue including holes */
static unsigned int choke_len(const struct choke_sched_data *q)
{
@@ -233,7 +226,7 @@ static struct sk_buff *choke_peek_random(const struct choke_sched_data *q,
int retrys = 3;
do {
- *pidx = (q->head + random_N(choke_len(q))) & q->tab_mask;
+ *pidx = (q->head + prandom_u32_max(choke_len(q))) & q->tab_mask;
skb = q->tab[*pidx];
if (skb)
return skb;
--
1.8.4.2
^ permalink raw reply related
* [PATCH net-next v2 3/3] reciprocal_divide: correction/update of the algorithm
From: Hannes Frederic Sowa @ 2014-01-17 0:28 UTC (permalink / raw)
To: netdev
Cc: Eric Dumazet, Austin S Hemmelgarn, linux-kernel, Jesse Gross,
Jamal Hadi Salim, Stephen Hemminger, Matt Mackall, Pekka Enberg,
Christoph Lameter, Andy Gospodarek, Veaceslav Falico,
Jay Vosburgh, Jakub Zawadzki, Daniel Borkmann
In-Reply-To: <1389918519-23779-1-git-send-email-hannes@stressinduktion.org>
Jakub Zawadzki noticed that some divisions by reciprocal_divide()
were not correct [1][2], which he could also show with BPF code after
divisions are transformed into reciprocal_value() for runtime invariant
which can be passed to reciprocal_divide() later on; reverse in BPF dump
ended up with a different, off-by-one K.
This has been fixed by Eric Dumazet in commit aee636c4809fa5 ("bpf: do not
use reciprocal divide"). This follow-up patch improves reciprocal_value()
and reciprocal_divide() to work in all cases, so future use is safe.
Known problems with the old implementation were that division by 1 always
returned 0 and some off-by-ones when the dividend and divisor where
very large. This seemed to not be problematic with its current users
in networking, mm/slab.c and lib/flex_array.c, but future users would
need to check for this specifically and it might not be obvious at first.
In order to fix that, we propose an extension from the original
implementation from commit 6a2d7a955d8d resp. [3][4], by using
the algorithm proposed in "Division by Invariant Integers Using
Multiplication" [5], Torbjörn Granlund and Peter L. Montgomery, that is,
pseudocode for q = n/d where q,n,d is in u32 universe:
1) Initialization:
int l = ceil(log_2 d)
uword m' = floor((1<<32)*((1<<l)-d)/d)+1
int sh_1 = min(l,1)
int sh_2 = max(l-1,0)
2) For q = n/d, all uword:
uword t = (n*m')>>32
q = (t+((n-t)>>sh_1))>>sh_2
The assembler implementation from Agner Fog [6] also helped a lot
while implementing. We have tested the implementation on x86_64,
ppc64, i686, s390x; on x86_64/haswell we're still half the latency
compared to normal divide.
Joint work with Daniel Borkmann.
[1] http://www.wireshark.org/~darkjames/reciprocal-buggy.c
[2] http://www.wireshark.org/~darkjames/set-and-dump-filter-k-bug.c
[3] https://gmplib.org/~tege/division-paper.pdf
[4] http://homepage.cs.uiowa.edu/~jones/bcd/divide.html
[5] http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.1.2556
[6] http://www.agner.org/optimize/asmlib.zip
Fixes: 6a2d7a955d8d ("SLAB: use a multiply instead of a divide in obj_to_index()")
Fixes: 704f15ddb5fc ("flex_array: avoid divisions when accessing elements")
Reported-by: Jakub Zawadzki <darkjames-ws@darkjames.pl>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Austin S Hemmelgarn <ahferroin7@gmail.com>
Cc: linux-kernel@vger.kernel.org
Cc: Jesse Gross <jesse@nicira.com>
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: Matt Mackall <mpm@selenic.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Christoph Lameter <cl@linux-foundation.org>
Cc: Andy Gospodarek <andy@greyhouse.net>
Cc: Veaceslav Falico <vfalico@redhat.com>
Cc: Jay Vosburgh <fubar@us.ibm.com>
Cc: Jakub Zawadzki <darkjames-ws@darkjames.pl>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
drivers/net/bonding/bond_main.c | 24 ++++++++++++++++-------
drivers/net/bonding/bond_netlink.c | 4 ----
drivers/net/bonding/bond_options.c | 15 ++++++++++-----
drivers/net/bonding/bond_sysfs.c | 5 -----
drivers/net/bonding/bonding.h | 3 +++
include/linux/flex_array.h | 3 ++-
include/linux/reciprocal_div.h | 39 ++++++++++++++++++++------------------
include/linux/slab_def.h | 4 +++-
include/net/red.h | 3 ++-
lib/flex_array.c | 7 ++++++-
lib/reciprocal_div.c | 24 +++++++++++++++++++----
net/sched/sch_netem.c | 6 ++++--
12 files changed, 88 insertions(+), 49 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f2fe6cb..77e57da 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -79,7 +79,6 @@
#include <net/pkt_sched.h>
#include <linux/rculist.h>
#include <net/flow_keys.h>
-#include <linux/reciprocal_div.h>
#include "bonding.h"
#include "bond_3ad.h"
#include "bond_alb.h"
@@ -3551,8 +3550,9 @@ static void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int sl
*/
static u32 bond_rr_gen_slave_id(struct bonding *bond)
{
- int packets_per_slave = bond->params.packets_per_slave;
u32 slave_id;
+ struct reciprocal_value reciprocal_packets_per_slave;
+ int packets_per_slave = bond->params.packets_per_slave;
switch (packets_per_slave) {
case 0:
@@ -3562,8 +3562,10 @@ static u32 bond_rr_gen_slave_id(struct bonding *bond)
slave_id = bond->rr_tx_counter;
break;
default:
+ reciprocal_packets_per_slave =
+ bond->params.reciprocal_packets_per_slave;
slave_id = reciprocal_divide(bond->rr_tx_counter,
- packets_per_slave);
+ reciprocal_packets_per_slave);
break;
}
bond->rr_tx_counter++;
@@ -4297,10 +4299,18 @@ static int bond_check_params(struct bond_params *params)
params->resend_igmp = resend_igmp;
params->min_links = min_links;
params->lp_interval = lp_interval;
- if (packets_per_slave > 1)
- params->packets_per_slave = reciprocal_value(packets_per_slave);
- else
- params->packets_per_slave = packets_per_slave;
+ params->packets_per_slave = packets_per_slave;
+ if (packets_per_slave > 0) {
+ params->reciprocal_packets_per_slave =
+ reciprocal_value(packets_per_slave);
+ } else {
+ /* reciprocal_packets_per_slave is unused if
+ * packets_per_slave is 0 or 1, just initialize it
+ */
+ params->reciprocal_packets_per_slave =
+ (struct reciprocal_value) { 0 };
+ }
+
if (primary) {
strncpy(params->primary, primary, IFNAMSIZ);
params->primary[IFNAMSIZ - 1] = 0;
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
index 555c783..9b13791 100644
--- a/drivers/net/bonding/bond_netlink.c
+++ b/drivers/net/bonding/bond_netlink.c
@@ -19,7 +19,6 @@
#include <linux/if_ether.h>
#include <net/netlink.h>
#include <net/rtnetlink.h>
-#include <linux/reciprocal_div.h>
#include "bonding.h"
static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
@@ -416,9 +415,6 @@ static int bond_fill_info(struct sk_buff *skb,
goto nla_put_failure;
packets_per_slave = bond->params.packets_per_slave;
- if (packets_per_slave > 1)
- packets_per_slave = reciprocal_value(packets_per_slave);
-
if (nla_put_u32(skb, IFLA_BOND_PACKETS_PER_SLAVE,
packets_per_slave))
goto nla_put_failure;
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 945a666..85e4348 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -16,7 +16,6 @@
#include <linux/netdevice.h>
#include <linux/rwlock.h>
#include <linux/rcupdate.h>
-#include <linux/reciprocal_div.h>
#include "bonding.h"
int bond_option_mode_set(struct bonding *bond, int mode)
@@ -671,11 +670,17 @@ int bond_option_packets_per_slave_set(struct bonding *bond,
pr_warn("%s: Warning: packets_per_slave has effect only in balance-rr mode\n",
bond->dev->name);
- if (packets_per_slave > 1)
- bond->params.packets_per_slave =
+ bond->params.packets_per_slave = packets_per_slave;
+ if (packets_per_slave > 0) {
+ bond->params.reciprocal_packets_per_slave =
reciprocal_value(packets_per_slave);
- else
- bond->params.packets_per_slave = packets_per_slave;
+ } else {
+ /* reciprocal_packets_per_slave is unused if
+ * packets_per_slave is 0 or 1, just initialize it
+ */
+ bond->params.reciprocal_packets_per_slave =
+ (struct reciprocal_value) { 0 };
+ }
return 0;
}
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 011f163..c083e9a 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -39,7 +39,6 @@
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include <linux/nsproxy.h>
-#include <linux/reciprocal_div.h>
#include "bonding.h"
@@ -1374,10 +1373,6 @@ static ssize_t bonding_show_packets_per_slave(struct device *d,
{
struct bonding *bond = to_bond(d);
unsigned int packets_per_slave = bond->params.packets_per_slave;
-
- if (packets_per_slave > 1)
- packets_per_slave = reciprocal_value(packets_per_slave);
-
return sprintf(buf, "%u\n", packets_per_slave);
}
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 955dc48..502dda8 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -23,6 +23,8 @@
#include <linux/netpoll.h>
#include <linux/inetdevice.h>
#include <linux/etherdevice.h>
+#include <linux/reciprocal_div.h>
+
#include "bond_3ad.h"
#include "bond_alb.h"
@@ -171,6 +173,7 @@ struct bond_params {
int resend_igmp;
int lp_interval;
int packets_per_slave;
+ struct reciprocal_value reciprocal_packets_per_slave;
};
struct bond_parm_tbl {
diff --git a/include/linux/flex_array.h b/include/linux/flex_array.h
index 6843cf1..b6efb0c 100644
--- a/include/linux/flex_array.h
+++ b/include/linux/flex_array.h
@@ -2,6 +2,7 @@
#define _FLEX_ARRAY_H
#include <linux/types.h>
+#include <linux/reciprocal_div.h>
#include <asm/page.h>
#define FLEX_ARRAY_PART_SIZE PAGE_SIZE
@@ -22,7 +23,7 @@ struct flex_array {
int element_size;
int total_nr_elements;
int elems_per_part;
- u32 reciprocal_elems;
+ struct reciprocal_value reciprocal_elems;
struct flex_array_part *parts[];
};
/*
diff --git a/include/linux/reciprocal_div.h b/include/linux/reciprocal_div.h
index f9c90b3..8c5a3fb 100644
--- a/include/linux/reciprocal_div.h
+++ b/include/linux/reciprocal_div.h
@@ -4,29 +4,32 @@
#include <linux/types.h>
/*
- * This file describes reciprocical division.
+ * This algorithm is based on the paper "Division by Invariant
+ * Integers Using Multiplication" by Torbjörn Granlund and Peter
+ * L. Montgomery.
*
- * This optimizes the (A/B) problem, when A and B are two u32
- * and B is a known value (but not known at compile time)
+ * The assembler implementation from Agner Fog, which this code is
+ * based on, can be found here:
+ * http://www.agner.org/optimize/asmlib.zip
*
- * The math principle used is :
- * Let RECIPROCAL_VALUE(B) be (((1LL << 32) + (B - 1))/ B)
- * Then A / B = (u32)(((u64)(A) * (R)) >> 32)
- *
- * This replaces a divide by a multiply (and a shift), and
- * is generally less expensive in CPU cycles.
+ * This optimization for A/B is helpful if the divisor B is mostly
+ * runtime invariant. The reciprocal of B is calculated in the
+ * slow-path with reciprocal_value(). The fast-path can then just use
+ * a much faster multiplication operation with a variable dividend A
+ * to calculate the division A/B.
*/
-/*
- * Computes the reciprocal value (R) for the value B of the divisor.
- * Should not be called before each reciprocal_divide(),
- * or else the performance is slower than a normal divide.
- */
-extern u32 reciprocal_value(u32 B);
+struct reciprocal_value {
+ u32 m;
+ u8 sh1, sh2;
+};
+struct reciprocal_value reciprocal_value(u32 d);
-static inline u32 reciprocal_divide(u32 A, u32 R)
+static inline u32 reciprocal_divide(u32 a, struct reciprocal_value R)
{
- return (u32)(((u64)A * R) >> 32);
+ u32 t = (u32)(((u64)a * R.m) >> 32);
+ return (t + ((a - t) >> R.sh1)) >> R.sh2;
}
-#endif
+
+#endif /* _LINUX_RECIPROCAL_DIV_H */
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
index 09bfffb..96e8aba 100644
--- a/include/linux/slab_def.h
+++ b/include/linux/slab_def.h
@@ -1,6 +1,8 @@
#ifndef _LINUX_SLAB_DEF_H
#define _LINUX_SLAB_DEF_H
+#include <linux/reciprocal_div.h>
+
/*
* Definitions unique to the original Linux SLAB allocator.
*/
@@ -12,7 +14,7 @@ struct kmem_cache {
unsigned int shared;
unsigned int size;
- u32 reciprocal_buffer_size;
+ struct reciprocal_value reciprocal_buffer_size;
/* 2) touched by every alloc & free from the backend */
unsigned int flags; /* constant flags */
diff --git a/include/net/red.h b/include/net/red.h
index 168bb2f..76e0b5f 100644
--- a/include/net/red.h
+++ b/include/net/red.h
@@ -130,7 +130,8 @@ struct red_parms {
u32 qth_max; /* Max avg length threshold: Wlog scaled */
u32 Scell_max;
u32 max_P; /* probability, [0 .. 1.0] 32 scaled */
- u32 max_P_reciprocal; /* reciprocal_value(max_P / qth_delta) */
+ /* reciprocal_value(max_P / qth_delta) */
+ struct reciprocal_value max_P_reciprocal;
u32 qth_delta; /* max_th - min_th */
u32 target_min; /* min_th + 0.4*(max_th - min_th) */
u32 target_max; /* min_th + 0.6*(max_th - min_th) */
diff --git a/lib/flex_array.c b/lib/flex_array.c
index 6948a66..2eed22f 100644
--- a/lib/flex_array.c
+++ b/lib/flex_array.c
@@ -90,8 +90,8 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total,
{
struct flex_array *ret;
int elems_per_part = 0;
- int reciprocal_elems = 0;
int max_size = 0;
+ struct reciprocal_value reciprocal_elems = { 0 };
if (element_size) {
elems_per_part = FLEX_ARRAY_ELEMENTS_PER_PART(element_size);
@@ -119,6 +119,11 @@ EXPORT_SYMBOL(flex_array_alloc);
static int fa_element_to_part_nr(struct flex_array *fa,
unsigned int element_nr)
{
+ /*
+ * if element_size == 0 we don't get here, so we never touch
+ * the zeroed fa->reciprocal_elems, which would yield invalid
+ * results
+ */
return reciprocal_divide(element_nr, fa->reciprocal_elems);
}
diff --git a/lib/reciprocal_div.c b/lib/reciprocal_div.c
index 75510e9..4641524 100644
--- a/lib/reciprocal_div.c
+++ b/lib/reciprocal_div.c
@@ -1,11 +1,27 @@
+#include <linux/kernel.h>
#include <asm/div64.h>
#include <linux/reciprocal_div.h>
#include <linux/export.h>
-u32 reciprocal_value(u32 k)
+/*
+ * For a description of the algorithm please have a look at
+ * include/linux/reciprocal_div.h
+ */
+
+struct reciprocal_value reciprocal_value(u32 d)
{
- u64 val = (1LL << 32) + (k - 1);
- do_div(val, k);
- return (u32)val;
+ struct reciprocal_value R;
+ u64 m;
+ int l;
+
+ l = fls(d - 1);
+ m = ((1ULL << 32) * ((1ULL << l) - d));
+ do_div(m, d);
+ ++m;
+ R.m = (u32)m;
+ R.sh1 = min(l, 1);
+ R.sh2 = max(l - 1, 0);
+
+ return R;
}
EXPORT_SYMBOL(reciprocal_value);
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 3019c10..81fc5b0 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -91,7 +91,7 @@ struct netem_sched_data {
u64 rate;
s32 packet_overhead;
u32 cell_size;
- u32 cell_size_reciprocal;
+ struct reciprocal_value cell_size_reciprocal;
s32 cell_overhead;
struct crndstate {
@@ -716,9 +716,11 @@ static void get_rate(struct Qdisc *sch, const struct nlattr *attr)
q->rate = r->rate;
q->packet_overhead = r->packet_overhead;
q->cell_size = r->cell_size;
+ q->cell_overhead = r->cell_overhead;
if (q->cell_size)
q->cell_size_reciprocal = reciprocal_value(q->cell_size);
- q->cell_overhead = r->cell_overhead;
+ else
+ q->cell_size_reciprocal = (struct reciprocal_value) { 0 };
}
static int get_loss_clg(struct Qdisc *sch, const struct nlattr *attr)
--
1.8.4.2
^ permalink raw reply related
* [PATCH net-next v2 0/3] reciprocal_divide updates
From: Hannes Frederic Sowa @ 2014-01-17 0:28 UTC (permalink / raw)
To: netdev
This set is on top of Eric's BPF fix, that is:
<http://patchwork.ozlabs.org/patch/311163/>
This fix is currently in the net repository; a merge of net to net-next
would be needed for this series.
Included Patches:
Daniel Borkmann (2):
random32: add prandom_u32_max and convert open coded users
net: add trim helper and convert users
Hannes Frederic Sowa (1):
reciprocal_divide: correction/update of the algorithm
Diffstat:
drivers/net/bonding/bond_main.c | 24 +++++++++++++++++-------
drivers/net/bonding/bond_netlink.c | 4 ----
drivers/net/bonding/bond_options.c | 15 ++++++++++-----
drivers/net/bonding/bond_sysfs.c | 5 -----
drivers/net/bonding/bonding.h | 3 +++
drivers/net/team/team_mode_random.c | 8 +-------
include/linux/flex_array.h | 3 ++-
include/linux/kernel.h | 19 +++++++++++++++++++
include/linux/random.h | 19 ++++++++++++++++++-
include/linux/reciprocal_div.h | 39 +++++++++++++++++++++------------------
include/linux/slab_def.h | 4 +++-
include/net/codel.h | 4 +---
include/net/red.h | 3 ++-
lib/flex_array.c | 7 ++++++-
lib/reciprocal_div.c | 24 ++++++++++++++++++++----
net/packet/af_packet.c | 5 ++---
net/sched/sch_choke.c | 9 +--------
net/sched/sch_netem.c | 6 ++++--
18 files changed, 130 insertions(+), 71 deletions(-)
Changelog:
v2)
* change function name to prandom_u32_max as suggested by Joe Perches
* first patch split into two patches, second one introduces helper
function trim (suggested by Eric Dumazet to not go back to open-coded
version and David Laight to rename reciprocal_divide())
* removed RECIPROCAL_VALUE_RESULT_TO_ZERO as it causes undefined behaviour
and is broken (thanks Ben Hutchings!)
* reworded
^ permalink raw reply
* [PATCH net-next v2 2/3] net: add trim helper and convert users
From: Hannes Frederic Sowa @ 2014-01-17 0:28 UTC (permalink / raw)
To: netdev; +Cc: Daniel Borkmann, Jakub Zawadzki, Eric Dumazet, linux-kernel
In-Reply-To: <1389918519-23779-1-git-send-email-hannes@stressinduktion.org>
From: Daniel Borkmann <dborkman@redhat.com>
As David Laight suggests, we shouldn't necessarily call this
reciprocal_divide() when users didn't requested a reciprocal_value().
Lets make the name short and nifty, put this where we have other
generic helpers of similar kind and convert users.
Joint work with Hannes Frederic Sowa.
Cc: Jakub Zawadzki <darkjames-ws@darkjames.pl>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
include/linux/kernel.h | 19 +++++++++++++++++++
include/net/codel.h | 4 +---
net/packet/af_packet.c | 3 +--
3 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index ecb8754..62ecbfa 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -193,6 +193,25 @@ extern int _cond_resched(void);
(__x < 0) ? -__x : __x; \
})
+/**
+ * trim - perform a reciprocal multiplication in order to "clamp" a
+ * value into range [0, ep_ro), where the upper interval
+ * endpoint is right-open. This is useful, e.g. for accessing
+ * a index of an array containing ep_ro elements, for example.
+ * Think of it as sort of modulus, only that the result isn't
+ * that of modulo. ;)
+ * More: http://homepage.cs.uiowa.edu/~jones/bcd/divide.html
+ *
+ * @val: value to 'trim'
+ * @ep_ro: right open interval endpoint
+ *
+ * Returns a result based on val in interval [0, ep_ro).
+ */
+static inline u32 trim(u32 val, u32 ep_ro)
+{
+ return (u32)(((u64) val * ep_ro) >> 32);
+}
+
#if defined(CONFIG_MMU) && \
(defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_DEBUG_ATOMIC_SLEEP))
void might_fault(void);
diff --git a/include/net/codel.h b/include/net/codel.h
index 3b04ff5..d302b4c 100644
--- a/include/net/codel.h
+++ b/include/net/codel.h
@@ -46,7 +46,6 @@
#include <linux/skbuff.h>
#include <net/pkt_sched.h>
#include <net/inet_ecn.h>
-#include <linux/reciprocal_div.h>
/* Controlling Queue Delay (CoDel) algorithm
* =========================================
@@ -211,10 +210,9 @@ static codel_time_t codel_control_law(codel_time_t t,
codel_time_t interval,
u32 rec_inv_sqrt)
{
- return t + reciprocal_divide(interval, rec_inv_sqrt << REC_INV_SQRT_SHIFT);
+ return t + trim(interval, rec_inv_sqrt << REC_INV_SQRT_SHIFT);
}
-
static bool codel_should_drop(const struct sk_buff *skb,
struct Qdisc *sch,
struct codel_vars *vars,
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 91daa01..d327774 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -88,7 +88,6 @@
#include <linux/virtio_net.h>
#include <linux/errqueue.h>
#include <linux/net_tstamp.h>
-#include <linux/reciprocal_div.h>
#ifdef CONFIG_INET
#include <net/inet_common.h>
#endif
@@ -1220,7 +1219,7 @@ static unsigned int fanout_demux_hash(struct packet_fanout *f,
struct sk_buff *skb,
unsigned int num)
{
- return reciprocal_divide(skb->rxhash, num);
+ return trim(skb->rxhash, num);
}
static unsigned int fanout_demux_lb(struct packet_fanout *f,
--
1.8.4.2
^ permalink raw reply related
* Re: [PATCH net-next v4 1/6] net: allow > 0 order atomic page alloc in skb_page_frag_refill
From: Michael Dalton @ 2014-01-17 0:30 UTC (permalink / raw)
To: David Miller
Cc: netdev, Eric Dumazet, Rusty Russell, Michael S. Tsirkin,
Jason Wang, Ben Hutchings, lf-virt
In-Reply-To: <20140116.153020.587523865163482894.davem@davemloft.net>
On Thu, Jan 16, 2014 at 3:30 PM, David Miller <davem@davemloft.net> wrote:
> Actually, I reverted, please resubmit this series with the following
> build warning corrected:
Thanks David, I will send out another patchset shortly with the warning
resolved and a header e-mail (and one other sysfs group fix that I just
found in the same file). Sorry I didn't include a header e-mail
initially.
Best,
Mike
^ permalink raw reply
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