* Re: [PATCH] qla3xxx: add missing __iomem annotation
From: Ron Mercer @ 2011-02-23 21:47 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, netdev@vger.kernel.org
In-Reply-To: <20110223095427.38a67186@nehalam>
On Wed, Feb 23, 2011 at 09:54:27AM -0800, Stephen Hemminger wrote:
> Add necessary annotations about pointer to io memory space
> that is checked by sparse.
>
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>
Thanks Stephen. Looks good.
Acked-by: Ron Mercer <ron.mercer@qlogic.com>
^ permalink raw reply
* Re: [PATCHv2 2/2] DM9000B: Fix PHY power for network down/up
From: David Miller @ 2011-02-23 22:30 UTC (permalink / raw)
To: henry.nestler; +Cc: netdev, akpm, linux-arm-kernel
In-Reply-To: <4D642AC6.6050101@henry.nestler.mail.gmail.com>
From: Henry Nestler <henry.nestler@gmail.com>
Date: Tue, 22 Feb 2011 22:29:42 +0100
> DM9000 revision B needs 1 ms delay after PHY power-on.
> PHY must be powered on by writing 0 into register DM9000_GPR before
> all other settings will change (see Davicom spec and example code).
>
> Remember, that register DM9000_GPR was not changed by reset sequence.
>
> Without this fix the FIFO is out of sync and sends wrong data after
> sequence of "ifconfig ethX down ; ifconfig ethX up".
I've applied both of your patches, thanks.
^ permalink raw reply
* Re: [PATCH] bonding: fix sparse warning
From: Jay Vosburgh @ 2011-02-23 22:29 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, netdev
In-Reply-To: <20110223094033.0c2268b4@nehalam>
Stephen Hemminger <shemminger@vyatta.com> wrote:
>Fix use of zero where NULL expected. And wrap long line.
>
>Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
>--- a/drivers/net/bonding/bonding.h 2011-02-23 09:33:39.493248155 -0800
>+++ b/drivers/net/bonding/bonding.h 2011-02-23 09:33:48.825356637 -0800
>@@ -265,7 +265,8 @@ struct bonding {
> *
> * Caller must hold bond lock for read
> */
>-static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev)
>+static inline struct slave *bond_get_slave_by_dev(struct bonding *bond,
>+ struct net_device *slave_dev)
> {
> struct slave *slave = NULL;
> int i;
>@@ -276,7 +277,7 @@ static inline struct slave *bond_get_sla
> }
> }
>
>- return 0;
>+ return NULL;
> }
>
> static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
^ permalink raw reply
* Re: [PATCH 0/4] Fixes for unified offload configuration
From: David Miller @ 2011-02-23 22:24 UTC (permalink / raw)
To: mirq-linux; +Cc: netdev, bhutchings
In-Reply-To: <cover.1298429033.git.mirq-linux@rere.qmqm.pl>
From: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Date: Wed, 23 Feb 2011 03:52:28 +0100 (CET)
> this series contains couple of fixes to ethtool unification work in net-next.
>
> patches 1 and 2 (resend):
> fix following message at device registration:
> (unregistered net_device): features changed: 0x00011065 -> 0x00015065
>
> patches 3 and 4:
> implement compatibility fallback in ethtool_{g,s}features for drivers
> not converted to new offload setting scheme.
>
> only compile tested for now as my test box has some hardware issues lately.
All applied, thanks.
^ permalink raw reply
* Re: [PATCHv2 NEXT 0/2]qlcnic: minor fixes
From: David Miller @ 2011-02-23 22:23 UTC (permalink / raw)
To: amit.salecha; +Cc: netdev, ameen.rahman, anirban.chakraborty
In-Reply-To: <1298467285-7201-1-git-send-email-amit.salecha@qlogic.com>
From: Amit Kumar Salecha <amit.salecha@qlogic.com>
Date: Wed, 23 Feb 2011 05:21:23 -0800
> Hi
> Series v2 of minor fixes. Apply them on net-next.
> Now, patch 1 doesn't change module parameters name and its properties.
Both applied, thanks.
^ permalink raw reply
* Re: [PATCH 2/2 net-next-2.6] r6040: bump to version 0.27 and date 23Feb2011
From: David Miller @ 2011-02-23 22:23 UTC (permalink / raw)
To: florian; +Cc: netdev
In-Reply-To: <201102231532.37179.florian@openwrt.org>
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 23 Feb 2011 15:32:37 +0100
> From: Florian Fainelli <florian@openwrt.org>
>
> Signed-off-by: Florian Fainelli <florian@openwrt.org>
Applied.
^ permalink raw reply
* Re: [PATCH 1/2 net-next-2.6] r6040: fix multicast operations
From: David Miller @ 2011-02-23 22:22 UTC (permalink / raw)
To: florian; +Cc: netdev
In-Reply-To: <201102231532.34849.florian@openwrt.org>
From: Florian Fainelli <florian@openwrt.org>
Date: Wed, 23 Feb 2011 15:32:34 +0100
> From: Shawn Lin <shawn@dmp.com.tw>
>
> The original code does not work well when the number of mulitcast
> address to handle is greater than MCAST_MAX. It only enable promiscous
> mode instead of multicast hash table mode, so the hash table function
> will not be activated and all multicast frames will be recieved in this
> condition.
>
> This patch fixes the following issues with the r6040 NIC operating in
> multicast:
>
> 1) When the IFF_ALLMULTI flag is set, we should write 0xffff to the NIC
> hash table registers to make it process multicast traffic.
>
> 2) When the number of multicast address to handle is smaller than
> MCAST_MAX, we should use the NIC multicast registers MID1_{L,M,H}.
>
> 3) The hashing of the address was not correct, due to an invalid
> substraction (15 - (crc & 0x0f)) instead of (crc & 0x0f) and an
> incorrect crc algorithm (ether_crc_le) instead of (ether_crc).
>
> 4) If necessary, we should set HASH_EN flag in MCR0 to enable multicast
> hash table function.
>
> CC: stable@kernel.org
If it's not appropriate for net-2.6, it's not appropriate for -stable
either.
I'm applying this to net-next-2.6, as you requested, and removing the
stable CC: tag from the commit message.
> Reported-by: Marc Leclerc <marc-leclerc@signaturealpha.com>
> Tested-by: Marc Leclerc <marc-leclerc@signaturealpha.com>
> Signed-off-by: Shawn Lin <shawn@dmp.com.tw>
> Signed-off-by: Albert Chen <albert.chen@rdc.com.tw>
> Signed-off-by: Florian Fainelli <florian@openwrt.org>
^ permalink raw reply
* Re: [PATCH 1/2] bonding: fix incorrect transmit queue offset
From: Jay Vosburgh @ 2011-02-23 22:19 UTC (permalink / raw)
To: Andy Gospodarek; +Cc: netdev, Phil Oester, Ben Hutchings
In-Reply-To: <1298490169-5224-1-git-send-email-andy@greyhouse.net>
Andy Gospodarek <andy@greyhouse.net> wrote:
>Users noticed the following messages:
>
>kernel: bond0 selects TX queue 16, but real number of TX queues is 16
>
>were filling their logs when frames received from a device that
>contained 16 input queues were being forwarded out of a bonded device.
>Ben pointed out that the contents of skb->queue_mapping cannot be
>directly mapped to a transmit queue, so I went with his suggestion for a
>solution to the offset problem.
>
>The function now also warns the user to increase the default value for
>tx_queues if needed and returns a valid tx queue to dev_pick_tx.
>
>Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
>Reported-by: Phil Oester <kernel@linuxace.com>
>CC: Ben Hutchings <bhutchings@solarflare.com>
>---
> drivers/net/bonding/bond_main.c | 24 +++++++++++++++++-------
> 1 files changed, 17 insertions(+), 7 deletions(-)
>
>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>index 77e3c6a..1512c83 100644
>--- a/drivers/net/bonding/bond_main.c
>+++ b/drivers/net/bonding/bond_main.c
>@@ -4533,15 +4533,25 @@ out:
> return res;
> }
>
>+/*
>+ * This helper function exists to help dev_pick_tx get the correct
>+ * destination queue. Using a helper function skips the a call to
>+ * skb_tx_hash and will put the skbs in the queue we expect on their
>+ * way down to the bonding driver.
>+ */
> static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb)
> {
>- /*
>- * This helper function exists to help dev_pick_tx get the correct
>- * destination queue. Using a helper function skips the a call to
>- * skb_tx_hash and will put the skbs in the queue we expect on their
>- * way down to the bonding driver.
>- */
>- return skb->queue_mapping;
>+ u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
>+
>+ while (txq >= dev->real_num_tx_queues) {
>+ /* let the user know if we do not have enough tx queues */
>+ if (net_ratelimit())
>+ pr_warning("%s selects invalid tx queue %d. Consider"
>+ " setting module option tx_queues > %d.",
>+ dev->name, txq, dev->real_num_tx_queues);
>+ txq -= dev->real_num_tx_queues;
Would this be better as:
if (txq >= dev->real_num_tx_queues) {
/* let the user know if we do not have enough tx queues */
if (net_ratelimit())
pr_warning("%s selects invalid tx queue %d. Consider"
" setting module option tx_queues > %d.",
dev->name, txq, dev->real_num_tx_queues);
txq %= dev->real_num_tx_queues;
}
I.e., use one modulus instead of a looping subtraction? If the
queue id in the packet is substantially out of range, the loop may
interate multiple times. Presumably you want to distribute the out of
range queue mappings (not just assign them all to the same queue id).
-J
>+ }
>+ return txq;
> }
>
> static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
>--
>1.7.4
>
---
-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
^ permalink raw reply
* Re: [PATCH] net_sched: long word align struct qdisc_skb_cb data
From: David Miller @ 2011-02-23 22:17 UTC (permalink / raw)
To: shemminger
Cc: eric.dumazet, kaber, Juliusz.Chroboczek, linville, netdev, andi
In-Reply-To: <20110223093001.28e1a8ef@nehalam>
From: Stephen Hemminger <shemminger@vyatta.com>
Date: Wed, 23 Feb 2011 09:30:01 -0800
> On Wed, 23 Feb 2011 18:05:07 +0100
> Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
>> Le mercredi 23 février 2011 à 17:24 +0100, Patrick McHardy a écrit :
>> > Am 23.02.2011 16:14, schrieb Eric Dumazet:
>> > > diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
>> > > index 16626a0..f40d32e 100644
>> > > --- a/include/net/sch_generic.h
>> > > +++ b/include/net/sch_generic.h
>> > > @@ -218,6 +218,7 @@ struct tcf_proto {
>> > >
>> > > struct qdisc_skb_cb {
>> > > unsigned int pkt_len;
>> > > + unsigned int sfb_classid;
>> > > char data[];
>> > > };
>> >
>> > This could be moved into a SFB specific cb, similar to what netem
>> > does.
>>
>> Hmm... well... I want to be sure no other sch will destroy my values.
>>
>> netem seems buggy then.
>>
>> Probably following patch is needed ?
>
> Yes, it was long word aligned when netem was written but
> we seem to have bit creep.
Applied to net-2.6, thanks!
^ permalink raw reply
* Re: [PATCH 0/5] sparse related patches
From: David Miller @ 2011-02-23 22:11 UTC (permalink / raw)
To: shemminger; +Cc: netdev
In-Reply-To: <20110223190647.482444598@vyatta.com>
All applied, thanks Stephen.
^ permalink raw reply
* Re: [PATCH net-next-2.6 v4] net_sched: SFB flow scheduler
From: David Miller @ 2011-02-23 22:06 UTC (permalink / raw)
To: eric.dumazet
Cc: Juliusz.Chroboczek, linville, shemminger, kaber, netdev, andi
In-Reply-To: <1298494577.2898.9.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 23 Feb 2011 21:56:17 +0100
> This is the Stochastic Fair Blue scheduler, based on work from :
Applied with the 'static' fix, thanks Eric!
^ permalink raw reply
* Re: [PATCH] connector: Convert char *name to const char *name
From: Greg KH @ 2011-02-23 21:22 UTC (permalink / raw)
To: Evgeniy Polyakov
Cc: Joe Perches, Javier Martinez Canillas, Greg Kroah-Hartman, devel,
K. Y. Srinivasan, netdev
In-Reply-To: <20110220143259.GA19984@ioremap.net>
On Sun, Feb 20, 2011 at 05:32:59PM +0300, Evgeniy Polyakov wrote:
> Hi Joe.
>
> On Sat, Feb 19, 2011 at 03:45:29PM -0800, Joe Perches (joe@perches.com) wrote:
> > Allow more const declarations.
> >
> > Signed-off-by: Joe Perches <joe@perches.com>
> >
> > ---
> >
> > Better to change the declarations and uses as this argument
> > is not modified.
>
> Looks good, thank you.
> Greg, please push it into your tree.
>
> Acked-by: Evgeniy Polyakov <zbr@ioremap.net>
Now applied, thanks.
greg k-h
^ permalink raw reply
* Re: [PATCH net-next-2.6 v4] net_sched: SFB flow scheduler
From: David Miller @ 2011-02-23 21:30 UTC (permalink / raw)
To: eric.dumazet
Cc: shemminger, Juliusz.Chroboczek, linville, kaber, netdev, andi
In-Reply-To: <1298496516.2898.10.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 23 Feb 2011 22:28:36 +0100
> Le mercredi 23 février 2011 à 13:11 -0800, Stephen Hemminger a écrit :
>> On Wed, 23 Feb 2011 21:56:17 +0100
>> Eric Dumazet <eric.dumazet@gmail.com> wrote:
>>
>> > +struct Qdisc_ops sfb_qdisc_ops __read_mostly = {
>>
>> Should be static?
>>
>>
>
> Sure ! ;)
I can make this simple fixup when I apply the patch to net-next-2.6,
Eric you don't have to respin it just for this.
^ permalink raw reply
* Re: [PATCH net-next-2.6 v4] net_sched: SFB flow scheduler
From: Eric Dumazet @ 2011-02-23 21:28 UTC (permalink / raw)
To: Stephen Hemminger
Cc: David Miller, Juliusz Chroboczek, John W. Linville,
Patrick McHardy, netdev, Andi Kleen
In-Reply-To: <20110223131158.632dc45c@nehalam>
Le mercredi 23 février 2011 à 13:11 -0800, Stephen Hemminger a écrit :
> On Wed, 23 Feb 2011 21:56:17 +0100
> Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> > +struct Qdisc_ops sfb_qdisc_ops __read_mostly = {
>
> Should be static?
>
>
Sure ! ;)
^ permalink raw reply
* Re: [PATCH net-next-2.6 v4] net_sched: SFB flow scheduler
From: Stephen Hemminger @ 2011-02-23 21:11 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, Juliusz Chroboczek, John W. Linville,
Patrick McHardy, netdev, Andi Kleen
In-Reply-To: <1298494577.2898.9.camel@edumazet-laptop>
On Wed, 23 Feb 2011 21:56:17 +0100
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> +struct Qdisc_ops sfb_qdisc_ops __read_mostly = {
Should be static?
--
^ permalink raw reply
* [PATCH net-next-2.6 v4] net_sched: SFB flow scheduler
From: Eric Dumazet @ 2011-02-23 20:56 UTC (permalink / raw)
To: David Miller
Cc: Juliusz Chroboczek, John W. Linville, Stephen Hemminger,
Patrick McHardy, netdev, Andi Kleen
In-Reply-To: <1298474091.3301.364.camel@edumazet-laptop>
This is the Stochastic Fair Blue scheduler, based on work from :
W. Feng, D. Kandlur, D. Saha, K. Shin. Blue: A New Class of Active Queue
Management Algorithms. U. Michigan CSE-TR-387-99, April 1999.
http://www.thefengs.com/wuchang/blue/CSE-TR-387-99.pdf
This implementation is based on work done by Juliusz Chroboczek
General SFB algorithm can be found in figure 14, page 15:
B[l][n] : L x N array of bins (L levels, N bins per level)
enqueue()
Calculate hash function values h{0}, h{1}, .. h{L-1}
Update bins at each level
for i = 0 to L - 1
if (B[i][h{i}].qlen > bin_size)
B[i][h{i}].p_mark += p_increment;
else if (B[i][h{i}].qlen == 0)
B[i][h{i}].p_mark -= p_decrement;
p_min = min(B[0][h{0}].p_mark ... B[L-1][h{L-1}].p_mark);
if (p_min == 1.0)
ratelimit();
else
mark/drop with probabilty p_min;
I did the adaptation of Juliusz code to meet current kernel standards,
and various changes to address previous comments :
http://thread.gmane.org/gmane.linux.network/90225
http://thread.gmane.org/gmane.linux.network/90375
Default flow classifier is the rxhash introduced by RPS in 2.6.35, but
we can use an external flow classifier if wanted.
tc qdisc add dev $DEV parent 1:11 handle 11: \
est 0.5sec 2sec sfb limit 128
tc filter add dev $DEV protocol ip parent 11: handle 3 \
flow hash keys dst divisor 1024
Notes:
1) SFB default child qdisc is pfifo_fast. It can be changed by another
qdisc but a child qdisc MUST not drop a packet previously queued. This
is because SFB needs to handle a dequeued packet in order to maintain
its virtual queue states. pfifo_head_drop or CHOKe should not be used.
2) ECN is enabled by default, unlike RED/CHOKe/GRED
With help from Patrick McHardy & Andi Kleen
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Juliusz Chroboczek <Juliusz.Chroboczek@pps.jussieu.fr>
CC: Stephen Hemminger <shemminger@vyatta.com>
CC: Patrick McHardy <kaber@trash.net>
CC: Andi Kleen <andi@firstfloor.org>
CC: John W. Linville <linville@tuxdriver.com>
---
V4: added sfb_skb_cb to hold two hashes values per skb
double buffering takes place only for inelastic flows
some fields renames.
timeouts are now given in ms instead of seconds
include/linux/pkt_sched.h | 39 +
net/sched/Kconfig | 11
net/sched/Makefile | 1
net/sched/sch_sfb.c | 709 ++++++++++++++++++++++++++++++++++++
4 files changed, 760 insertions(+)
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index d4bb6f5..5afee2b 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -522,4 +522,43 @@ struct tc_mqprio_qopt {
__u16 offset[TC_QOPT_MAX_QUEUE];
};
+/* SFB */
+
+enum {
+ TCA_SFB_UNSPEC,
+ TCA_SFB_PARMS,
+ __TCA_SFB_MAX,
+};
+
+#define TCA_SFB_MAX (__TCA_SFB_MAX - 1)
+
+/*
+ * Note: increment, decrement are Q0.16 fixed-point values.
+ */
+struct tc_sfb_qopt {
+ __u32 rehash_interval; /* delay between hash move, in ms */
+ __u32 warmup_time; /* double buffering warmup time in ms (warmup_time < rehash_interval) */
+ __u32 max; /* max len of qlen_min */
+ __u32 bin_size; /* maximum queue length per bin */
+ __u32 increment; /* probability increment, (d1 in Blue) */
+ __u32 decrement; /* probability decrement, (d2 in Blue) */
+ __u32 limit; /* max SFB queue length */
+ __u32 penalty_rate; /* inelastic flows are rate limited to 'rate' pps */
+ __u32 penalty_burst;
+};
+
+struct tc_sfb_xstats {
+ __u32 earlydrop;
+ __u32 penaltydrop;
+ __u32 bucketdrop;
+ __u32 queuedrop;
+ __u32 childdrop; /* drops in child qdisc */
+ __u32 marked;
+ __u32 maxqlen;
+ __u32 maxprob;
+ __u32 avgprob;
+};
+
+#define SFB_MAX_PROB 0xFFFF
+
#endif
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 8c19b6e..a7a5583 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -126,6 +126,17 @@ config NET_SCH_RED
To compile this code as a module, choose M here: the
module will be called sch_red.
+config NET_SCH_SFB
+ tristate "Stochastic Fair Blue (SFB)"
+ ---help---
+ Say Y here if you want to use the Stochastic Fair Blue (SFB)
+ packet scheduling algorithm.
+
+ See the top of <file:net/sched/sch_sfb.c> for more details.
+
+ To compile this code as a module, choose M here: the
+ module will be called sch_sfb.
+
config NET_SCH_SFQ
tristate "Stochastic Fairness Queueing (SFQ)"
---help---
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 06c6cdf..2e77b8d 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_NET_SCH_RED) += sch_red.o
obj-$(CONFIG_NET_SCH_GRED) += sch_gred.o
obj-$(CONFIG_NET_SCH_INGRESS) += sch_ingress.o
obj-$(CONFIG_NET_SCH_DSMARK) += sch_dsmark.o
+obj-$(CONFIG_NET_SCH_SFB) += sch_sfb.o
obj-$(CONFIG_NET_SCH_SFQ) += sch_sfq.o
obj-$(CONFIG_NET_SCH_TBF) += sch_tbf.o
obj-$(CONFIG_NET_SCH_TEQL) += sch_teql.o
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
new file mode 100644
index 0000000..7b2e0cc
--- /dev/null
+++ b/net/sched/sch_sfb.c
@@ -0,0 +1,709 @@
+/*
+ * net/sched/sch_sfb.c Stochastic Fair Blue
+ *
+ * Copyright (c) 2008-2011 Juliusz Chroboczek <jch@pps.jussieu.fr>
+ * Copyright (c) 2011 Eric Dumazet <eric.dumazet@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * W. Feng, D. Kandlur, D. Saha, K. Shin. Blue:
+ * A New Class of Active Queue Management Algorithms.
+ * U. Michigan CSE-TR-387-99, April 1999.
+ *
+ * http://www.thefengs.com/wuchang/blue/CSE-TR-387-99.pdf
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+#include <linux/random.h>
+#include <linux/jhash.h>
+#include <net/ip.h>
+#include <net/pkt_sched.h>
+#include <net/inet_ecn.h>
+
+/*
+ * SFB uses two B[l][n] : L x N arrays of bins (L levels, N bins per level)
+ * This implementation uses L = 8 and N = 16
+ * This permits us to split one 32bit hash (provided per packet by rxhash or
+ * external classifier) into 8 subhashes of 4 bits.
+ */
+#define SFB_BUCKET_SHIFT 4
+#define SFB_NUMBUCKETS (1 << SFB_BUCKET_SHIFT) /* N bins per Level */
+#define SFB_BUCKET_MASK (SFB_NUMBUCKETS - 1)
+#define SFB_LEVELS (32 / SFB_BUCKET_SHIFT) /* L */
+
+/* SFB algo uses a virtual queue, named "bin" */
+struct sfb_bucket {
+ u16 qlen; /* length of virtual queue */
+ u16 p_mark; /* marking probability */
+};
+
+/* We use a double buffering right before hash change
+ * (Section 4.4 of SFB reference : moving hash functions)
+ */
+struct sfb_bins {
+ u32 perturbation; /* jhash perturbation */
+ struct sfb_bucket bins[SFB_LEVELS][SFB_NUMBUCKETS];
+};
+
+struct sfb_sched_data {
+ struct Qdisc *qdisc;
+ struct tcf_proto *filter_list;
+ unsigned long rehash_interval;
+ unsigned long warmup_time; /* double buffering warmup time in jiffies */
+ u32 max;
+ u32 bin_size; /* maximum queue length per bin */
+ u32 increment; /* d1 */
+ u32 decrement; /* d2 */
+ u32 limit; /* HARD maximal queue length */
+ u32 penalty_rate;
+ u32 penalty_burst;
+ u32 tokens_avail;
+ unsigned long rehash_time;
+ unsigned long token_time;
+
+ u8 slot; /* current active bins (0 or 1) */
+ bool double_buffering;
+ struct sfb_bins bins[2];
+
+ struct {
+ u32 earlydrop;
+ u32 penaltydrop;
+ u32 bucketdrop;
+ u32 queuedrop;
+ u32 childdrop; /* drops in child qdisc */
+ u32 marked; /* ECN mark */
+ } stats;
+};
+
+/*
+ * Each queued skb might be hashed on one or two bins
+ * We store in skb_cb the two hash values.
+ * (A zero value means double buffering was not used)
+ */
+struct sfb_skb_cb {
+ u32 hashes[2];
+};
+
+static inline struct sfb_skb_cb *sfb_skb_cb(const struct sk_buff *skb)
+{
+ BUILD_BUG_ON(sizeof(skb->cb) <
+ sizeof(struct qdisc_skb_cb) + sizeof(struct sfb_skb_cb));
+ return (struct sfb_skb_cb *)qdisc_skb_cb(skb)->data;
+}
+
+/*
+ * If using 'internal' SFB flow classifier, hash comes from skb rxhash
+ * If using external classifier, hash comes from the classid.
+ */
+static u32 sfb_hash(const struct sk_buff *skb, u32 slot)
+{
+ return sfb_skb_cb(skb)->hashes[slot];
+}
+
+/* Probabilities are coded as Q0.16 fixed-point values,
+ * with 0xFFFF representing 65535/65536 (almost 1.0)
+ * Addition and subtraction are saturating in [0, 65535]
+ */
+static u32 prob_plus(u32 p1, u32 p2)
+{
+ u32 res = p1 + p2;
+
+ return min_t(u32, res, SFB_MAX_PROB);
+}
+
+static u32 prob_minus(u32 p1, u32 p2)
+{
+ return p1 > p2 ? p1 - p2 : 0;
+}
+
+static void increment_one_qlen(u32 sfbhash, u32 slot, struct sfb_sched_data *q)
+{
+ int i;
+ struct sfb_bucket *b = &q->bins[slot].bins[0][0];
+
+ for (i = 0; i < SFB_LEVELS; i++) {
+ u32 hash = sfbhash & SFB_BUCKET_MASK;
+
+ sfbhash >>= SFB_BUCKET_SHIFT;
+ if (b[hash].qlen < 0xFFFF)
+ b[hash].qlen++;
+ b += SFB_NUMBUCKETS; /* next level */
+ }
+}
+
+static void increment_qlen(const struct sk_buff *skb, struct sfb_sched_data *q)
+{
+ u32 sfbhash;
+
+ sfbhash = sfb_hash(skb, 0);
+ if (sfbhash)
+ increment_one_qlen(sfbhash, 0, q);
+
+ sfbhash = sfb_hash(skb, 1);
+ if (sfbhash)
+ increment_one_qlen(sfbhash, 1, q);
+}
+
+static void decrement_one_qlen(u32 sfbhash, u32 slot,
+ struct sfb_sched_data *q)
+{
+ int i;
+ struct sfb_bucket *b = &q->bins[slot].bins[0][0];
+
+ for (i = 0; i < SFB_LEVELS; i++) {
+ u32 hash = sfbhash & SFB_BUCKET_MASK;
+
+ sfbhash >>= SFB_BUCKET_SHIFT;
+ if (b[hash].qlen > 0)
+ b[hash].qlen--;
+ b += SFB_NUMBUCKETS; /* next level */
+ }
+}
+
+static void decrement_qlen(const struct sk_buff *skb, struct sfb_sched_data *q)
+{
+ u32 sfbhash;
+
+ sfbhash = sfb_hash(skb, 0);
+ if (sfbhash)
+ decrement_one_qlen(sfbhash, 0, q);
+
+ sfbhash = sfb_hash(skb, 1);
+ if (sfbhash)
+ decrement_one_qlen(sfbhash, 1, q);
+}
+
+static void decrement_prob(struct sfb_bucket *b, struct sfb_sched_data *q)
+{
+ b->p_mark = prob_minus(b->p_mark, q->decrement);
+}
+
+static void increment_prob(struct sfb_bucket *b, struct sfb_sched_data *q)
+{
+ b->p_mark = prob_plus(b->p_mark, q->increment);
+}
+
+static void sfb_zero_all_buckets(struct sfb_sched_data *q)
+{
+ memset(&q->bins, 0, sizeof(q->bins));
+}
+
+/*
+ * compute max qlen, max p_mark, and avg p_mark
+ */
+static u32 sfb_compute_qlen(u32 *prob_r, u32 *avgpm_r, const struct sfb_sched_data *q)
+{
+ int i;
+ u32 qlen = 0, prob = 0, totalpm = 0;
+ const struct sfb_bucket *b = &q->bins[q->slot].bins[0][0];
+
+ for (i = 0; i < SFB_LEVELS * SFB_NUMBUCKETS; i++) {
+ if (qlen < b->qlen)
+ qlen = b->qlen;
+ totalpm += b->p_mark;
+ if (prob < b->p_mark)
+ prob = b->p_mark;
+ b++;
+ }
+ *prob_r = prob;
+ *avgpm_r = totalpm / (SFB_LEVELS * SFB_NUMBUCKETS);
+ return qlen;
+}
+
+
+static void sfb_init_perturbation(u32 slot, struct sfb_sched_data *q)
+{
+ q->bins[slot].perturbation = net_random();
+}
+
+static void sfb_swap_slot(struct sfb_sched_data *q)
+{
+ sfb_init_perturbation(q->slot, q);
+ q->slot ^= 1;
+ q->double_buffering = false;
+}
+
+/* Non elastic flows are allowed to use part of the bandwidth, expressed
+ * in "penalty_rate" packets per second, with "penalty_burst" burst
+ */
+static bool sfb_rate_limit(struct sk_buff *skb, struct sfb_sched_data *q)
+{
+ if (q->penalty_rate == 0 || q->penalty_burst == 0)
+ return true;
+
+ if (q->tokens_avail < 1) {
+ unsigned long age = min(10UL * HZ, jiffies - q->token_time);
+
+ q->tokens_avail = (age * q->penalty_rate) / HZ;
+ if (q->tokens_avail > q->penalty_burst)
+ q->tokens_avail = q->penalty_burst;
+ q->token_time = jiffies;
+ if (q->tokens_avail < 1)
+ return true;
+ }
+
+ q->tokens_avail--;
+ return false;
+}
+
+static bool sfb_classify(struct sk_buff *skb, struct sfb_sched_data *q,
+ int *qerr, u32 *salt)
+{
+ struct tcf_result res;
+ int result;
+
+ result = tc_classify(skb, q->filter_list, &res);
+ if (result >= 0) {
+#ifdef CONFIG_NET_CLS_ACT
+ switch (result) {
+ case TC_ACT_STOLEN:
+ case TC_ACT_QUEUED:
+ *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
+ case TC_ACT_SHOT:
+ return false;
+ }
+#endif
+ *salt = TC_H_MIN(res.classid);
+ return true;
+ }
+ return false;
+}
+
+static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+{
+
+ struct sfb_sched_data *q = qdisc_priv(sch);
+ struct Qdisc *child = q->qdisc;
+ int i;
+ u32 p_min = ~0;
+ u32 minqlen = ~0;
+ u32 r, slot, salt, sfbhash;
+ int ret = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
+
+ if (q->rehash_interval > 0) {
+ unsigned long limit = q->rehash_time + q->rehash_interval;
+
+ if (unlikely(time_after(jiffies, limit))) {
+ sfb_swap_slot(q);
+ q->rehash_time = jiffies;
+ } else if (unlikely(!q->double_buffering && q->warmup_time > 0 &&
+ time_after(jiffies, limit - q->warmup_time))) {
+ q->double_buffering = true;
+ }
+ }
+
+ if (q->filter_list) {
+ /* If using external classifiers, get result and record it. */
+ if (!sfb_classify(skb, q, &ret, &salt))
+ goto other_drop;
+ } else {
+ salt = skb_get_rxhash(skb);
+ }
+
+ slot = q->slot;
+
+ sfbhash = jhash_1word(salt, q->bins[slot].perturbation);
+ if (!sfbhash)
+ sfbhash = 1;
+ sfb_skb_cb(skb)->hashes[slot] = sfbhash;
+
+ for (i = 0; i < SFB_LEVELS; i++) {
+ u32 hash = sfbhash & SFB_BUCKET_MASK;
+ struct sfb_bucket *b = &q->bins[slot].bins[i][hash];
+
+ sfbhash >>= SFB_BUCKET_SHIFT;
+ if (b->qlen == 0)
+ decrement_prob(b, q);
+ else if (b->qlen >= q->bin_size)
+ increment_prob(b, q);
+ if (minqlen > b->qlen)
+ minqlen = b->qlen;
+ if (p_min > b->p_mark)
+ p_min = b->p_mark;
+ }
+
+ slot ^= 1;
+ sfb_skb_cb(skb)->hashes[slot] = 0;
+
+ if (unlikely(minqlen >= q->max || sch->q.qlen >= q->limit)) {
+ sch->qstats.overlimits++;
+ if (minqlen >= q->max)
+ q->stats.bucketdrop++;
+ else
+ q->stats.queuedrop++;
+ goto drop;
+ }
+
+ if (unlikely(p_min >= SFB_MAX_PROB)) {
+ /* Inelastic flow */
+ if (q->double_buffering) {
+ sfbhash = jhash_1word(salt, q->bins[slot].perturbation);
+ if (!sfbhash)
+ sfbhash = 1;
+ sfb_skb_cb(skb)->hashes[slot] = sfbhash;
+
+ for (i = 0; i < SFB_LEVELS; i++) {
+ u32 hash = sfbhash & SFB_BUCKET_MASK;
+ struct sfb_bucket *b = &q->bins[slot].bins[i][hash];
+
+ sfbhash >>= SFB_BUCKET_SHIFT;
+ if (b->qlen == 0)
+ decrement_prob(b, q);
+ else if (b->qlen >= q->bin_size)
+ increment_prob(b, q);
+ }
+ }
+ if (sfb_rate_limit(skb, q)) {
+ sch->qstats.overlimits++;
+ q->stats.penaltydrop++;
+ goto drop;
+ }
+ goto enqueue;
+ }
+
+ r = net_random() & SFB_MAX_PROB;
+
+ if (unlikely(r < p_min)) {
+ if (unlikely(p_min > SFB_MAX_PROB / 2)) {
+ /* If we're marking that many packets, then either
+ * this flow is unresponsive, or we're badly congested.
+ * In either case, we want to start dropping packets.
+ */
+ if (r < (p_min - SFB_MAX_PROB / 2) * 2) {
+ q->stats.earlydrop++;
+ goto drop;
+ }
+ }
+ if (INET_ECN_set_ce(skb)) {
+ q->stats.marked++;
+ } else {
+ q->stats.earlydrop++;
+ goto drop;
+ }
+ }
+
+enqueue:
+ ret = qdisc_enqueue(skb, child);
+ if (likely(ret == NET_XMIT_SUCCESS)) {
+ sch->q.qlen++;
+ increment_qlen(skb, q);
+ } else if (net_xmit_drop_count(ret)) {
+ q->stats.childdrop++;
+ sch->qstats.drops++;
+ }
+ return ret;
+
+drop:
+ qdisc_drop(skb, sch);
+ return NET_XMIT_CN;
+other_drop:
+ if (ret & __NET_XMIT_BYPASS)
+ sch->qstats.drops++;
+ kfree_skb(skb);
+ return ret;
+}
+
+static struct sk_buff *sfb_dequeue(struct Qdisc *sch)
+{
+ struct sfb_sched_data *q = qdisc_priv(sch);
+ struct Qdisc *child = q->qdisc;
+ struct sk_buff *skb;
+
+ skb = child->dequeue(q->qdisc);
+
+ if (skb) {
+ qdisc_bstats_update(sch, skb);
+ sch->q.qlen--;
+ decrement_qlen(skb, q);
+ }
+
+ return skb;
+}
+
+static struct sk_buff *sfb_peek(struct Qdisc *sch)
+{
+ struct sfb_sched_data *q = qdisc_priv(sch);
+ struct Qdisc *child = q->qdisc;
+
+ return child->ops->peek(child);
+}
+
+/* No sfb_drop -- impossible since the child doesn't return the dropped skb. */
+
+static void sfb_reset(struct Qdisc *sch)
+{
+ struct sfb_sched_data *q = qdisc_priv(sch);
+
+ qdisc_reset(q->qdisc);
+ sch->q.qlen = 0;
+ q->slot = 0;
+ q->double_buffering = false;
+ sfb_zero_all_buckets(q);
+ sfb_init_perturbation(0, q);
+}
+
+static void sfb_destroy(struct Qdisc *sch)
+{
+ struct sfb_sched_data *q = qdisc_priv(sch);
+
+ tcf_destroy_chain(&q->filter_list);
+ qdisc_destroy(q->qdisc);
+}
+
+static const struct nla_policy sfb_policy[TCA_SFB_MAX + 1] = {
+ [TCA_SFB_PARMS] = { .len = sizeof(struct tc_sfb_qopt) },
+};
+
+static const struct tc_sfb_qopt sfb_default_ops = {
+ .rehash_interval = 600 * MSEC_PER_SEC,
+ .warmup_time = 60 * MSEC_PER_SEC,
+ .limit = 0,
+ .max = 25,
+ .bin_size = 20,
+ .increment = (SFB_MAX_PROB + 500) / 1000, /* 0.1 % */
+ .decrement = (SFB_MAX_PROB + 3000) / 6000,
+ .penalty_rate = 10,
+ .penalty_burst = 20,
+};
+
+static int sfb_change(struct Qdisc *sch, struct nlattr *opt)
+{
+ struct sfb_sched_data *q = qdisc_priv(sch);
+ struct Qdisc *child;
+ struct nlattr *tb[TCA_SFB_MAX + 1];
+ const struct tc_sfb_qopt *ctl = &sfb_default_ops;
+ u32 limit;
+ int err;
+
+ if (opt) {
+ err = nla_parse_nested(tb, TCA_SFB_MAX, opt, sfb_policy);
+ if (err < 0)
+ return -EINVAL;
+
+ if (tb[TCA_SFB_PARMS] == NULL)
+ return -EINVAL;
+
+ ctl = nla_data(tb[TCA_SFB_PARMS]);
+ }
+
+ limit = ctl->limit;
+ if (limit == 0)
+ limit = max_t(u32, qdisc_dev(sch)->tx_queue_len, 1);
+
+ child = fifo_create_dflt(sch, &pfifo_qdisc_ops, limit);
+ if (IS_ERR(child))
+ return PTR_ERR(child);
+
+ sch_tree_lock(sch);
+
+ qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen);
+ qdisc_destroy(q->qdisc);
+ q->qdisc = child;
+
+ q->rehash_interval = msecs_to_jiffies(ctl->rehash_interval);
+ q->warmup_time = msecs_to_jiffies(ctl->warmup_time);
+ q->rehash_time = jiffies;
+ q->limit = limit;
+ q->increment = ctl->increment;
+ q->decrement = ctl->decrement;
+ q->max = ctl->max;
+ q->bin_size = ctl->bin_size;
+ q->penalty_rate = ctl->penalty_rate;
+ q->penalty_burst = ctl->penalty_burst;
+ q->tokens_avail = ctl->penalty_burst;
+ q->token_time = jiffies;
+
+ q->slot = 0;
+ q->double_buffering = false;
+ sfb_zero_all_buckets(q);
+ sfb_init_perturbation(0, q);
+ sfb_init_perturbation(1, q);
+
+ sch_tree_unlock(sch);
+
+ return 0;
+}
+
+static int sfb_init(struct Qdisc *sch, struct nlattr *opt)
+{
+ struct sfb_sched_data *q = qdisc_priv(sch);
+
+ q->qdisc = &noop_qdisc;
+ return sfb_change(sch, opt);
+}
+
+static int sfb_dump(struct Qdisc *sch, struct sk_buff *skb)
+{
+ struct sfb_sched_data *q = qdisc_priv(sch);
+ struct nlattr *opts;
+ struct tc_sfb_qopt opt = {
+ .rehash_interval = jiffies_to_msecs(q->rehash_interval),
+ .warmup_time = jiffies_to_msecs(q->warmup_time),
+ .limit = q->limit,
+ .max = q->max,
+ .bin_size = q->bin_size,
+ .increment = q->increment,
+ .decrement = q->decrement,
+ .penalty_rate = q->penalty_rate,
+ .penalty_burst = q->penalty_burst,
+ };
+
+ sch->qstats.backlog = q->qdisc->qstats.backlog;
+ opts = nla_nest_start(skb, TCA_OPTIONS);
+ NLA_PUT(skb, TCA_SFB_PARMS, sizeof(opt), &opt);
+ return nla_nest_end(skb, opts);
+
+nla_put_failure:
+ nla_nest_cancel(skb, opts);
+ return -EMSGSIZE;
+}
+
+static int sfb_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
+{
+ struct sfb_sched_data *q = qdisc_priv(sch);
+ struct tc_sfb_xstats st = {
+ .earlydrop = q->stats.earlydrop,
+ .penaltydrop = q->stats.penaltydrop,
+ .bucketdrop = q->stats.bucketdrop,
+ .queuedrop = q->stats.queuedrop,
+ .childdrop = q->stats.childdrop,
+ .marked = q->stats.marked,
+ };
+
+ st.maxqlen = sfb_compute_qlen(&st.maxprob, &st.avgprob, q);
+
+ return gnet_stats_copy_app(d, &st, sizeof(st));
+}
+
+static int sfb_dump_class(struct Qdisc *sch, unsigned long cl,
+ struct sk_buff *skb, struct tcmsg *tcm)
+{
+ return -ENOSYS;
+}
+
+static int sfb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
+ struct Qdisc **old)
+{
+ struct sfb_sched_data *q = qdisc_priv(sch);
+
+ if (new == NULL)
+ new = &noop_qdisc;
+
+ sch_tree_lock(sch);
+ *old = q->qdisc;
+ q->qdisc = new;
+ qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
+ qdisc_reset(*old);
+ sch_tree_unlock(sch);
+ return 0;
+}
+
+static struct Qdisc *sfb_leaf(struct Qdisc *sch, unsigned long arg)
+{
+ struct sfb_sched_data *q = qdisc_priv(sch);
+
+ return q->qdisc;
+}
+
+static unsigned long sfb_get(struct Qdisc *sch, u32 classid)
+{
+ return 1;
+}
+
+static void sfb_put(struct Qdisc *sch, unsigned long arg)
+{
+}
+
+static int sfb_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+ struct nlattr **tca, unsigned long *arg)
+{
+ return -ENOSYS;
+}
+
+static int sfb_delete(struct Qdisc *sch, unsigned long cl)
+{
+ return -ENOSYS;
+}
+
+static void sfb_walk(struct Qdisc *sch, struct qdisc_walker *walker)
+{
+ if (!walker->stop) {
+ if (walker->count >= walker->skip)
+ if (walker->fn(sch, 1, walker) < 0) {
+ walker->stop = 1;
+ return;
+ }
+ walker->count++;
+ }
+}
+
+static struct tcf_proto **sfb_find_tcf(struct Qdisc *sch, unsigned long cl)
+{
+ struct sfb_sched_data *q = qdisc_priv(sch);
+
+ if (cl)
+ return NULL;
+ return &q->filter_list;
+}
+
+static unsigned long sfb_bind(struct Qdisc *sch, unsigned long parent,
+ u32 classid)
+{
+ return 0;
+}
+
+
+static const struct Qdisc_class_ops sfb_class_ops = {
+ .graft = sfb_graft,
+ .leaf = sfb_leaf,
+ .get = sfb_get,
+ .put = sfb_put,
+ .change = sfb_change_class,
+ .delete = sfb_delete,
+ .walk = sfb_walk,
+ .tcf_chain = sfb_find_tcf,
+ .bind_tcf = sfb_bind,
+ .unbind_tcf = sfb_put,
+ .dump = sfb_dump_class,
+};
+
+struct Qdisc_ops sfb_qdisc_ops __read_mostly = {
+ .id = "sfb",
+ .priv_size = sizeof(struct sfb_sched_data),
+ .cl_ops = &sfb_class_ops,
+ .enqueue = sfb_enqueue,
+ .dequeue = sfb_dequeue,
+ .peek = sfb_peek,
+ .init = sfb_init,
+ .reset = sfb_reset,
+ .destroy = sfb_destroy,
+ .change = sfb_change,
+ .dump = sfb_dump,
+ .dump_stats = sfb_dump_stats,
+ .owner = THIS_MODULE,
+};
+
+static int __init sfb_module_init(void)
+{
+ return register_qdisc(&sfb_qdisc_ops);
+}
+
+static void __exit sfb_module_exit(void)
+{
+ unregister_qdisc(&sfb_qdisc_ops);
+}
+
+module_init(sfb_module_init)
+module_exit(sfb_module_exit)
+
+MODULE_DESCRIPTION("Stochastic Fair Blue queue discipline");
+MODULE_AUTHOR("Juliusz Chroboczek");
+MODULE_AUTHOR("Eric Dumazet");
+MODULE_LICENSE("GPL");
^ permalink raw reply related
* Re: [RFC PATCH 09/10] netdev: octeon_mgmt: Convert to use device tree.
From: David Miller @ 2011-02-23 20:33 UTC (permalink / raw)
To: grant.likely
Cc: ddaney, linux-mips, ralf, devicetree-discuss, linux-kernel,
netdev
In-Reply-To: <20110223163200.GC14597@angua.secretlab.ca>
Grant, please do not quote hundreds of lines of the patch which
you are not commenting on, just to make comments on a few small
hunks.
Thanks.
^ permalink raw reply
* Re: [PATCH] cxgb{3,4}: streamline Kconfig options
From: David Miller @ 2011-02-23 20:27 UTC (permalink / raw)
To: JBeulich; +Cc: divy, dm, linux-kbuild, netdev
In-Reply-To: <4D64E5720200007800033420@vpn.id2.novell.com>
From: "Jan Beulich" <JBeulich@novell.com>
Date: Wed, 23 Feb 2011 09:46:10 +0000
>>>> On 22.02.11 at 19:14, David Miller <davem@davemloft.net> wrote:
>> From: "Jan Beulich" <JBeulich@novell.com>
>> Date: Thu, 17 Feb 2011 13:29:30 +0000
>>
>>> The CHELSIO_T{3,4}_DEPENDS options are really awkward, and can be
>>> easily dropped if the reverse dependencies of SCSI_CXGB{3,4}_ISCSI on
>>> the former get converted to normal (forward) ones referring to
>>> CHELSIO_T{3,4}.
>>>
>>> Signed-off-by: Jan Beulich <jbeulich@novell.com>
>>
>> I think the goal of these strange rules is not to be complicated
>> on purpose, but rather to cause the iSCSI drivers to appear without
>> the user having to know that he needs to enable the networking
>> driver in order for that to happen.
>
> While I realize that this might have been the reason, it's completely
> contrary to how everyone else writes dependencies, and hence I
> think these should be removed.
If you knew you were changing the behavior of the config option in
this way, you sure didn't think it was worth mentioning in your commit
message.
I definitely would never expect to have to enable a scsi option to get
some network driver visible to enable in the config, and therefore I
could see the opposite being insanely frustrating too.
You can't ignore these issues and just say "that's not the normal way
so I'm going to change it anyways."
^ permalink raw reply
* Re: [PATCH] r8169: incorrect args to oob notify
From: Francois Romieu @ 2011-02-23 20:00 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, netdev, Hayes Wang
In-Reply-To: <20110223095237.0ee9c130@nehalam>
Stephen Hemminger <shemminger@vyatta.com> :
[...]
> Sparse detected this bug. The function oob_notify was being
> passed the private ptr, but expected to get the ioaddr.
> Compile checked only; not tested on real hardware.
>
> Patch against net-next-2.6 but should be applied to net-2.6.
> Bug not present in 2.6.37 and earlier.
Hayes has sent this fix and a few others. I am giving them a short
testing right now.
--
Ueimor
^ permalink raw reply
* [PATCH 2/5] atl1[ce]: fix sparse warnings
From: Stephen Hemminger @ 2011-02-23 19:06 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20110223190647.482444598@vyatta.com>
[-- Attachment #1: atl1c-sparse.patch --]
[-- Type: text/plain, Size: 1751 bytes --]
The dmaw_block is an enum and max_pay_load is u32. Therefore
sparse gives warning about comparison of unsigned and signed value.
Resolve by using min_t to force cast.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/atl1c/atl1c_main.c 2011-02-23 09:58:11.282457630 -0800
+++ b/drivers/net/atl1c/atl1c_main.c 2011-02-23 09:58:42.626823758 -0800
@@ -1102,10 +1102,10 @@ static void atl1c_configure_tx(struct at
AT_READ_REG(hw, REG_DEVICE_CTRL, &dev_ctrl_data);
max_pay_load = (dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT) &
DEVICE_CTRL_MAX_PAYLOAD_MASK;
- hw->dmaw_block = min(max_pay_load, hw->dmaw_block);
+ hw->dmaw_block = min_t(u32, max_pay_load, hw->dmaw_block);
max_pay_load = (dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT) &
DEVICE_CTRL_MAX_RREQ_SZ_MASK;
- hw->dmar_block = min(max_pay_load, hw->dmar_block);
+ hw->dmar_block = min_t(u32, max_pay_load, hw->dmar_block);
txq_ctrl_data = (hw->tpd_burst & TXQ_NUM_TPD_BURST_MASK) <<
TXQ_NUM_TPD_BURST_SHIFT;
--- a/drivers/net/atl1e/atl1e_main.c 2011-02-23 09:58:52.594940247 -0800
+++ b/drivers/net/atl1e/atl1e_main.c 2011-02-23 09:59:03.859071913 -0800
@@ -932,11 +932,11 @@ static inline void atl1e_configure_tx(st
max_pay_load = ((dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT)) &
DEVICE_CTRL_MAX_PAYLOAD_MASK;
- hw->dmaw_block = min(max_pay_load, hw->dmaw_block);
+ hw->dmaw_block = min_t(u32, max_pay_load, hw->dmaw_block);
max_pay_load = ((dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT)) &
DEVICE_CTRL_MAX_RREQ_SZ_MASK;
- hw->dmar_block = min(max_pay_load, hw->dmar_block);
+ hw->dmar_block = min_t(u32, max_pay_load, hw->dmar_block);
if (hw->nic_type != athr_l2e_revB)
AT_WRITE_REGW(hw, REG_TXQ_CTRL + 2,
^ permalink raw reply
* [PATCH 4/5] mqprio: cleanups
From: Stephen Hemminger @ 2011-02-23 19:06 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20110223190647.482444598@vyatta.com>
[-- Attachment #1: mqprio-sparse.patch --]
[-- Type: text/plain, Size: 914 bytes --]
* make qdisc_ops local
* add sparse annotation about expected unlock/unlock in dump_class_stats
* fix indentation
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/net/sched/sch_mqprio.c 2011-02-23 10:22:17.171259588 -0800
+++ b/net/sched/sch_mqprio.c 2011-02-23 10:28:51.955835730 -0800
@@ -311,7 +311,9 @@ static int mqprio_dump_class(struct Qdis
}
static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
- struct gnet_dump *d)
+ struct gnet_dump *d)
+ __releases(d->lock)
+ __acquires(d->lock)
{
struct net_device *dev = qdisc_dev(sch);
@@ -389,7 +391,7 @@ static const struct Qdisc_class_ops mqpr
.dump_stats = mqprio_dump_class_stats,
};
-struct Qdisc_ops mqprio_qdisc_ops __read_mostly = {
+static struct Qdisc_ops mqprio_qdisc_ops __read_mostly = {
.cl_ops = &mqprio_class_ops,
.id = "mqprio",
.priv_size = sizeof(struct mqprio_sched),
^ permalink raw reply
* [PATCH 1/5] socket: suppress sparse warnings
From: Stephen Hemminger @ 2011-02-23 19:06 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20110223190647.482444598@vyatta.com>
[-- Attachment #1: socket-sparse --]
[-- Type: text/plain, Size: 1122 bytes --]
Use __force to quiet sparse warnings for cases where the code
is simulating user space pointers.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/net/socket.c 2011-02-23 08:26:51.905069267 -0800
+++ b/net/socket.c 2011-02-23 08:26:59.005160474 -0800
@@ -2648,7 +2648,8 @@ static int bond_ioctl(struct net *net, u
old_fs = get_fs();
set_fs(KERNEL_DS);
- err = dev_ioctl(net, cmd, &kifr);
+ err = dev_ioctl(net, cmd,
+ (struct ifreq __user __force *) &kifr);
set_fs(old_fs);
return err;
@@ -2757,7 +2758,7 @@ static int compat_sioc_ifmap(struct net
old_fs = get_fs();
set_fs(KERNEL_DS);
- err = dev_ioctl(net, cmd, (void __user *)&ifr);
+ err = dev_ioctl(net, cmd, (void __user __force *)&ifr);
set_fs(old_fs);
if (cmd == SIOCGIFMAP && !err) {
@@ -2862,7 +2863,8 @@ static int routing_ioctl(struct net *net
ret |= __get_user(rtdev, &(ur4->rt_dev));
if (rtdev) {
ret |= copy_from_user(devname, compat_ptr(rtdev), 15);
- r4.rt_dev = devname; devname[15] = 0;
+ r4.rt_dev = (char __user __force *)devname;
+ devname[15] = 0;
} else
r4.rt_dev = NULL;
^ permalink raw reply
* [PATCH 3/5] afkey: add sparse annotation about rcu
From: Stephen Hemminger @ 2011-02-23 19:06 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20110223190647.482444598@vyatta.com>
[-- Attachment #1: afkey-sparse --]
[-- Type: text/plain, Size: 604 bytes --]
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/net/key/af_key.c 2011-02-23 10:20:23.181943425 -0800
+++ b/net/key/af_key.c 2011-02-23 10:20:47.290221581 -0800
@@ -3655,6 +3655,7 @@ static int pfkey_seq_show(struct seq_fil
}
static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos)
+ __acquires(rcu)
{
struct net *net = seq_file_net(f);
struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
@@ -3672,6 +3673,7 @@ static void *pfkey_seq_next(struct seq_f
}
static void pfkey_seq_stop(struct seq_file *f, void *v)
+ __releases(rcu)
{
rcu_read_unlock();
}
^ permalink raw reply
* [PATCH 0/5] sparse related patches
From: Stephen Hemminger @ 2011-02-23 19:06 UTC (permalink / raw)
To: davem; +Cc: netdev
^ permalink raw reply
* [PATCH 5/5] em_meta: fix sparse warning
From: Stephen Hemminger @ 2011-02-23 19:06 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20110223190647.482444598@vyatta.com>
[-- Attachment #1: em-meta-sparse --]
[-- Type: text/plain, Size: 457 bytes --]
gfp_t needs to be cast to integer.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/net/sched/em_meta.c 2011-02-23 10:26:17.534042646 -0800
+++ b/net/sched/em_meta.c 2011-02-23 10:30:37.533063770 -0800
@@ -401,7 +401,7 @@ META_COLLECTOR(int_sk_sndbuf)
META_COLLECTOR(int_sk_alloc)
{
SKIP_NONLOCAL(skb);
- dst->value = skb->sk->sk_allocation;
+ dst->value = (__force int) skb->sk->sk_allocation;
}
META_COLLECTOR(int_sk_route_caps)
^ 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