[PATCH] netfilter: xt_hashlimit: avoid 64-bit division

Subsystems: netfilter, networking [general], the rest

STALE3285d

6 messages, 4 authors, 2017-09-07 · open the first message on its own page

[PATCH] netfilter: xt_hashlimit: avoid 64-bit division

From: Arnd Bergmann <arnd@arndb.de>
Date: 2017-09-06 19:58:58

64-bit division is expensive on 32-bit architectures, and
requires a special function call to avoid a link error like:

net/netfilter/xt_hashlimit.o: In function `hashlimit_mt_common':
xt_hashlimit.c:(.text+0x1328): undefined reference to `__aeabi_uldivmod'

In the case of hashlimit_mt_common, we don't actually need a
64-bit operation, we can simply rewrite the function slightly
to make that clear to the compiler.

Fixes: bea74641e378 ("netfilter: xt_hashlimit: add rate match mode")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 net/netfilter/xt_hashlimit.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 10d48234f5f4..50b53d86eef5 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -531,7 +531,10 @@ static u64 user2rate_bytes(u64 user)
 {
 	u64 r;
 
-	r = user ? 0xFFFFFFFFULL / user : 0xFFFFFFFFULL;
+	if (user > 0xFFFFFFFFULL)
+		return 0;
+
+	r = user ? 0xFFFFFFFFULL / (u32)user : 0xFFFFFFFFULL;
 	r = (r - 1) << 4;
 	return r;
 }
-- 
2.9.0

Re: [PATCH] netfilter: xt_hashlimit: avoid 64-bit division

From: Vishwanath Pai <hidden>
Date: 2017-09-06 20:24:16

On 09/06/2017 03:57 PM, Arnd Bergmann wrote:
quoted hunk
64-bit division is expensive on 32-bit architectures, and
requires a special function call to avoid a link error like:

net/netfilter/xt_hashlimit.o: In function `hashlimit_mt_common':
xt_hashlimit.c:(.text+0x1328): undefined reference to `__aeabi_uldivmod'

In the case of hashlimit_mt_common, we don't actually need a
64-bit operation, we can simply rewrite the function slightly
to make that clear to the compiler.

Fixes: bea74641e378 ("netfilter: xt_hashlimit: add rate match mode")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 net/netfilter/xt_hashlimit.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 10d48234f5f4..50b53d86eef5 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -531,7 +531,10 @@ static u64 user2rate_bytes(u64 user)
 {
 	u64 r;
 
-	r = user ? 0xFFFFFFFFULL / user : 0xFFFFFFFFULL;
+	if (user > 0xFFFFFFFFULL)
+		return 0;
+
+	r = user ? 0xFFFFFFFFULL / (u32)user : 0xFFFFFFFFULL;
 	r = (r - 1) << 4;
 	return r;
 }
I have submitted another patch to fix this:
https://patchwork.ozlabs.org/patch/809881/

We have seen this problem before, I was careful not to introduce this
again in the new patch but clearly I overlooked this particular line :(

In the other cases we fixed it by replacing division with div64_u64().

-Vishwanath

Re: [PATCH] netfilter: xt_hashlimit: avoid 64-bit division

From: Arnd Bergmann <arnd@arndb.de>
Date: 2017-09-06 20:48:26

On Wed, Sep 6, 2017 at 10:22 PM, Vishwanath Pai [off-list ref] wrote:
On 09/06/2017 03:57 PM, Arnd Bergmann wrote:
quoted
64-bit division is expensive on 32-bit architectures, and
requires a special function call to avoid a link error like:

net/netfilter/xt_hashlimit.o: In function `hashlimit_mt_common':
xt_hashlimit.c:(.text+0x1328): undefined reference to `__aeabi_uldivmod'

In the case of hashlimit_mt_common, we don't actually need a
64-bit operation, we can simply rewrite the function slightly
to make that clear to the compiler.

Fixes: bea74641e378 ("netfilter: xt_hashlimit: add rate match mode")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 net/netfilter/xt_hashlimit.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 10d48234f5f4..50b53d86eef5 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -531,7 +531,10 @@ static u64 user2rate_bytes(u64 user)
 {
      u64 r;

-     r = user ? 0xFFFFFFFFULL / user : 0xFFFFFFFFULL;
+     if (user > 0xFFFFFFFFULL)
+             return 0;
+
+     r = user ? 0xFFFFFFFFULL / (u32)user : 0xFFFFFFFFULL;
      r = (r - 1) << 4;
      return r;
 }
I have submitted another patch to fix this:
https://patchwork.ozlabs.org/patch/809881/

We have seen this problem before, I was careful not to introduce this
again in the new patch but clearly I overlooked this particular line :(

In the other cases we fixed it by replacing division with div64_u64().
div64_u64() seems needlessly expensive here since the dividend
is known to be a 32-bit number. I guess the function is not called
frequently though, so it doesn't matter much.

      Arnd

Re: [PATCH] netfilter: xt_hashlimit: avoid 64-bit division

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: 2017-09-07 10:20:02

On Wed, Sep 06, 2017 at 10:48:22PM +0200, Arnd Bergmann wrote:
On Wed, Sep 6, 2017 at 10:22 PM, Vishwanath Pai [off-list ref] wrote:
quoted
On 09/06/2017 03:57 PM, Arnd Bergmann wrote:
quoted
64-bit division is expensive on 32-bit architectures, and
requires a special function call to avoid a link error like:

net/netfilter/xt_hashlimit.o: In function `hashlimit_mt_common':
xt_hashlimit.c:(.text+0x1328): undefined reference to `__aeabi_uldivmod'

In the case of hashlimit_mt_common, we don't actually need a
64-bit operation, we can simply rewrite the function slightly
to make that clear to the compiler.

Fixes: bea74641e378 ("netfilter: xt_hashlimit: add rate match mode")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 net/netfilter/xt_hashlimit.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 10d48234f5f4..50b53d86eef5 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -531,7 +531,10 @@ static u64 user2rate_bytes(u64 user)
 {
      u64 r;

-     r = user ? 0xFFFFFFFFULL / user : 0xFFFFFFFFULL;
+     if (user > 0xFFFFFFFFULL)
+             return 0;
+
+     r = user ? 0xFFFFFFFFULL / (u32)user : 0xFFFFFFFFULL;
      r = (r - 1) << 4;
      return r;
 }
I have submitted another patch to fix this:
https://patchwork.ozlabs.org/patch/809881/

We have seen this problem before, I was careful not to introduce this
again in the new patch but clearly I overlooked this particular line :(

In the other cases we fixed it by replacing division with div64_u64().
div64_u64() seems needlessly expensive here since the dividend
is known to be a 32-bit number. I guess the function is not called
frequently though, so it doesn't matter much.
This is called from the packet path, only for the first packet for
each new destination IP entry in the hashtable, still from the
datapath. So if we can take something faster (for 32 bit arches) that
is correct, I think it's sensible to take.

Let me know in any case.

Re: [PATCH] netfilter: xt_hashlimit: avoid 64-bit division

From: Arnd Bergmann <arnd@arndb.de>
Date: 2017-09-07 11:16:19

On Thu, Sep 7, 2017 at 12:19 PM, Pablo Neira Ayuso [off-list ref] wrote:
On Wed, Sep 06, 2017 at 10:48:22PM +0200, Arnd Bergmann wrote:
quoted
On Wed, Sep 6, 2017 at 10:22 PM, Vishwanath Pai [off-list ref] wrote:
quoted
On 09/06/2017 03:57 PM, Arnd Bergmann wrote:
quoted
64-bit division is expensive on 32-bit architectures, and
requires a special function call to avoid a link error like:

net/netfilter/xt_hashlimit.o: In function `hashlimit_mt_common':
xt_hashlimit.c:(.text+0x1328): undefined reference to `__aeabi_uldivmod'

In the case of hashlimit_mt_common, we don't actually need a
64-bit operation, we can simply rewrite the function slightly
to make that clear to the compiler.

Fixes: bea74641e378 ("netfilter: xt_hashlimit: add rate match mode")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 net/netfilter/xt_hashlimit.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 10d48234f5f4..50b53d86eef5 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -531,7 +531,10 @@ static u64 user2rate_bytes(u64 user)
 {
      u64 r;

-     r = user ? 0xFFFFFFFFULL / user : 0xFFFFFFFFULL;
+     if (user > 0xFFFFFFFFULL)
+             return 0;
+
+     r = user ? 0xFFFFFFFFULL / (u32)user : 0xFFFFFFFFULL;
      r = (r - 1) << 4;
      return r;
 }
I have submitted another patch to fix this:
https://patchwork.ozlabs.org/patch/809881/

We have seen this problem before, I was careful not to introduce this
again in the new patch but clearly I overlooked this particular line :(

In the other cases we fixed it by replacing division with div64_u64().
div64_u64() seems needlessly expensive here since the dividend
is known to be a 32-bit number. I guess the function is not called
frequently though, so it doesn't matter much.
This is called from the packet path, only for the first packet for
each new destination IP entry in the hashtable, still from the
datapath. So if we can take something faster (for 32 bit arches) that
is correct, I think it's sensible to take.

Let me know in any case.
I think my version should be slightly better then, unless someone
finds something wrong with it.

       Arnd

Re: [PATCH] netfilter: xt_hashlimit: avoid 64-bit division

From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: 2017-09-07 14:16:49

Hi Arnd,

On Wed, Sep 6, 2017 at 9:57 PM, Arnd Bergmann [off-list ref] wrote:
64-bit division is expensive on 32-bit architectures, and
requires a special function call to avoid a link error like:

net/netfilter/xt_hashlimit.o: In function `hashlimit_mt_common':
xt_hashlimit.c:(.text+0x1328): undefined reference to `__aeabi_uldivmod'

In the case of hashlimit_mt_common, we don't actually need a
64-bit operation, we can simply rewrite the function slightly
to make that clear to the compiler.

Fixes: bea74641e378 ("netfilter: xt_hashlimit: add rate match mode")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Thanks, this fixes a similar issue (__udivdi3 undefined) on m68k.

Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>

Gr{oetje,eeting}s,

                        Geert
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help