Skip to contentSkip to conversation

dsmark: get rid of trivial function

PATCH Applied Stephen Hemminger 5 participants 6 messages Jan 20, 2008 – Jan 22, 2008 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore
#1 lore raw

PATCH 2/4 dsmark: get rid of trivial function

In reply to a message not in the archive

Replace loop in dsmark_valid_indices with equivalent bit math.

net/sched/sch_dsmark.c +2 -7
@@ -45,13 +45,8 @@ struct dsmark_qdisc_data {
 
 static inline int dsmark_valid_indices(u16 indices)
 {
-	while (indices != 1) {
-		if (indices & 1)
-			return 0;
-		indices >>= 1;
-	}
-
-	return 1;
+	/* Must have only one bit set */
+	return (indices & (indices - 1)) == 0;
 }
 
 static inline int dsmark_valid_index(struct dsmark_qdisc_data *p, u16 index)
#2 lore raw
Quoted 9 lines · Stephen Hemminger

Replace loop in dsmark_valid_indices with equivalent bit math.

net/sched/sch_dsmark.c +0 -0
@@ -45,13 +45,8 @@ struct dsmark_qdisc_data {
 
 static inline int dsmark_valid_indices(u16 indices)

net/sched/sch_dsmark.c struct dsmark_qdisc_data { · line 49

Quoted 10 lines
net/sched/sch_dsmark.c +2 -7
 {
-	while (indices != 1) {
-		if (indices & 1)
-			return 0;
-		indices >>= 1;
-	}
-
-	return 1;
+	/* Must have only one bit set */
+	return (indices & (indices - 1)) == 0;

hweight seems easier to understand, it took me a bit to realize that the comment matches the code :)

#3 lore raw
Quoted 9 lines · Patrick McHardy
Quoted 8 lines · Stephen Hemminger

Replace loop in dsmark_valid_indices with equivalent bit math.

net/sched/sch_dsmark.c +0 -0
@@ -45,13 +45,8 @@ struct dsmark_qdisc_data {
 
Quoted 11 lines

net/sched/sch_dsmark.c struct dsmark_qdisc_data { · line 49

Quoted 11 lines
net/sched/sch_dsmark.c +2 -7
 static inline int dsmark_valid_indices(u16 indices)
 {
-	while (indices != 1) {
-		if (indices & 1)
-			return 0;
-		indices >>= 1;
-	}
-
-	return 1;
+	/* Must have only one bit set */
+	return (indices & (indices - 1)) == 0;

Isn't there some magic under include/linux to do that btw, I suppose that if the caller side zero check is pushed down there too, the is_power_of_2() is 100% match? :-)

Quoted 2 lines

hweight seems easier to understand, it took me a bit to realize that the comment matches the code :)

In addition, the original seems infinite loop with zero indices given but luckily that was checked at the caller site already...

Signature · 1 line
 i.
maintainer
#4 lore raw
In reply to Patrick McHardy

From: Patrick McHardy <[email protected]>
Date: Mon, 21 Jan 2008 01:16:32 +0100

Quoted 9 lines
Quoted 8 lines · Stephen Hemminger

Replace loop in dsmark_valid_indices with equivalent bit math.

net/sched/sch_dsmark.c +0 -0
@@ -45,13 +45,8 @@ struct dsmark_qdisc_data {
 
Quoted 14 lines

net/sched/sch_dsmark.c struct dsmark_qdisc_data { · line 49

Quoted 11 lines
net/sched/sch_dsmark.c +2 -7
 static inline int dsmark_valid_indices(u16 indices)
 {
-	while (indices != 1) {
-		if (indices & 1)
-			return 0;
-		indices >>= 1;
-	}
-
-	return 1;
+	/* Must have only one bit set */
+	return (indices & (indices - 1)) == 0;

hweight seems easier to understand, it took me a bit to realize that the comment matches the code :)

Sounds good. Here is what I ended up checking in.

[PKT_SCHED] dsmark: Use hweight32() instead of convoluted loop.

Based upon a patch by Stephen Hemminger and suggestions from Patrick McHardy.

net/sched/sch_dsmark.c +3 -12
index a9732ae..d96eaf0 100644
@@ -10,6 +10,7 @@
 #include <linux/errno.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
+#include <linux/bitops.h>
 #include <net/pkt_sched.h>
 #include <net/dsfield.h>
 #include <net/inet_ecn.h>
@@ -43,17 +44,6 @@ struct dsmark_qdisc_data {
 	int			set_tc_index;
 };
 
-static inline int dsmark_valid_indices(u16 indices)
-{
-	while (indices != 1) {
-		if (indices & 1)
-			return 0;
-		indices >>= 1;
-	}
-
-	return 1;
-}
-
 static inline int dsmark_valid_index(struct dsmark_qdisc_data *p, u16 index)
 {
 	return (index <= p->indices && index > 0);
@@ -348,7 +338,8 @@ static int dsmark_init(struct Qdisc *sch, struct rtattr *opt)
 		goto errout;
 
 	indices = RTA_GET_U16(tb[TCA_DSMARK_INDICES-1]);
-	if (!indices || !dsmark_valid_indices(indices))
+
+	if (hweight32(indices) != 1)
 		goto errout;
 
 	if (tb[TCA_DSMARK_DEFAULT_INDEX-1])
#5 lore raw
Quoted 67 lines · On Mon, 21 Jan 2008 02:22:23 -0800 (PST) David Miller <[email protected]>…

From: Patrick McHardy <[email protected]>
Date: Mon, 21 Jan 2008 01:16:32 +0100

Quoted 9 lines
Quoted 8 lines · Stephen Hemminger

Replace loop in dsmark_valid_indices with equivalent bit math.

net/sched/sch_dsmark.c +0 -0
@@ -45,13 +45,8 @@ struct dsmark_qdisc_data {
 
Quoted 14 lines

net/sched/sch_dsmark.c struct dsmark_qdisc_data {

Quoted 11 lines
net/sched/sch_dsmark.c +2 -7
 static inline int dsmark_valid_indices(u16 indices)
 {
-	while (indices != 1) {
-		if (indices & 1)
-			return 0;
-		indices >>= 1;
-	}
-
-	return 1;
+	/* Must have only one bit set */
+	return (indices & (indices - 1)) == 0;

hweight seems easier to understand, it took me a bit to realize that the comment matches the code :)

Sounds good. Here is what I ended up checking in.

[PKT_SCHED] dsmark: Use hweight32() instead of convoluted loop.

Based upon a patch by Stephen Hemminger and suggestions from Patrick McHardy.

net/sched/sch_dsmark.c +1 -11
index a9732ae..d96eaf0 100644
@@ -10,6 +10,7 @@
 #include <linux/errno.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
+#include <linux/bitops.h>
 #include <net/pkt_sched.h>
 #include <net/dsfield.h>
 #include <net/inet_ecn.h>
@@ -43,17 +44,6 @@ struct dsmark_qdisc_data {
 	int			set_tc_index;
 };
 
-static inline int dsmark_valid_indices(u16 indices)
-{
-	while (indices != 1) {
-		if (indices & 1)
-			return 0;
-		indices >>= 1;
-	}
-
-	return 1;
-}
-
 static inline int dsmark_valid_index(struct dsmark_qdisc_data *p, u16 index)
 {
 	return (index <= p->indices && index > 0);

net/sched/sch_dsmark.c static int dsmark_init(struct Qdisc *sch, struct rtattr *opt) · line 343

Quoted 7 lines
net/sched/sch_dsmark.c +2 -1
@@ -348,7 +338,8 @@ static int dsmark_init(struct Qdisc *sch, struct rtattr *opt)
 		goto errout;
 
 	indices = RTA_GET_U16(tb[TCA_DSMARK_INDICES-1]);
-	if (!indices || !dsmark_valid_indices(indices))
+
+	if (hweight32(indices) != 1)
 		goto errout;

Come on Dave, that is a step backwards.
So you took a two instruction thing that any programmer who ever had one of those technical trick interviews would surely understand, and made it call a function... Seems like the thing you would consul others against.

Please use !is_power_of_2(indices) instead.

maintainer
#6 lore raw

From: Stephen Hemminger <[email protected]>
Date: Mon, 21 Jan 2008 19:47:51 -0800

Quoted 8 lines

net/sched/sch_dsmark.c static int dsmark_init(struct Qdisc *sch, struct rtattr *opt) · line 343

Quoted 6 lines
net/sched/sch_dsmark.c +2 -1
 	indices = RTA_GET_U16(tb[TCA_DSMARK_INDICES-1]);
-	if (!indices || !dsmark_valid_indices(indices))
+
+	if (hweight32(indices) != 1)
 		goto errout;

Come on Dave, that is a step backwards.

Absolutely not.

Quoted 4 lines

So you took a two instruction thing that any programmer who ever had one of those technical trick interviews would surely understand, and made it call a function... Seems like the thing you would consul others against.

It's counting bits, "hamming weight" is a count of bits.

That is more understandable to me than:

Oh BTW, power of two values also just so happen to have only 1 bit set.

Testing for a power of two obfuscates the meaning of the test. It doesn't want a power-of-two, it wants a bitmask with only one bit set.