* RE: [PATCH 1/2] ixgb: Don't check for vlan group on transmit.
From: Duyck, Alexander H @ 2010-12-01 17:40 UTC (permalink / raw)
To: Jesse Gross
Cc: Kirsher, Jeffrey T, David Miller, netdev@vger.kernel.org,
Brandeburg, Jesse
In-Reply-To: <AANLkTik43SPbQiTxOQPTsUq9hu7h3EgbZ1cvxh=nsFPM@mail.gmail.com>
>-----Original Message-----
>From: Jesse Gross [mailto:jesse@nicira.com]
>Sent: Tuesday, November 30, 2010 2:34 PM
>To: Duyck, Alexander H
>Cc: Kirsher, Jeffrey T; David Miller; netdev@vger.kernel.org;
>Brandeburg, Jesse
>Subject: Re: [PATCH 1/2] ixgb: Don't check for vlan group on transmit.
>
>On Mon, Nov 8, 2010 at 11:59 AM, Jesse Gross <jesse@nicira.com> wrote:
>> On Fri, Nov 5, 2010 at 3:30 PM, Duyck, Alexander H
>>> The quick fix for your patch is to move the addition of
>VLAN_TAG_SIZE to the max_frame in igb_change_mtu instead of in the
>set_rlpml call. Otherwise I will see about submitting an updated
>patch in the next few days.
>>
>> I happy to let you take care of it - obviously you know the
>> driver/hardware much better than I.
>
>Alex, did you get a chance to take a look at this? I was hoping to
>get the fix for this (and also the patch mentioned originally in this
>message for ixgb) into 2.6.37. I can also respin it along the lines
>that you suggested if that would help.
I did, and we are currently testing the patch I have generated. Once it passes testing Jeff will submit it to netdev.
Thanks,
Alex
^ permalink raw reply
* Re: [PATCH net-next-2.6] net: optimize INET input path further
From: Eric Dumazet @ 2010-12-01 17:42 UTC (permalink / raw)
To: Brian Haley; +Cc: David Miller, netdev
In-Reply-To: <4CF687F3.7030107@hp.com>
Le mercredi 01 décembre 2010 à 12:37 -0500, Brian Haley a écrit :
> On 12/01/2010 12:04 AM, Eric Dumazet wrote:
> > struct sock_common {
> > - /*
> > - * first fields are not copied in sock_copy()
> > + /* skc_daddr and skc_rcv_saddr must be grouped :
> > + * cf INET_MATCH() and INET_TW_MATCH()
> > */
> > - union {
> > - struct hlist_node skc_node;
> > - struct hlist_nulls_node skc_nulls_node;
> > - };
> > - atomic_t skc_refcnt;
> > - int skc_tx_queue_mapping;
> > + __be32 skc_daddr;
> > + __be32 skc_rcv_saddr;
> >
> > union {
> > unsigned int skc_hash;
>
> Putting IPv4 addresses in sock_common doesn't make it so common anymore :)
>
> Is it possible to make this a union so other address families like IPv6
> can benefit from this as well, or will that blow the whole cache line
> effect you were trying to achieve?
This might be OK, depending on cache line size and/or arch.
On x86_32 for example, that might even be a good thing, because refcnt
might still be in the first 64bytes of socket.
By the way, ipv6 sock includes inet, so includes ipv4 addresses too, I
only moved them in the 'whole structure'
^ permalink raw reply
* [PATCH] ath: Add and use ath_printk and ath_<level>
From: Joe Perches @ 2010-12-01 17:44 UTC (permalink / raw)
To: Felix Fietkau, Luis R. Rodriguez
Cc: ath9k-devel, Peter Stuge, John W. Linville, linux-wireless,
netdev, linux-kernel
In-Reply-To: <4CF65DB9.3050007@openwrt.org>
Add ath_printk and ath_<level> similar to
dev_printk and dev_<level> from device.h
This allows a more gradual rename of ath_print
to to ath_dbg or perhaps ath_debug.
This basically removes debug.h leaving
only an #define ath_printk ath_dbg
there and moving all the ATH_DBG_<foo>
enums to ath.h
I do not think there's much purpose for struct
ath_common * being passed to the ath_printk
functions, but perhaps there might be.
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/net/wireless/ath/ath.h | 103 ++++++++++++++++++++++++++++++++++++++
drivers/net/wireless/ath/debug.c | 20 -------
drivers/net/wireless/ath/debug.h | 72 +--------------------------
drivers/net/wireless/ath/main.c | 20 +++++++
4 files changed, 124 insertions(+), 91 deletions(-)
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 26bdbee..5a598b9 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -186,4 +186,107 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry);
void ath_hw_cycle_counters_update(struct ath_common *common);
int32_t ath_hw_get_listen_time(struct ath_common *common);
+extern __attribute__ ((format (printf, 3, 4))) int
+ath_printk(const char *level, struct ath_common *common, const char *fmt, ...);
+
+#define ath_emerg(common, fmt, ...) \
+ ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS)
+#define ath_alert(common, fmt, ...) \
+ ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS)
+#define ath_crit(common, fmt, ...) \
+ ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS)
+#define ath_err(common, fmt, ...) \
+ ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS)
+#define ath_warn(common, fmt, ...) \
+ ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS)
+#define ath_notice(common, fmt, ...) \
+ ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS)
+#define ath_info(common, fmt, ...) \
+ ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS)
+
+/**
+ * enum ath_debug_level - atheros wireless debug level
+ *
+ * @ATH_DBG_RESET: reset processing
+ * @ATH_DBG_QUEUE: hardware queue management
+ * @ATH_DBG_EEPROM: eeprom processing
+ * @ATH_DBG_CALIBRATE: periodic calibration
+ * @ATH_DBG_INTERRUPT: interrupt processing
+ * @ATH_DBG_REGULATORY: regulatory processing
+ * @ATH_DBG_ANI: adaptive noise immunitive processing
+ * @ATH_DBG_XMIT: basic xmit operation
+ * @ATH_DBG_BEACON: beacon handling
+ * @ATH_DBG_CONFIG: configuration of the hardware
+ * @ATH_DBG_FATAL: fatal errors, this is the default, DBG_DEFAULT
+ * @ATH_DBG_PS: power save processing
+ * @ATH_DBG_HWTIMER: hardware timer handling
+ * @ATH_DBG_BTCOEX: bluetooth coexistance
+ * @ATH_DBG_BSTUCK: stuck beacons
+ * @ATH_DBG_ANY: enable all debugging
+ *
+ * The debug level is used to control the amount and type of debugging output
+ * we want to see. Each driver has its own method for enabling debugging and
+ * modifying debug level states -- but this is typically done through a
+ * module parameter 'debug' along with a respective 'debug' debugfs file
+ * entry.
+ */
+enum ATH_DEBUG {
+ ATH_DBG_RESET = 0x00000001,
+ ATH_DBG_QUEUE = 0x00000002,
+ ATH_DBG_EEPROM = 0x00000004,
+ ATH_DBG_CALIBRATE = 0x00000008,
+ ATH_DBG_INTERRUPT = 0x00000010,
+ ATH_DBG_REGULATORY = 0x00000020,
+ ATH_DBG_ANI = 0x00000040,
+ ATH_DBG_XMIT = 0x00000080,
+ ATH_DBG_BEACON = 0x00000100,
+ ATH_DBG_CONFIG = 0x00000200,
+ ATH_DBG_FATAL = 0x00000400,
+ ATH_DBG_PS = 0x00000800,
+ ATH_DBG_HWTIMER = 0x00001000,
+ ATH_DBG_BTCOEX = 0x00002000,
+ ATH_DBG_WMI = 0x00004000,
+ ATH_DBG_BSTUCK = 0x00008000,
+ ATH_DBG_ANY = 0xffffffff
+};
+
+#define ATH_DBG_DEFAULT (ATH_DBG_FATAL)
+
+#ifdef CONFIG_ATH_DEBUG
+
+#define ath_dbg(common, dbg_mask, fmt, ...) \
+({ \
+ int rtn; \
+ if ((common)->debug_mask & dbg_mask) \
+ rtn = ath_printk(KERN_DEBUG, common, fmt, \
+ ##__VA_ARGS__); \
+ else \
+ rtn = 0; \
+ \
+ rtn; \
+})
+#define ATH_DBG_WARN(foo, arg...) WARN(foo, arg)
+
+#else
+
+static inline __attribute__ ((format (printf, 3, 4))) int
+ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask,
+ const char *fmt, ...)
+{
+ return 0;
+}
+#define ATH_DBG_WARN(foo, arg) do {} while (0)
+
+#endif /* CONFIG_ATH_DEBUG */
+
+/** Returns string describing opmode, or NULL if unknown mode. */
+#ifdef CONFIG_ATH_DEBUG
+const char *ath_opmode_to_string(enum nl80211_iftype opmode);
+#else
+static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
+{
+ return "UNKNOWN";
+}
+#endif
+
#endif /* ATH_H */
diff --git a/drivers/net/wireless/ath/debug.c b/drivers/net/wireless/ath/debug.c
index a9600ba..5367b10 100644
--- a/drivers/net/wireless/ath/debug.c
+++ b/drivers/net/wireless/ath/debug.c
@@ -15,26 +15,6 @@
*/
#include "ath.h"
-#include "debug.h"
-
-void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
-{
- struct va_format vaf;
- va_list args;
-
- if (likely(!(common->debug_mask & dbg_mask)))
- return;
-
- va_start(args, fmt);
-
- vaf.fmt = fmt;
- vaf.va = &args;
-
- printk(KERN_DEBUG "ath: %pV", &vaf);
-
- va_end(args);
-}
-EXPORT_SYMBOL(ath_print);
const char *ath_opmode_to_string(enum nl80211_iftype opmode)
{
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index f207007..cec951c 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -17,76 +17,6 @@
#ifndef ATH_DEBUG_H
#define ATH_DEBUG_H
-#include "ath.h"
-
-/**
- * enum ath_debug_level - atheros wireless debug level
- *
- * @ATH_DBG_RESET: reset processing
- * @ATH_DBG_QUEUE: hardware queue management
- * @ATH_DBG_EEPROM: eeprom processing
- * @ATH_DBG_CALIBRATE: periodic calibration
- * @ATH_DBG_INTERRUPT: interrupt processing
- * @ATH_DBG_REGULATORY: regulatory processing
- * @ATH_DBG_ANI: adaptive noise immunitive processing
- * @ATH_DBG_XMIT: basic xmit operation
- * @ATH_DBG_BEACON: beacon handling
- * @ATH_DBG_CONFIG: configuration of the hardware
- * @ATH_DBG_FATAL: fatal errors, this is the default, DBG_DEFAULT
- * @ATH_DBG_PS: power save processing
- * @ATH_DBG_HWTIMER: hardware timer handling
- * @ATH_DBG_BTCOEX: bluetooth coexistance
- * @ATH_DBG_BSTUCK: stuck beacons
- * @ATH_DBG_ANY: enable all debugging
- *
- * The debug level is used to control the amount and type of debugging output
- * we want to see. Each driver has its own method for enabling debugging and
- * modifying debug level states -- but this is typically done through a
- * module parameter 'debug' along with a respective 'debug' debugfs file
- * entry.
- */
-enum ATH_DEBUG {
- ATH_DBG_RESET = 0x00000001,
- ATH_DBG_QUEUE = 0x00000002,
- ATH_DBG_EEPROM = 0x00000004,
- ATH_DBG_CALIBRATE = 0x00000008,
- ATH_DBG_INTERRUPT = 0x00000010,
- ATH_DBG_REGULATORY = 0x00000020,
- ATH_DBG_ANI = 0x00000040,
- ATH_DBG_XMIT = 0x00000080,
- ATH_DBG_BEACON = 0x00000100,
- ATH_DBG_CONFIG = 0x00000200,
- ATH_DBG_FATAL = 0x00000400,
- ATH_DBG_PS = 0x00000800,
- ATH_DBG_HWTIMER = 0x00001000,
- ATH_DBG_BTCOEX = 0x00002000,
- ATH_DBG_WMI = 0x00004000,
- ATH_DBG_BSTUCK = 0x00008000,
- ATH_DBG_ANY = 0xffffffff
-};
-
-#define ATH_DBG_DEFAULT (ATH_DBG_FATAL)
-
-#ifdef CONFIG_ATH_DEBUG
-void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
- __attribute__ ((format (printf, 3, 4)));
-#define ATH_DBG_WARN(foo, arg...) WARN(foo, arg)
-#else
-static inline void __attribute__ ((format (printf, 3, 4)))
-ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
-{
-}
-#define ATH_DBG_WARN(foo, arg)
-#endif /* CONFIG_ATH_DEBUG */
-
-/** Returns string describing opmode, or NULL if unknown mode. */
-#ifdef CONFIG_ATH_DEBUG
-const char *ath_opmode_to_string(enum nl80211_iftype opmode);
-#else
-static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
-{
- return "UNKNOWN";
-}
-#endif
+#define ath_print ath_dbg
#endif /* ATH_DEBUG_H */
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c
index 487193f..c325202 100644
--- a/drivers/net/wireless/ath/main.c
+++ b/drivers/net/wireless/ath/main.c
@@ -56,3 +56,23 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
return skb;
}
EXPORT_SYMBOL(ath_rxbuf_alloc);
+
+int ath_printk(const char *level, struct ath_common *common,
+ const char *fmt, ...)
+{
+ struct va_format vaf;
+ va_list args;
+ int rtn;
+
+ va_start(args, fmt);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ rtn = printk("%sath: %pV", level, &vaf);
+
+ va_end(args);
+
+ return rtn;
+}
+EXPORT_SYMBOL(ath_printk);
--
1.7.3.2.245.g03276.dirty
^ permalink raw reply related
* Re: [PATCH net-next-2.6] net: optimize INET input path further
From: Brian Haley @ 2010-12-01 17:37 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1291179847.2856.452.camel@edumazet-laptop>
On 12/01/2010 12:04 AM, Eric Dumazet wrote:
> struct sock_common {
> - /*
> - * first fields are not copied in sock_copy()
> + /* skc_daddr and skc_rcv_saddr must be grouped :
> + * cf INET_MATCH() and INET_TW_MATCH()
> */
> - union {
> - struct hlist_node skc_node;
> - struct hlist_nulls_node skc_nulls_node;
> - };
> - atomic_t skc_refcnt;
> - int skc_tx_queue_mapping;
> + __be32 skc_daddr;
> + __be32 skc_rcv_saddr;
>
> union {
> unsigned int skc_hash;
Putting IPv4 addresses in sock_common doesn't make it so common anymore :)
Is it possible to make this a union so other address families like IPv6
can benefit from this as well, or will that blow the whole cache line
effect you were trying to achieve?
-Brian
^ permalink raw reply
* Re: [PATCH v16 14/17]Add a kconfig entry and make entry for mp device.
From: Randy Dunlap @ 2010-12-01 17:53 UTC (permalink / raw)
To: xiaohui.xin; +Cc: netdev, kvm, linux-kernel, mst, mingo, davem, herbert, jdike
In-Reply-To: <a1c255bc496b7aaca26912790f8bb0162dd1f4bf.1291187695.git.xiaohui.xin@intel.com>
On Wed, 1 Dec 2010 16:08:25 +0800 xiaohui.xin@intel.com wrote:
> From: Xin Xiaohui <xiaohui.xin@intel.com>
>
> Signed-off-by: Xin Xiaohui <xiaohui.xin@intel.com>
> Reviewed-by: Jeff Dike <jdike@linux.intel.com>
> ---
> drivers/vhost/Kconfig | 10 ++++++++++
> drivers/vhost/Makefile | 2 ++
> 2 files changed, 12 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
> index e4e2fd1..a6b8cbf 100644
> --- a/drivers/vhost/Kconfig
> +++ b/drivers/vhost/Kconfig
> @@ -9,3 +9,13 @@ config VHOST_NET
> To compile this driver as a module, choose M here: the module will
> be called vhost_net.
>
> +config MEDIATE_PASSTHRU
> + tristate "mediate passthru network driver (EXPERIMENTAL)"
> + depends on VHOST_NET
> + ---help---
> + zerocopy network I/O support, we call it as mediate passthru to
support; we call it "mediate passthru" to
> + be distiguish with hardare passthru.
distinguish it from hardware passthru.
> +
> + To compile this driver as a module, choose M here: the module will
> + be called mpassthru.
> +
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
^ permalink raw reply
* Re: [PATCH net-next-2.6] net: optimize INET input path further
From: Brian Haley @ 2010-12-01 18:00 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1291225358.2856.1035.camel@edumazet-laptop>
On 12/01/2010 12:42 PM, Eric Dumazet wrote:
>> Putting IPv4 addresses in sock_common doesn't make it so common anymore :)
>>
>> Is it possible to make this a union so other address families like IPv6
>> can benefit from this as well, or will that blow the whole cache line
>> effect you were trying to achieve?
>
> This might be OK, depending on cache line size and/or arch.
>
> On x86_32 for example, that might even be a good thing, because refcnt
> might still be in the first 64bytes of socket.
>
> By the way, ipv6 sock includes inet, so includes ipv4 addresses too, I
> only moved them in the 'whole structure'
Yes, all that IPv4 address baggage is still there in an IPv6 sock, even
if not used. I haven't even looked close enough to see if it is possible
to move the IPv6 addresses since I think there are times when both are
in-use.
-Brian
^ permalink raw reply
* [PATCH V2] ath: Add and use ath_printk and ath_<level>
From: Joe Perches @ 2010-12-01 18:05 UTC (permalink / raw)
To: Felix Fietkau, Luis R. Rodriguez
Cc: netdev, linux-wireless, John W. Linville, linux-kernel,
ath9k-devel, Peter Stuge
In-Reply-To: <d2a73495a7295cbd01ffd820761f538bc301f6aa.1291224405.git.joe@perches.com>
Add ath_printk and ath_<level> similar to
dev_printk and dev_<level> from device.h
This allows a more gradual rename of ath_print
to to ath_dbg or perhaps ath_debug.
This basically removes debug.h leaving
only an #define ath_printk ath_dbg
there and moving all the ATH_DBG_<foo>
enums to ath.h
I do not think there's much purpose for struct
ath_common * being passed to the ath_printk
functions, but perhaps there might be.
Signed-off-by: Joe Perches <joe@perches.com>
---
V2:
Yes, Joe's an eedjot that must learn to use git commit --amend properly.
Compiled and built with and without CONFIG_ATH_DEBUG but otherwise
untested.
drivers/net/wireless/ath/ath.h | 103 ++++++++++++++++++++++++++++++++++++++
drivers/net/wireless/ath/debug.c | 20 -------
drivers/net/wireless/ath/debug.h | 72 +--------------------------
drivers/net/wireless/ath/main.c | 20 +++++++
4 files changed, 124 insertions(+), 91 deletions(-)
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 26bdbee..cbdd654 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -186,4 +186,107 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry);
void ath_hw_cycle_counters_update(struct ath_common *common);
int32_t ath_hw_get_listen_time(struct ath_common *common);
+extern __attribute__ ((format (printf, 3, 4))) int
+ath_printk(const char *level, struct ath_common *common, const char *fmt, ...);
+
+#define ath_emerg(common, fmt, ...) \
+ ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__)
+#define ath_alert(common, fmt, ...) \
+ ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__)
+#define ath_crit(common, fmt, ...) \
+ ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__)
+#define ath_err(common, fmt, ...) \
+ ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__)
+#define ath_warn(common, fmt, ...) \
+ ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__)
+#define ath_notice(common, fmt, ...) \
+ ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__)
+#define ath_info(common, fmt, ...) \
+ ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__)
+
+/**
+ * enum ath_debug_level - atheros wireless debug level
+ *
+ * @ATH_DBG_RESET: reset processing
+ * @ATH_DBG_QUEUE: hardware queue management
+ * @ATH_DBG_EEPROM: eeprom processing
+ * @ATH_DBG_CALIBRATE: periodic calibration
+ * @ATH_DBG_INTERRUPT: interrupt processing
+ * @ATH_DBG_REGULATORY: regulatory processing
+ * @ATH_DBG_ANI: adaptive noise immunitive processing
+ * @ATH_DBG_XMIT: basic xmit operation
+ * @ATH_DBG_BEACON: beacon handling
+ * @ATH_DBG_CONFIG: configuration of the hardware
+ * @ATH_DBG_FATAL: fatal errors, this is the default, DBG_DEFAULT
+ * @ATH_DBG_PS: power save processing
+ * @ATH_DBG_HWTIMER: hardware timer handling
+ * @ATH_DBG_BTCOEX: bluetooth coexistance
+ * @ATH_DBG_BSTUCK: stuck beacons
+ * @ATH_DBG_ANY: enable all debugging
+ *
+ * The debug level is used to control the amount and type of debugging output
+ * we want to see. Each driver has its own method for enabling debugging and
+ * modifying debug level states -- but this is typically done through a
+ * module parameter 'debug' along with a respective 'debug' debugfs file
+ * entry.
+ */
+enum ATH_DEBUG {
+ ATH_DBG_RESET = 0x00000001,
+ ATH_DBG_QUEUE = 0x00000002,
+ ATH_DBG_EEPROM = 0x00000004,
+ ATH_DBG_CALIBRATE = 0x00000008,
+ ATH_DBG_INTERRUPT = 0x00000010,
+ ATH_DBG_REGULATORY = 0x00000020,
+ ATH_DBG_ANI = 0x00000040,
+ ATH_DBG_XMIT = 0x00000080,
+ ATH_DBG_BEACON = 0x00000100,
+ ATH_DBG_CONFIG = 0x00000200,
+ ATH_DBG_FATAL = 0x00000400,
+ ATH_DBG_PS = 0x00000800,
+ ATH_DBG_HWTIMER = 0x00001000,
+ ATH_DBG_BTCOEX = 0x00002000,
+ ATH_DBG_WMI = 0x00004000,
+ ATH_DBG_BSTUCK = 0x00008000,
+ ATH_DBG_ANY = 0xffffffff
+};
+
+#define ATH_DBG_DEFAULT (ATH_DBG_FATAL)
+
+#ifdef CONFIG_ATH_DEBUG
+
+#define ath_dbg(common, dbg_mask, fmt, ...) \
+({ \
+ int rtn; \
+ if ((common)->debug_mask & dbg_mask) \
+ rtn = ath_printk(KERN_DEBUG, common, fmt, \
+ ##__VA_ARGS__); \
+ else \
+ rtn = 0; \
+ \
+ rtn; \
+})
+#define ATH_DBG_WARN(foo, arg...) WARN(foo, arg)
+
+#else
+
+static inline __attribute__ ((format (printf, 3, 4))) int
+ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask,
+ const char *fmt, ...)
+{
+ return 0;
+}
+#define ATH_DBG_WARN(foo, arg) do {} while (0)
+
+#endif /* CONFIG_ATH_DEBUG */
+
+/** Returns string describing opmode, or NULL if unknown mode. */
+#ifdef CONFIG_ATH_DEBUG
+const char *ath_opmode_to_string(enum nl80211_iftype opmode);
+#else
+static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
+{
+ return "UNKNOWN";
+}
+#endif
+
#endif /* ATH_H */
diff --git a/drivers/net/wireless/ath/debug.c b/drivers/net/wireless/ath/debug.c
index a9600ba..5367b10 100644
--- a/drivers/net/wireless/ath/debug.c
+++ b/drivers/net/wireless/ath/debug.c
@@ -15,26 +15,6 @@
*/
#include "ath.h"
-#include "debug.h"
-
-void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
-{
- struct va_format vaf;
- va_list args;
-
- if (likely(!(common->debug_mask & dbg_mask)))
- return;
-
- va_start(args, fmt);
-
- vaf.fmt = fmt;
- vaf.va = &args;
-
- printk(KERN_DEBUG "ath: %pV", &vaf);
-
- va_end(args);
-}
-EXPORT_SYMBOL(ath_print);
const char *ath_opmode_to_string(enum nl80211_iftype opmode)
{
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index f207007..cec951c 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -17,76 +17,6 @@
#ifndef ATH_DEBUG_H
#define ATH_DEBUG_H
-#include "ath.h"
-
-/**
- * enum ath_debug_level - atheros wireless debug level
- *
- * @ATH_DBG_RESET: reset processing
- * @ATH_DBG_QUEUE: hardware queue management
- * @ATH_DBG_EEPROM: eeprom processing
- * @ATH_DBG_CALIBRATE: periodic calibration
- * @ATH_DBG_INTERRUPT: interrupt processing
- * @ATH_DBG_REGULATORY: regulatory processing
- * @ATH_DBG_ANI: adaptive noise immunitive processing
- * @ATH_DBG_XMIT: basic xmit operation
- * @ATH_DBG_BEACON: beacon handling
- * @ATH_DBG_CONFIG: configuration of the hardware
- * @ATH_DBG_FATAL: fatal errors, this is the default, DBG_DEFAULT
- * @ATH_DBG_PS: power save processing
- * @ATH_DBG_HWTIMER: hardware timer handling
- * @ATH_DBG_BTCOEX: bluetooth coexistance
- * @ATH_DBG_BSTUCK: stuck beacons
- * @ATH_DBG_ANY: enable all debugging
- *
- * The debug level is used to control the amount and type of debugging output
- * we want to see. Each driver has its own method for enabling debugging and
- * modifying debug level states -- but this is typically done through a
- * module parameter 'debug' along with a respective 'debug' debugfs file
- * entry.
- */
-enum ATH_DEBUG {
- ATH_DBG_RESET = 0x00000001,
- ATH_DBG_QUEUE = 0x00000002,
- ATH_DBG_EEPROM = 0x00000004,
- ATH_DBG_CALIBRATE = 0x00000008,
- ATH_DBG_INTERRUPT = 0x00000010,
- ATH_DBG_REGULATORY = 0x00000020,
- ATH_DBG_ANI = 0x00000040,
- ATH_DBG_XMIT = 0x00000080,
- ATH_DBG_BEACON = 0x00000100,
- ATH_DBG_CONFIG = 0x00000200,
- ATH_DBG_FATAL = 0x00000400,
- ATH_DBG_PS = 0x00000800,
- ATH_DBG_HWTIMER = 0x00001000,
- ATH_DBG_BTCOEX = 0x00002000,
- ATH_DBG_WMI = 0x00004000,
- ATH_DBG_BSTUCK = 0x00008000,
- ATH_DBG_ANY = 0xffffffff
-};
-
-#define ATH_DBG_DEFAULT (ATH_DBG_FATAL)
-
-#ifdef CONFIG_ATH_DEBUG
-void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
- __attribute__ ((format (printf, 3, 4)));
-#define ATH_DBG_WARN(foo, arg...) WARN(foo, arg)
-#else
-static inline void __attribute__ ((format (printf, 3, 4)))
-ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
-{
-}
-#define ATH_DBG_WARN(foo, arg)
-#endif /* CONFIG_ATH_DEBUG */
-
-/** Returns string describing opmode, or NULL if unknown mode. */
-#ifdef CONFIG_ATH_DEBUG
-const char *ath_opmode_to_string(enum nl80211_iftype opmode);
-#else
-static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
-{
- return "UNKNOWN";
-}
-#endif
+#define ath_print ath_dbg
#endif /* ATH_DEBUG_H */
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c
index 487193f..c325202 100644
--- a/drivers/net/wireless/ath/main.c
+++ b/drivers/net/wireless/ath/main.c
@@ -56,3 +56,23 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
return skb;
}
EXPORT_SYMBOL(ath_rxbuf_alloc);
+
+int ath_printk(const char *level, struct ath_common *common,
+ const char *fmt, ...)
+{
+ struct va_format vaf;
+ va_list args;
+ int rtn;
+
+ va_start(args, fmt);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ rtn = printk("%sath: %pV", level, &vaf);
+
+ va_end(args);
+
+ return rtn;
+}
+EXPORT_SYMBOL(ath_printk);
--
1.7.3.2.245.g03276.dirty
^ permalink raw reply related
* Re: multi bpf filter will impact performance?
From: David Miller @ 2010-12-01 18:18 UTC (permalink / raw)
To: hagen; +Cc: eric.dumazet, xiaosuo, wirelesser, netdev
In-Reply-To: <18eaf7d286236427b1632b9af62be513@localhost>
From: Hagen Paul Pfeifer <hagen@jauu.net>
Date: Wed, 01 Dec 2010 18:22:48 +0100
> On Wed, 01 Dec 2010 09:42:47 +0100, Eric Dumazet wrote:
>
>> IMHO, a better pcap optimizer would be the first step.
>
> +1
>
> Optimizing complex filter rules is step one in the process of optimizing
> the packet processing. A JIT compiler like FreeBSD provides cannot polish a
> (pcap)turd. I thought Patrick was working on a generic filter mechanism for
> netfilter!? ... ;)
Yes, and we spoke at the netfilter workshop about making that interpreter
available to socket filters and the packet classifier layer.
However, I think it's still valuable to write a few JIT compilers for
the existing BPF stuff. I considered working on a sparc64 JIT just to
see what it would look like.
If people work on the BPF optimizer and BPF JITs in parallel, we'll have
both ready at the same time. win++
^ permalink raw reply
* Re: multi bpf filter will impact performance?
From: David Miller @ 2010-12-01 18:24 UTC (permalink / raw)
To: hagen; +Cc: eric.dumazet, xiaosuo, wirelesser, netdev
In-Reply-To: <20101201.101809.71122121.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Wed, 01 Dec 2010 10:18:09 -0800 (PST)
> If people work on the BPF optimizer and BPF JITs in parallel, we'll have
> both ready at the same time. win++
BTW, the JIT is non-trivial work for us because of non-linear SKBs.
We'd need some kind of helper stub or similar, with a straight line
fast path for the linear case.
^ permalink raw reply
* [RFC PATCH v2 1/3] net: implement mechanism for HW based QOS
From: John Fastabend @ 2010-12-01 18:22 UTC (permalink / raw)
To: davem; +Cc: john.r.fastabend, netdev, tgraf, eric.dumazet
This patch provides a mechanism for lower layer devices to
steer traffic using skb->priority to tx queues. This allows
for hardware based QOS schemes to use the default qdisc without
incurring the penalties related to global state and the qdisc
lock. While reliably receiving skbs on the correct tx ring
to avoid head of line blocking resulting from shuffling in
the LLD. Finally, all the goodness from txq caching and xps/rps
can still be leveraged.
Many drivers and hardware exist with the ability to implement
QOS schemes in the hardware but currently these drivers tend
to rely on firmware to reroute specific traffic, a driver
specific select_queue or the queue_mapping action in the
qdisc.
None of these solutions are ideal or generic so we end up
with driver specific solutions that one-off traffic types
for example FCoE traffic is steered in ixgbe with the
queue_select routine. By using select_queue for this drivers
need to be updated for each and every traffic type and we
loose the goodness of much of the upstream work.
Firmware solutions are inherently inflexible. And finally if
admins are expected to build a qdisc and filter rules to steer
traffic this requires knowledge of how the hardware is currently
configured. The number of tx queues and the queue offsets may
change depending on resources. Also this approach incurs all the
overhead of a qdisc with filters.
With this mechanism users can set skb priority using expected
methods either socket options or the stack can set this directly.
Then the skb will be steered to the correct tx queues aligned
with hardware QOS traffic classes. In the normal case with a
single traffic class and all queues in this class every thing
works as is until the LLD enables multiple tcs.
To steer the skb we mask out the lower 8 bits of the priority
and allow the hardware to configure upto 15 distinct classes
of traffic. This is expected to be sufficient for most applications
at any rate it is more then the 8021Q spec designates and is
equal to the number of prio bands currently implemented in
the default qdisc.
This in conjunction with a userspace application such as
lldpad can be used to implement 8021Q transmission selection
algorithms one of these algorithms being the extended transmission
selection algorithm currently being used for DCB.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
include/linux/netdevice.h | 64 +++++++++++++++++++++++++++++++++++++++++++++
net/core/dev.c | 41 ++++++++++++++++++++++++++++-
2 files changed, 104 insertions(+), 1 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 4b0c7f3..3307979 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -628,6 +628,12 @@ struct xps_dev_maps {
(nr_cpu_ids * sizeof(struct xps_map *)))
#endif /* CONFIG_XPS */
+/* HW offloaded queuing disciplines txq count and offset maps */
+struct netdev_tc_txq {
+ u16 count;
+ u16 offset;
+};
+
/*
* This structure defines the management hooks for network devices.
* The following hooks can be defined; unless noted otherwise, they are
@@ -1128,6 +1134,10 @@ struct net_device {
/* Data Center Bridging netlink ops */
const struct dcbnl_rtnl_ops *dcbnl_ops;
#endif
+ u8 max_tcs;
+ u8 num_tcs;
+ struct netdev_tc_txq *_tc_to_txq;
+ u8 prio_tc_map[16];
#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
/* max exchange id for FCoE LRO by ddp */
@@ -1144,6 +1154,57 @@ struct net_device {
#define NETDEV_ALIGN 32
static inline
+int netdev_get_prio_tc_map(const struct net_device *dev, u32 prio)
+{
+ return dev->prio_tc_map[prio & 15];
+}
+
+static inline
+int netdev_set_prio_tc_map(struct net_device *dev, u8 prio, u8 tc)
+{
+ if (tc >= dev->num_tcs)
+ return -EINVAL;
+
+ return dev->prio_tc_map[prio & 15] = tc & 15;
+}
+
+static inline
+int netdev_set_tc_queue(struct net_device *dev, u8 tc, u16 count, u16 offset)
+{
+ struct netdev_tc_txq *tcp;
+
+ if (tc >= dev->num_tcs)
+ return -EINVAL;
+
+ tcp = &dev->_tc_to_txq[tc];
+ tcp->count = count;
+ tcp->offset = offset;
+ return 0;
+}
+
+static inline
+struct netdev_tc_txq *netdev_get_tc_queue(const struct net_device *dev, u8 tc)
+{
+ return &dev->_tc_to_txq[tc];
+}
+
+static inline
+int netdev_set_num_tc(struct net_device *dev, u8 num_tc)
+{
+ if (num_tc > dev->max_tcs)
+ return -EINVAL;
+
+ dev->num_tcs = num_tc;
+ return 0;
+}
+
+static inline
+u8 netdev_get_num_tc(const struct net_device *dev)
+{
+ return dev->num_tcs;
+}
+
+static inline
struct netdev_queue *netdev_get_tx_queue(const struct net_device *dev,
unsigned int index)
{
@@ -1368,6 +1429,9 @@ static inline void unregister_netdevice(struct net_device *dev)
unregister_netdevice_queue(dev, NULL);
}
+extern int netdev_alloc_max_tcs(struct net_device *dev, u8 tcs);
+extern void netdev_free_tcs(struct net_device *dev);
+
extern int netdev_refcnt_read(const struct net_device *dev);
extern void free_netdev(struct net_device *dev);
extern void synchronize_net(void);
diff --git a/net/core/dev.c b/net/core/dev.c
index 3259d2c..66c3af8 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2118,6 +2118,8 @@ static u32 hashrnd __read_mostly;
u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb)
{
u32 hash;
+ u16 qoffset = 0;
+ u16 qcount = dev->real_num_tx_queues;
if (skb_rx_queue_recorded(skb)) {
hash = skb_get_rx_queue(skb);
@@ -2126,13 +2128,20 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb)
return hash;
}
+ if (dev->num_tcs) {
+ u8 tc = netdev_get_prio_tc_map(dev, skb->priority);
+ struct netdev_tc_txq *tcp = netdev_get_tc_queue(dev, tc);
+ qoffset = tcp->offset;
+ qcount = tcp->count;
+ }
+
if (skb->sk && skb->sk->sk_hash)
hash = skb->sk->sk_hash;
else
hash = (__force u16) skb->protocol ^ skb->rxhash;
hash = jhash_1word(hash, hashrnd);
- return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32);
+ return (u16) ((((u64) hash * qcount)) >> 32) + qoffset;
}
EXPORT_SYMBOL(skb_tx_hash);
@@ -5088,6 +5097,35 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev,
}
EXPORT_SYMBOL(netif_stacked_transfer_operstate);
+int netdev_alloc_max_tcs(struct net_device *dev, u8 tcs)
+{
+ struct netdev_tc_txq *tcp;
+
+ if (tcs > 15)
+ return -EINVAL;
+
+ tcp = kcalloc(tcs, sizeof(*tcp), GFP_KERNEL);
+ if (!tcp)
+ return -ENOMEM;
+
+ dev->_tc_to_txq = tcp;
+ dev->max_tcs = tcs;
+ return tcs;
+}
+EXPORT_SYMBOL(netdev_alloc_max_tcs);
+
+void netdev_free_tcs(struct net_device *dev)
+{
+ u8 *prio_map = dev->prio_tc_map;
+
+ dev->max_tcs = 0;
+ dev->num_tcs = 0;
+ memset(prio_map, 0, sizeof(*prio_map) * 16);
+ kfree(dev->_tc_to_txq);
+ dev->_tc_to_txq = NULL;
+}
+EXPORT_SYMBOL(netdev_free_tcs);
+
#ifdef CONFIG_RPS
static int netif_alloc_rx_queues(struct net_device *dev)
{
@@ -5695,6 +5733,7 @@ void free_netdev(struct net_device *dev)
#ifdef CONFIG_RPS
kfree(dev->_rx);
#endif
+ netdev_free_tcs(dev);
kfree(rcu_dereference_raw(dev->ingress_queue));
^ permalink raw reply related
* Re: multi bpf filter will impact performance?
From: Eric Dumazet @ 2010-12-01 18:24 UTC (permalink / raw)
To: David Miller; +Cc: hagen, xiaosuo, wirelesser, netdev
In-Reply-To: <20101201.101809.71122121.davem@davemloft.net>
Le mercredi 01 décembre 2010 à 10:18 -0800, David Miller a écrit :
> From: Hagen Paul Pfeifer <hagen@jauu.net>
> Date: Wed, 01 Dec 2010 18:22:48 +0100
>
> > On Wed, 01 Dec 2010 09:42:47 +0100, Eric Dumazet wrote:
> >
> >> IMHO, a better pcap optimizer would be the first step.
> >
> > +1
> >
> > Optimizing complex filter rules is step one in the process of optimizing
> > the packet processing. A JIT compiler like FreeBSD provides cannot polish a
> > (pcap)turd. I thought Patrick was working on a generic filter mechanism for
> > netfilter!? ... ;)
>
> Yes, and we spoke at the netfilter workshop about making that interpreter
> available to socket filters and the packet classifier layer.
>
> However, I think it's still valuable to write a few JIT compilers for
> the existing BPF stuff. I considered working on a sparc64 JIT just to
> see what it would look like.
>
> If people work on the BPF optimizer and BPF JITs in parallel, we'll have
> both ready at the same time. win++
A third work in progress (from my side) is to add a check in
sk_chk_filter() to remove the memvalid we added lately to protect the
LOAD M(K).
It is needed anyway for arches without a BPF JIT :)
^ permalink raw reply
* [RFC PATCH v2 2/3] netlink: implement nla_policy for HW QOS
From: John Fastabend @ 2010-12-01 18:22 UTC (permalink / raw)
To: davem; +Cc: john.r.fastabend, netdev, tgraf, eric.dumazet
In-Reply-To: <20101201182252.2748.15208.stgit@jf-dev1-dcblab>
Implement nla_policy hooks to get/set HW offloaded QOS policies.
The following types are added to RTM_{GET|SET}LINK.
[IFLA_TC]
[IFLA_TC_MAX_TC]
[IFLA_TC_NUM_TC]
[IFLA_TC_TXQS]
[IFLA_TC_TXQ]
...
[IFLA_TC_MAPS]
[IFLA_TC_MAP]
...
The following are read only,
IFLA_TC_MAX_TC
IFLA_TC_TXQS
The IFLA_TC_MAX_TC attribute can only be set by the lower layer drivers
because it is a hardware limit. The IFLA_TC_TXQ_* values provide insight
into how the hardware has aligned the tx queues with traffic classes
but can not be modified.
This adds a net_device ops ndo_set_num_tc() to callback into drivers
to change the number of traffic classes. Lower layer drivers may need to
move resources around or reconfigure HW to support changing number
of traffic classes.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
include/linux/if_link.h | 50 ++++++++++++++++++++++
include/linux/netdevice.h | 4 ++
net/core/rtnetlink.c | 103 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 156 insertions(+), 1 deletions(-)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 6485d2a..ebe13a0 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -135,6 +135,7 @@ enum {
IFLA_VF_PORTS,
IFLA_PORT_SELF,
IFLA_AF_SPEC,
+ IFLA_TC,
__IFLA_MAX
};
@@ -378,4 +379,53 @@ struct ifla_port_vsi {
__u8 pad[3];
};
+/* HW QOS management section
+ *
+ * Nested layout of set/get msg is:
+ *
+ * [IFLA_TC]
+ * [IFLA_TC_MAX_TC]
+ * [IFLA_TC_NUM_TC]
+ * [IFLA_TC_TXQS]
+ * [IFLA_TC_TXQ]
+ * ...
+ * [IFLA_TC_MAPS]
+ * [IFLA_TC_MAP]
+ * ...
+ */
+enum {
+ IFLA_TC_UNSPEC,
+ IFLA_TC_TXMAX,
+ IFLA_TC_TXNUM,
+ IFLA_TC_TXQS,
+ IFLA_TC_MAPS,
+ __IFLA_TC_MAX,
+};
+#define IFLA_TC_MAX (__IFLA_TC_MAX - 1)
+
+struct ifla_tc_txq {
+ __u8 tc;
+ __u16 count;
+ __u16 offset;
+};
+
+enum {
+ IFLA_TC_TXQ_UNSPEC,
+ IFLA_TC_TXQ,
+ __IFLA_TC_TCQ_MAX,
+};
+#define IFLA_TC_TXQS_MAX (__IFLA_TC_TCQ_MAX - 1)
+
+struct ifla_tc_map {
+ __u8 prio;
+ __u8 tc;
+};
+
+enum {
+ IFLA_TC_MAP_UNSPEC,
+ IFLA_TC_MAP,
+ __IFLA_TC_MAP_MAX,
+};
+#define IFLA_TC_MAPS_MAX (__IFLA_TC_TCQ_MAX - 1)
+
#endif /* _LINUX_IF_LINK_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 3307979..c44da29 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -744,6 +744,8 @@ struct netdev_tc_txq {
* int (*ndo_set_vf_port)(struct net_device *dev, int vf,
* struct nlattr *port[]);
* int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);
+ *
+ * int (*ndo_set_num_tc)(struct net_device *dev, int tcs);
*/
#define HAVE_NET_DEVICE_OPS
struct net_device_ops {
@@ -802,6 +804,8 @@ struct net_device_ops {
struct nlattr *port[]);
int (*ndo_get_vf_port)(struct net_device *dev,
int vf, struct sk_buff *skb);
+ int (*ndo_set_num_tc)(struct net_device *dev,
+ u8 tcs);
#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
int (*ndo_fcoe_enable)(struct net_device *dev);
int (*ndo_fcoe_disable)(struct net_device *dev);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 750db57..12bdff5 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -739,6 +739,21 @@ static size_t rtnl_port_size(const struct net_device *dev)
return port_self_size;
}
+static size_t rtnl_tc_size(const struct net_device *dev)
+{
+ u8 num_tcs = netdev_get_num_tc(dev);
+ size_t table_size = nla_total_size(8) /* IFLA_TC_TXMAX */
+ + nla_total_size(8); /* IFLA_TC_TXNUM */
+
+ table_size += nla_total_size(sizeof(struct nlattr));
+ table_size += num_tcs * nla_total_size(sizeof(struct ifla_tc_txq));
+
+ table_size += nla_total_size(sizeof(struct nlattr));
+ table_size += 16 * nla_total_size(sizeof(struct ifla_tc_map));
+
+ return table_size;
+}
+
static noinline size_t if_nlmsg_size(const struct net_device *dev)
{
return NLMSG_ALIGN(sizeof(struct ifinfomsg))
@@ -761,7 +776,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev)
+ rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */
+ rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
+ rtnl_link_get_size(dev) /* IFLA_LINKINFO */
- + rtnl_link_get_af_size(dev); /* IFLA_AF_SPEC */
+ + rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */
+ + rtnl_tc_size(dev); /* IFLA_TC */
}
static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
@@ -952,6 +968,41 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
if (rtnl_port_fill(skb, dev))
goto nla_put_failure;
+ if (dev->max_tcs) {
+ struct nlattr *tc_tbl, *tc_txq, *tc_map;
+ struct netdev_tc_txq *tcq;
+ struct ifla_tc_txq ifla_tcq;
+ struct ifla_tc_map ifla_map;
+ u8 i;
+
+ tc_tbl = nla_nest_start(skb, IFLA_TC);
+ if (!tc_tbl)
+ goto nla_put_failure;
+
+ NLA_PUT_U8(skb, IFLA_TC_TXMAX, dev->max_tcs);
+ NLA_PUT_U8(skb, IFLA_TC_TXNUM, dev->num_tcs);
+
+ tc_txq = nla_nest_start(skb, IFLA_TC_TXQS);
+ for (i = 0; i < dev->num_tcs; i++) {
+ tcq = netdev_get_tc_queue(dev, i);
+ ifla_tcq.tc = i;
+ ifla_tcq.count = tcq->count;
+ ifla_tcq.offset = tcq->offset;
+
+ NLA_PUT(skb, IFLA_TC_TXQ, sizeof(ifla_tcq), &ifla_tcq);
+ }
+ nla_nest_end(skb, tc_txq);
+
+ tc_map = nla_nest_start(skb, IFLA_TC_MAPS);
+ for (i = 0; i < 16; i++) {
+ ifla_map.prio = i;
+ ifla_map.tc = netdev_get_prio_tc_map(dev, i);
+ NLA_PUT(skb, IFLA_TC_MAP, sizeof(ifla_map), &ifla_map);
+ }
+ nla_nest_end(skb, tc_map);
+ nla_nest_end(skb, tc_tbl);
+ }
+
if (dev->rtnl_link_ops) {
if (rtnl_link_fill(skb, dev) < 0)
goto nla_put_failure;
@@ -1046,6 +1097,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_VF_PORTS] = { .type = NLA_NESTED },
[IFLA_PORT_SELF] = { .type = NLA_NESTED },
[IFLA_AF_SPEC] = { .type = NLA_NESTED },
+ [IFLA_TC] = { .type = NLA_NESTED },
};
EXPORT_SYMBOL(ifla_policy);
@@ -1081,6 +1133,23 @@ static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = {
[IFLA_PORT_RESPONSE] = { .type = NLA_U16, },
};
+static const struct nla_policy ifla_tc_policy[IFLA_TC_MAX+1] = {
+ [IFLA_TC_TXMAX] = { .type = NLA_U8 },
+ [IFLA_TC_TXNUM] = { .type = NLA_U8 },
+ [IFLA_TC_TXQS] = { .type = NLA_NESTED },
+ [IFLA_TC_MAPS] = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy ifla_tc_txq[IFLA_TC_TXQS_MAX+1] = {
+ [IFLA_TC_TXQ] = { .type = NLA_BINARY,
+ .len = sizeof(struct ifla_tc_txq)},
+};
+
+static const struct nla_policy ifla_tc_map[IFLA_TC_MAPS_MAX+1] = {
+ [IFLA_TC_MAP] = { .type = NLA_BINARY,
+ .len = sizeof(struct ifla_tc_map)},
+};
+
struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
{
struct net *net;
@@ -1389,6 +1458,38 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
}
err = 0;
+ if (tb[IFLA_TC]) {
+ struct nlattr *table[IFLA_TC_MAX+1];
+ struct nlattr *tc_maps;
+ int rem;
+
+ err = nla_parse_nested(table, IFLA_TC_MAX, tb[IFLA_TC],
+ ifla_tc_policy);
+ if (err < 0)
+ goto errout;
+
+ if (table[IFLA_TC_TXNUM]) {
+ u8 tcs = nla_get_u8(table[IFLA_TC_TXNUM]);
+ err = -EOPNOTSUPP;
+ if (ops->ndo_set_num_tc)
+ err = ops->ndo_set_num_tc(dev, tcs);
+ if (err < 0)
+ goto errout;
+ }
+
+ if (table[IFLA_TC_MAPS]) {
+ nla_for_each_nested(tc_maps, table[IFLA_TC_MAPS], rem) {
+ struct ifla_tc_map *map;
+ map = nla_data(tc_maps);
+ err = netdev_set_prio_tc_map(dev, map->prio,
+ map->tc);
+ if (err < 0)
+ goto errout;
+ }
+ }
+ }
+ err = 0;
+
errout:
if (err < 0 && modified && net_ratelimit())
printk(KERN_WARNING "A link change request failed with "
^ permalink raw reply related
* Re: [PATCH] bonding: check for assigned mac before adopting the slaves mac address
From: David Strand @ 2010-12-01 18:25 UTC (permalink / raw)
To: Jay Vosburgh; +Cc: netdev, linux-kernel
In-Reply-To: <8879.1290741991@death>
On Thu, Nov 25, 2010 at 7:26 PM, Jay Vosburgh <fubar@us.ibm.com> wrote:
>
> Ok, fair enough. If we want to get back to the original
> behavior, however, your patch should only test for zero MAC address
> instead of testing for zero MAC address in addition to first slave.
>
> -J
>
> ---
> -Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
>
Understood, that makes sense. The updated patch is below.
---
diff -uprN a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c 2010-11-24 11:36:58.125640000 -0800
+++ b/drivers/net/bonding/bond_main.c 2010-12-01 10:12:33.728640001 -0800
@@ -1576,7 +1576,7 @@ int bond_enslave(struct net_device *bond
/* If this is the first slave, then we need to set the master's hardware
* address to be the same as the slave's. */
- if (bond->slave_cnt == 0)
+ if (is_zero_ether_addr(bond->dev->dev_addr))
memcpy(bond->dev->dev_addr, slave_dev->dev_addr,
slave_dev->addr_len);
^ permalink raw reply
* [RFC PATCH v2 3/3] ixgbe: add multiple txqs per tc
From: John Fastabend @ 2010-12-01 18:23 UTC (permalink / raw)
To: davem; +Cc: john.r.fastabend, netdev, tgraf, eric.dumazet
In-Reply-To: <20101201182252.2748.15208.stgit@jf-dev1-dcblab>
This is sample code to illustrate the usage model for hardware
QOS offloading. It needs some polishing, but should be good
enough to illustrate how the API can be used.
Currently, DCB only enables a single queue per tc. Due to
complications with how to map tc filter rules to traffic classes
when multiple queues are enabled. And previously there was no
mechanism to map flows to multiple queues by priority.
Using the QOS offloading API we allocate multiple queues per
tc and configure the stack to hash across these queues. The
hardware then offloads the DCB extended transmission selection
algorithm. Sockets can set the priority using the SO_PRIORITY
socket option and expect ETS to work.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/ixgbe/ixgbe.h | 2
drivers/net/ixgbe/ixgbe_dcb_nl.c | 3
drivers/net/ixgbe/ixgbe_main.c | 264 +++++++++++++++++++-------------------
3 files changed, 134 insertions(+), 135 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 3ae30b8..860b1fa 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -243,7 +243,7 @@ enum ixgbe_ring_f_enum {
RING_F_ARRAY_SIZE /* must be last in enum set */
};
-#define IXGBE_MAX_DCB_INDICES 8
+#define IXGBE_MAX_DCB_INDICES 64
#define IXGBE_MAX_RSS_INDICES 16
#define IXGBE_MAX_VMDQ_INDICES 64
#define IXGBE_MAX_FDIR_INDICES 64
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index bf566e8..8e203ae 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -155,6 +155,7 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
if (netif_running(netdev))
netdev->netdev_ops->ndo_stop(netdev);
ixgbe_clear_interrupt_scheme(adapter);
+ netdev_set_num_tc(adapter->netdev, 0);
adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
adapter->temp_dcb_cfg.pfc_mode_enable = false;
@@ -359,7 +360,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
return DCB_NO_HW_CHG;
ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
- adapter->ring_feature[RING_F_DCB].indices);
+ netdev->num_tcs);
if (ret)
return DCB_NO_HW_CHG;
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 494cb57..1517e5c 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -634,6 +634,18 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring,
/* tx_buffer_info must be completely set up in the transmit path */
}
+int ixgbe_set_num_tc(struct net_device *dev, u8 tcs)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+ int err = 0;
+
+ /* Do not allow change while DCB controlled */
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
+ return -EINVAL;
+
+ return netdev_set_num_tc(dev, tcs);
+}
+
/**
* ixgbe_dcb_txq_to_tc - convert a reg index to a traffic class
* @adapter: driver private struct
@@ -647,7 +659,7 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring,
u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx)
{
int tc = -1;
- int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
+ u8 num_tcs = netdev_get_num_tc(adapter->netdev);
/* if DCB is not enabled the queues have no TC */
if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
@@ -662,13 +674,13 @@ u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx)
tc = reg_idx >> 2;
break;
default:
- if (dcb_i != 4 && dcb_i != 8)
+ if (num_tcs != 4 && num_tcs != 8)
break;
/* if VMDq is enabled the lowest order bits determine TC */
if (adapter->flags & (IXGBE_FLAG_SRIOV_ENABLED |
IXGBE_FLAG_VMDQ_ENABLED)) {
- tc = reg_idx & (dcb_i - 1);
+ tc = reg_idx & (num_tcs - 1);
break;
}
@@ -681,9 +693,9 @@ u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx)
* will only ever be 8 or 4 and that reg_idx will never
* be greater then 128. The code without the power of 2
* optimizations would be:
- * (((reg_idx % 32) + 32) * dcb_i) >> (9 - reg_idx / 32)
+ * (((reg_idx % 32) + 32) * num_tcs) >> (9 - reg_idx / 32)
*/
- tc = ((reg_idx & 0X1F) + 0x20) * dcb_i;
+ tc = ((reg_idx & 0X1F) + 0x20) * num_tcs;
tc >>= 9 - (reg_idx >> 5);
}
@@ -4190,14 +4202,29 @@ static void ixgbe_reset_task(struct work_struct *work)
}
#ifdef CONFIG_IXGBE_DCB
+#define MAX_Q_PER_TC 8
+
static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter)
{
bool ret = false;
struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_DCB];
+ int num_tcs;
+ int i, q;
if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
return ret;
+ num_tcs = 8;
+ netdev_set_num_tc(adapter->netdev, num_tcs);
+
+ f->indices = 0;
+ for (i = 0; i < num_tcs; i++) {
+ q = min((int)num_online_cpus(), MAX_Q_PER_TC);
+ netdev_set_prio_tc_map(adapter->netdev, i, i);
+ netdev_set_tc_queue(adapter->netdev, i, q, f->indices);
+ f->indices += q;
+ }
+
f->mask = 0x7 << 3;
adapter->num_rx_queues = f->indices;
adapter->num_tx_queues = f->indices;
@@ -4284,12 +4311,7 @@ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter)
if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
adapter->num_rx_queues = 1;
adapter->num_tx_queues = 1;
-#ifdef CONFIG_IXGBE_DCB
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- e_info(probe, "FCoE enabled with DCB\n");
- ixgbe_set_dcb_queues(adapter);
- }
-#endif
+
if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
e_info(probe, "FCoE enabled with RSS\n");
if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) ||
@@ -4345,16 +4367,15 @@ static int ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
if (ixgbe_set_sriov_queues(adapter))
goto done;
-#ifdef IXGBE_FCOE
- if (ixgbe_set_fcoe_queues(adapter))
- goto done;
-
-#endif /* IXGBE_FCOE */
#ifdef CONFIG_IXGBE_DCB
if (ixgbe_set_dcb_queues(adapter))
goto done;
-
#endif
+
+#ifdef IXGBE_FCOE
+ if (ixgbe_set_fcoe_queues(adapter))
+ goto done;
+#endif /* IXGBE_FCOE */
if (ixgbe_set_fdir_queues(adapter))
goto done;
@@ -4446,6 +4467,63 @@ static inline bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter)
}
#ifdef CONFIG_IXGBE_DCB
+
+ /* ixgbe_get_first_reg_idx - Return first register index associated
+ * with this traffic class
+ */
+void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc,
+ unsigned int *tx, unsigned int *rx)
+{
+ struct net_device *dev = adapter->netdev;
+ struct ixgbe_hw *hw = &adapter->hw;
+ u8 num_tcs = netdev_get_num_tc(dev);
+
+ *tx = 0;
+ *rx = 0;
+
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
+ *tx = tc << 3;
+ *rx = tc << 2;
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ if (num_tcs == 8) {
+ if (tc < 3) {
+ *tx = tc << 5;
+ *rx = tc << 4;
+ } else if (tc < 5) {
+ *tx = ((tc + 2) << 4);
+ *rx = tc << 4;
+ } else if (tc < num_tcs) {
+ *tx = ((tc + 8) << 3);
+ *rx = tc << 4;
+ }
+ } else if (num_tcs == 4) {
+ *rx = tc << 5;
+ switch (tc) {
+ case 0:
+ *tx = 0;
+ break;
+ case 1:
+ *tx = 64;
+ break;
+ case 2:
+ *tx = 96;
+ break;
+ case 3:
+ *tx = 112;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
/**
* ixgbe_cache_ring_dcb - Descriptor ring to register mapping for DCB
* @adapter: board private structure to initialize
@@ -4455,72 +4533,26 @@ static inline bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter)
**/
static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter)
{
- int i;
- bool ret = false;
- int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
+ struct net_device *dev = adapter->netdev;
+ int i, j, k;
+ u8 num_tcs = netdev_get_num_tc(dev);
+ unsigned int tx_s, rx_s;
if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
return false;
/* the number of queues is assumed to be symmetric */
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82598EB:
- for (i = 0; i < dcb_i; i++) {
- adapter->rx_ring[i]->reg_idx = i << 3;
- adapter->tx_ring[i]->reg_idx = i << 2;
+ for (i = 0, k = 0; i < num_tcs; i++) {
+ struct netdev_tc_txq *tcp = netdev_get_tc_queue(dev, i);
+ u16 qcount = tcp->count;
+ ixgbe_get_first_reg_idx(adapter, i, &tx_s, &rx_s);
+ for (j = 0; j < qcount; j++, k++) {
+ adapter->tx_ring[k]->reg_idx = tx_s + j;
+ adapter->rx_ring[k]->reg_idx = rx_s + j;
}
- ret = true;
- break;
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- if (dcb_i == 8) {
- /*
- * Tx TC0 starts at: descriptor queue 0
- * Tx TC1 starts at: descriptor queue 32
- * Tx TC2 starts at: descriptor queue 64
- * Tx TC3 starts at: descriptor queue 80
- * Tx TC4 starts at: descriptor queue 96
- * Tx TC5 starts at: descriptor queue 104
- * Tx TC6 starts at: descriptor queue 112
- * Tx TC7 starts at: descriptor queue 120
- *
- * Rx TC0-TC7 are offset by 16 queues each
- */
- for (i = 0; i < 3; i++) {
- adapter->tx_ring[i]->reg_idx = i << 5;
- adapter->rx_ring[i]->reg_idx = i << 4;
- }
- for ( ; i < 5; i++) {
- adapter->tx_ring[i]->reg_idx = ((i + 2) << 4);
- adapter->rx_ring[i]->reg_idx = i << 4;
- }
- for ( ; i < dcb_i; i++) {
- adapter->tx_ring[i]->reg_idx = ((i + 8) << 3);
- adapter->rx_ring[i]->reg_idx = i << 4;
- }
- ret = true;
- } else if (dcb_i == 4) {
- /*
- * Tx TC0 starts at: descriptor queue 0
- * Tx TC1 starts at: descriptor queue 64
- * Tx TC2 starts at: descriptor queue 96
- * Tx TC3 starts at: descriptor queue 112
- *
- * Rx TC0-TC3 are offset by 32 queues each
- */
- adapter->tx_ring[0]->reg_idx = 0;
- adapter->tx_ring[1]->reg_idx = 64;
- adapter->tx_ring[2]->reg_idx = 96;
- adapter->tx_ring[3]->reg_idx = 112;
- for (i = 0 ; i < dcb_i; i++)
- adapter->rx_ring[i]->reg_idx = i << 5;
- ret = true;
- }
- break;
- default:
- break;
}
- return ret;
+
+ return true;
}
#endif
@@ -4648,17 +4680,15 @@ static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
if (ixgbe_cache_ring_sriov(adapter))
return;
-
+#ifdef CONFIG_IXGBE_DCB
+ if (ixgbe_cache_ring_dcb(adapter))
+ return;
+#endif /* IXGBE_DCB */
#ifdef IXGBE_FCOE
if (ixgbe_cache_ring_fcoe(adapter))
return;
#endif /* IXGBE_FCOE */
-#ifdef CONFIG_IXGBE_DCB
- if (ixgbe_cache_ring_dcb(adapter))
- return;
-
-#endif
if (ixgbe_cache_ring_fdir(adapter))
return;
@@ -5122,7 +5152,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->dcb_cfg.round_robin_enable = false;
adapter->dcb_set_bitmap = 0x00;
ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg,
- adapter->ring_feature[RING_F_DCB].indices);
+ dev->max_tcs);
#endif
@@ -5975,7 +6005,7 @@ static void ixgbe_watchdog_task(struct work_struct *work)
if (link_up) {
#ifdef CONFIG_DCB
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+ for (i = 0; i < netdev->max_tcs; i++)
hw->mac.ops.fc_enable(hw, i);
} else {
hw->mac.ops.fc_enable(hw, 0);
@@ -6500,25 +6530,6 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
int txq = smp_processor_id();
-#ifdef IXGBE_FCOE
- __be16 protocol;
-
- protocol = vlan_get_protocol(skb);
-
- if ((protocol == htons(ETH_P_FCOE)) ||
- (protocol == htons(ETH_P_FIP))) {
- if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
- txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1);
- txq += adapter->ring_feature[RING_F_FCOE].mask;
- return txq;
-#ifdef CONFIG_IXGBE_DCB
- } else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- txq = adapter->fcoe.up;
- return txq;
-#endif
- }
- }
-#endif
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) {
while (unlikely(txq >= dev->real_num_tx_queues))
@@ -6526,14 +6537,20 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
return txq;
}
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- if (skb->priority == TC_PRIO_CONTROL)
- txq = adapter->ring_feature[RING_F_DCB].indices-1;
- else
- txq = (skb->vlan_tci & IXGBE_TX_FLAGS_VLAN_PRIO_MASK)
- >> 13;
+#ifdef IXGBE_FCOE
+ /*
+ * If DCB is not enabled to assign FCoE a priority mapping
+ * we need to steer the skb to FCoE enabled tx rings.
+ */
+ if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
+ !(adapter->flags & IXGBE_FLAG_DCB_ENABLED) &&
+ ((skb->protocol == htons(ETH_P_FCOE)) ||
+ (skb->protocol == htons(ETH_P_FIP)))) {
+ txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1);
+ txq += adapter->ring_feature[RING_F_FCOE].mask;
return txq;
}
+#endif
return skb_tx_hash(dev, skb);
}
@@ -6556,33 +6573,12 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
if (vlan_tx_tag_present(skb)) {
tx_flags |= vlan_tx_tag_get(skb);
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- tx_flags &= ~IXGBE_TX_FLAGS_VLAN_PRIO_MASK;
- tx_flags |= ((skb->queue_mapping & 0x7) << 13);
- }
- tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
- tx_flags |= IXGBE_TX_FLAGS_VLAN;
- } else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED &&
- skb->priority != TC_PRIO_CONTROL) {
- tx_flags |= ((skb->queue_mapping & 0x7) << 13);
tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
tx_flags |= IXGBE_TX_FLAGS_VLAN;
}
#ifdef IXGBE_FCOE
- /* for FCoE with DCB, we force the priority to what
- * was specified by the switch */
- if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED &&
- (protocol == htons(ETH_P_FCOE) ||
- protocol == htons(ETH_P_FIP))) {
-#ifdef CONFIG_IXGBE_DCB
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK
- << IXGBE_TX_FLAGS_VLAN_SHIFT);
- tx_flags |= ((adapter->fcoe.up << 13)
- << IXGBE_TX_FLAGS_VLAN_SHIFT);
- }
-#endif
+ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
/* flag for FCoE offloads */
if (protocol == htons(ETH_P_FCOE))
tx_flags |= IXGBE_TX_FLAGS_FCOE;
@@ -6856,6 +6852,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_set_vf_tx_rate = ixgbe_ndo_set_vf_bw,
.ndo_get_vf_config = ixgbe_ndo_get_vf_config,
.ndo_get_stats64 = ixgbe_get_stats64,
+ .ndo_set_num_tc = ixgbe_set_num_tc,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ixgbe_netpoll,
#endif
@@ -6994,9 +6991,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
indices = min_t(unsigned int, indices, IXGBE_MAX_RSS_INDICES);
else
indices = min_t(unsigned int, indices, IXGBE_MAX_FDIR_INDICES);
-
+#if defined(CONFIG_IXGBE_DCB)
indices = max_t(unsigned int, indices, IXGBE_MAX_DCB_INDICES);
-#ifdef IXGBE_FCOE
+#elif defined(IXGBE_FCOE)
indices += min_t(unsigned int, num_possible_cpus(),
IXGBE_MAX_FCOE_INDICES);
#endif
@@ -7157,6 +7154,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
#ifdef CONFIG_IXGBE_DCB
netdev->dcbnl_ops = &dcbnl_ops;
+ netdev_alloc_max_tcs(netdev, MAX_TRAFFIC_CLASS);
#endif
#ifdef IXGBE_FCOE
^ permalink raw reply related
* [RFC PATCH v1] iproute2: add IFLA_TC support to 'ip link'
From: John Fastabend @ 2010-12-01 18:27 UTC (permalink / raw)
To: shemminger; +Cc: netdev, tgraf, eric.dumazet, davem, john.r.fastabend
Add support to return IFLA_TC qos settings to the 'ip link'
command. The following sets the number of traffic classes
supported in HW and builds a priority map.
#ip link set eth3 tc num 8 map 0 1 2 3 4 5 6 7 0 0 0 0 0 0 0 0
With the output from 'ip link' showing maps for interfaces with
the ability to use HW traffic classes.
#ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 00:30:48:f0:fc:88 brdff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:30:48:f0:fc:89 brdff:ff:ff:ff:ff:ff
6: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN qlen 1000
link/ether 00:1b:21:55:23:58 brdff:ff:ff:ff:ff:ff
tc 0:8
7: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:1b:21:55:23:59 brdff:ff:ff:ff:ff:ff
tc 8:8 map: { 0 1 2 3 4 5 6 7 0 0 0 0 0 0 0 0 }
txqs: (0:8) (8:16) (16:24) (24:32) (32:40) (40:48) (48:56) (56:64)
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
include/linux/if_link.h | 51 ++++++++++++++++++++++++++++++++++++++
ip/ipaddress.c | 48 ++++++++++++++++++++++++++++++++++--
ip/iplink.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 160 insertions(+), 2 deletions(-)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index f5bb2dc..190c70d 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -116,6 +116,8 @@ enum {
IFLA_STATS64,
IFLA_VF_PORTS,
IFLA_PORT_SELF,
+ IFLA_AF_SPEC,
+ IFLA_TC,
__IFLA_MAX
};
@@ -348,4 +350,53 @@ struct ifla_port_vsi {
__u8 pad[3];
};
+/* HW QOS management section
+ *
+ * Nested layout of set/get msg is:
+ *
+ * [IFLA_TC]
+ * [IFLA_TC_MAX_TC]
+ * [IFLA_TC_NUM_TC]
+ * [IFLA_TC_TXQS]
+ * [IFLA_TC_TXQ]
+ * ...
+ * [IFLA_TC_MAPS]
+ * [IFLA_TC_MAP]
+ * ...
+ */
+enum {
+ IFLA_TC_UNSPEC,
+ IFLA_TC_TXMAX,
+ IFLA_TC_TXNUM,
+ IFLA_TC_TXQS,
+ IFLA_TC_MAPS,
+ __IFLA_TC_MAX,
+};
+#define IFLA_TC_MAX (__IFLA_TC_MAX - 1)
+
+struct ifla_tc_txq {
+ __u8 num;
+ __u16 count;
+ __u16 offset;
+};
+
+enum {
+ IFLA_TC_TXQ_UNSPEC,
+ IFLA_TC_TXQ,
+ __IFLA_TC_TCQ_MAX,
+};
+#define IFLA_TC_TXQS_MAX (__IFLA_TC_TCQ_MAX - 1)
+
+struct ifla_tc_map {
+ __u8 prio;
+ __u8 tc;
+};
+
+enum {
+ IFLA_TC_MAP_UNSPEC,
+ IFLA_TC_MAP,
+ __IFLA_TC_MAP_MAX,
+};
+#define IFLA_TC_MAP_MAX (__IFLA_TC_MAP_MAX - 1)
+
#endif /* _LINUX_IF_LINK_H */
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 19b3d6e..39b357f 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -152,6 +152,47 @@ static void print_queuelen(FILE *f, const char *name)
fprintf(f, "qlen %d", ifr.ifr_qlen);
}
+static void print_tc_table(FILE *fp, struct rtattr *tb)
+{
+ struct rtattr *table[IFLA_TC_MAX+1];
+ struct rtattr *attr;
+ struct ifla_tc_map *map;
+ struct ifla_tc_txq *txq;
+ __u8 max, num;
+ int rem;
+
+ parse_rtattr_nested(table, IFLA_TC_MAX, tb);
+
+ if (table[IFLA_TC_MAX])
+ max = * (__u8 *) RTA_DATA(table[IFLA_TC_TXMAX]);
+ if (table[IFLA_TC_MAX])
+ num = * (__u8 *) RTA_DATA(table[IFLA_TC_TXNUM]);
+
+
+ fprintf(fp, "\n tc %d:%d ", num, max);
+
+ if (!num)
+ return;
+
+ rem = RTA_PAYLOAD(table[IFLA_TC_MAPS]);
+ attr = RTA_DATA(table[IFLA_TC_MAPS]);
+ fprintf(fp, "map: {");
+ for (; RTA_OK(attr, rem); attr = RTA_NEXT(attr, rem)) {
+ map = RTA_DATA(attr);
+ fprintf(fp, " %d", map->tc);
+ }
+ fprintf(fp, " }");
+
+ rem = RTA_PAYLOAD(table[IFLA_TC_TXQS]);
+ attr = RTA_DATA(table[IFLA_TC_TXQS]);
+ fprintf(fp, "\n txqs: ");
+ for (; RTA_OK(attr, rem); attr = RTA_NEXT(attr, rem)) {
+ txq = RTA_DATA(attr);
+ fprintf(fp, "(%d:%d) ",
+ txq->offset, txq->offset + txq->count);
+ }
+}
+
static void print_linktype(FILE *fp, struct rtattr *tb)
{
struct rtattr *linkinfo[IFLA_INFO_MAX+1];
@@ -299,8 +340,8 @@ int print_linkinfo(const struct sockaddr_nl *who,
if (ifi->ifi_flags&IFF_POINTOPOINT)
fprintf(fp, " peer ");
else
- fprintf(fp, " brd ");
- fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
+ fprintf(fp, " brd");
+ fprintf(fp, "%s ", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
RTA_PAYLOAD(tb[IFLA_BROADCAST]),
ifi->ifi_type,
b1, sizeof(b1)));
@@ -421,6 +462,9 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_vfinfo(fp, i);
}
+ if (tb[IFLA_TC])
+ print_tc_table(fp, tb[IFLA_TC]);
+
fprintf(fp, "\n");
fflush(fp);
return 0;
diff --git a/ip/iplink.c b/ip/iplink.c
index cb2c4f5..fa9236e 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -71,6 +71,8 @@ void iplink_usage(void)
fprintf(stderr, " [ vf NUM [ mac LLADDR ]\n");
fprintf(stderr, " [ vlan VLANID [ qos VLAN-QOS ] ]\n");
fprintf(stderr, " [ rate TXRATE ] ] \n");
+ fprintf(stderr, " [ tc [ num NUMTC ]\n");
+ fprintf(stderr, " [ map PRIO1 PRIO2 ... ] ]\n");
fprintf(stderr, " ip link show [ DEVICE ]\n");
if (iplink_have_newlink()) {
@@ -242,6 +244,58 @@ int iplink_parse_vf(int vf, int *argcp, char ***argvp,
return 0;
}
+int iplink_parse_tc(int *argcp, char ***argvp, struct iplink_req *req)
+{
+ int argc = *argcp;
+ char **argv = *argvp;
+
+ while (NEXT_ARG_OK()) {
+ NEXT_ARG();
+ if (matches(*argv, "num") == 0) {
+ __u8 numtc;
+ NEXT_ARG();
+ if (get_u8(&numtc, *argv, 0))
+ invarg("Invalid \"num\" value\n", *argv);
+ addattr_l(&req->n, sizeof(*req), IFLA_TC_TXNUM,
+ &numtc, 1);
+ }
+
+ if (matches(*argv, "map") == 0) {
+ struct ifla_tc_map map;
+ struct rtattr *maps;
+ int i;
+
+ maps = addattr_nest(&req->n, sizeof(*req),
+ IFLA_TC_MAPS);
+
+ for (i = 0; NEXT_ARG_OK(); i++) {
+ NEXT_ARG();
+ if (i > 15)
+ invarg("\"map\" value exceeds "
+ "prio map\n", *argv);
+ map.prio = i;
+ if (get_u8(&map.tc, *argv, 0))
+ invarg("Invalid \"map\" value\n", *argv);
+
+ if (map.tc > 15)
+ invarg("\"map\" value exceeds max tc",
+ *argv);
+
+ addattr_l(&req->n, sizeof(*req), IFLA_TC_MAP,
+ &map, sizeof(map));
+ }
+
+ addattr_nest_end(&req->n, maps);
+ }
+ }
+
+ if (argc == *argcp)
+ incomplete_command();
+ *argcp = argc;
+ *argvp = argv;
+ return 0;
+}
+
int iplink_parse(int argc, char **argv, struct iplink_req *req,
char **name, char **type, char **link, char **dev)
@@ -361,6 +415,15 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
if (len < 0)
return -1;
addattr_nest_end(&req->n, vflist);
+ } else if (strcmp(*argv, "tc") == 0) {
+ struct rtattr *table;
+
+ table = addattr_nest(&req->n, sizeof(*req),
+ IFLA_TC);
+ len = iplink_parse_tc(&argc, &argv, req);
+ if (len < 0)
+ return -1;
+ addattr_nest_end(&req->n, table);
#ifdef IFF_DYNAMIC
} else if (matches(*argv, "dynamic") == 0) {
NEXT_ARG();
^ permalink raw reply related
* Re: [RFC PATCH v1] iproute2: add IFLA_TC support to 'ip link'
From: Stephen Hemminger @ 2010-12-01 18:38 UTC (permalink / raw)
To: John Fastabend; +Cc: netdev, tgraf, eric.dumazet, davem
In-Reply-To: <20101201182758.3297.34345.stgit@jf-dev1-dcblab>
On Wed, 01 Dec 2010 10:27:58 -0800
John Fastabend <john.r.fastabend@intel.com> wrote:
> Add support to return IFLA_TC qos settings to the 'ip link'
> command. The following sets the number of traffic classes
> supported in HW and builds a priority map.
>
> #ip link set eth3 tc num 8 map 0 1 2 3 4 5 6 7 0 0 0 0 0 0 0 0
>
> With the output from 'ip link' showing maps for interfaces with
> the ability to use HW traffic classes.
>
> #ip link show
> 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
> link/loopback 00:00:00:00:00:00 brd00:00:00:00:00:00
> 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
> link/ether 00:30:48:f0:fc:88 brdff:ff:ff:ff:ff:ff
> 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
> link/ether 00:30:48:f0:fc:89 brdff:ff:ff:ff:ff:ff
> 6: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN qlen 1000
> link/ether 00:1b:21:55:23:58 brdff:ff:ff:ff:ff:ff
> tc 0:8
> 7: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
> link/ether 00:1b:21:55:23:59 brdff:ff:ff:ff:ff:ff
> tc 8:8 map: { 0 1 2 3 4 5 6 7 0 0 0 0 0 0 0 0 }
> txqs: (0:8) (8:16) (16:24) (24:32) (32:40) (40:48) (48:56) (56:64)
>
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Ok. but will not be applied until after 2.6.38 (when kernel support
is upstream).
--
^ permalink raw reply
* Re: [PATCHv6] net: Add batman-adv meshing protocol
From: David Miller @ 2010-12-01 18:43 UTC (permalink / raw)
To: sven.eckelmann; +Cc: netdev, b.a.t.m.a.n
In-Reply-To: <1289136377-18350-1-git-send-email-sven.eckelmann@gmx.de>
From: Sven Eckelmann <sven.eckelmann@gmx.de>
Date: Sun, 7 Nov 2010 14:26:17 +0100
> + if (seq_bits[word_num] & 1 << word_offset)
...
> + seq_bits[word_num] |= 1 << word_offset; /* turn the position on */
...
> +#define TYPE_OF_WORD unsigned long
"1" is an 'int' and won't get promoted to unsigned long which means
this code won't work on 64-bit, you need to explicitly say "1UL".
This seems to duplicate a lot of existing functionality, we have
properly bit set/clear/change/test routines, that operate on
"unsigned long" just as your code does.
And since you don't use the existing facilities, you end up with
bugs like this one. Bug which are completely unnecessary.
The badman-adv code is full of duplicated functionality, and until
all of these cases are cured I refuse to integrate this code. I
already complained about the hashing stuff, and now there's this
stuff too.
Every time I review the batman-adv code I find a bug, and the bug is
often in facilities which the kernel has already and are being
duplicated. That is by definition a waste of my and everyone else's
time.
Probably your submission will be almost half the size that it is
currently once you take care of this issue. :-)
^ permalink raw reply
* Re: multi bpf filter will impact performance?
From: David Miller @ 2010-12-01 18:44 UTC (permalink / raw)
To: eric.dumazet; +Cc: hagen, xiaosuo, wirelesser, netdev
In-Reply-To: <1291227893.2856.1039.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 01 Dec 2010 19:24:53 +0100
> A third work in progress (from my side) is to add a check in
> sk_chk_filter() to remove the memvalid we added lately to protect the
> LOAD M(K).
I understand your idea, but the static checkers are still going to
complain. So better add a huge comment in sk_run_filter() explaining
why the checker's complaint should be ignored :-)
^ permalink raw reply
* Re: [PATCH] bonding: check for assigned mac before adopting the slaves mac address
From: David Miller @ 2010-12-01 18:45 UTC (permalink / raw)
To: dpstrand; +Cc: fubar, netdev, linux-kernel
In-Reply-To: <AANLkTi=+jMkrgNjVQvOOn_zURiJ4rXu5LL9eA4o0T9db@mail.gmail.com>
From: David Strand <dpstrand@gmail.com>
Date: Wed, 1 Dec 2010 10:25:19 -0800
> On Thu, Nov 25, 2010 at 7:26 PM, Jay Vosburgh <fubar@us.ibm.com> wrote:
>>
>> Ok, fair enough. If we want to get back to the original
>> behavior, however, your patch should only test for zero MAC address
>> instead of testing for zero MAC address in addition to first slave.
>>
>> -J
>>
>> ---
>> -Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
>>
>
> Understood, that makes sense. The updated patch is below.
You need to provide a fresh posting of your patch, with a full
commit messag and proper Subject: line, as well as a proper
"Signed-off-by: " tag.
See Documentation/SubmittingPatches
^ permalink raw reply
* Re: [RFC PATCH v1] iproute2: add IFLA_TC support to 'ip link'
From: David Miller @ 2010-12-01 18:48 UTC (permalink / raw)
To: shemminger; +Cc: john.r.fastabend, netdev, tgraf, eric.dumazet
In-Reply-To: <20101201103802.11464029@nehalam>
From: Stephen Hemminger <shemminger@vyatta.com>
Date: Wed, 1 Dec 2010 10:38:02 -0800
> Ok. but will not be applied until after 2.6.38 (when kernel support
> is upstream).
Speaking of which, Stephen could you please process the iproute2 patches
which have been rotting in the patchwork queue since... May?!
Just reject them if you don't plan to apply them. Letting them just sit
around there for half a year bothers me (and patch submitters) a lot.
^ permalink raw reply
* Re: [PATCHv6] net: Add batman-adv meshing protocol
From: Sven Eckelmann @ 2010-12-01 18:54 UTC (permalink / raw)
To: David Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
In-Reply-To: <20101201.104314.112592938.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
[-- Attachment #1: Type: Text/Plain, Size: 1219 bytes --]
David Miller wrote:
> From: Sven Eckelmann <sven.eckelmann-Mmb7MZpHnFY@public.gmane.org>
> Date: Sun, 7 Nov 2010 14:26:17 +0100
>
> > + if (seq_bits[word_num] & 1 << word_offset)
>
> ...
>
> > + seq_bits[word_num] |= 1 << word_offset; /* turn the position on */
>
> ...
>
> > +#define TYPE_OF_WORD unsigned long
>
> "1" is an 'int' and won't get promoted to unsigned long which means
> this code won't work on 64-bit, you need to explicitly say "1UL".
Thanks, that's correct. Will be replaced by the kernel facilities.
[...]
> The badman-adv code is full of duplicated functionality, and until
> all of these cases are cured I refuse to integrate this code. I
> already complained about the hashing stuff, and now there's this
> stuff too.
>
> Every time I review the batman-adv code I find a bug, and the bug is
> often in facilities which the kernel has already and are being
> duplicated. That is by definition a waste of my and everyone else's
> time.
>
> Probably your submission will be almost half the size that it is
> currently once you take care of this issue. :-)
Do you have any more possible duplication you have in your mind right now?
thanks,
Sven
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCHv6] net: Add batman-adv meshing protocol
From: David Miller @ 2010-12-01 18:56 UTC (permalink / raw)
To: sven.eckelmann-Mmb7MZpHnFY
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
In-Reply-To: <201012011954.20275.sven.eckelmann-Mmb7MZpHnFY@public.gmane.org>
From: Sven Eckelmann <sven.eckelmann-Mmb7MZpHnFY@public.gmane.org>
Date: Wed, 1 Dec 2010 19:54:19 +0100
> Do you have any more possible duplication you have in your mind right now?
The hashing code, for the third time.
^ permalink raw reply
* Re: skge.c patch to limit DMA for ASUS A8N-SLI Premium board
From: David Miller @ 2010-12-01 19:00 UTC (permalink / raw)
To: kernel.org.alias; +Cc: netdev
In-Reply-To: <4CEEFA11.6040205@fremnet.net>
From: Shannon Wynter <kernel.org.alias@fremnet.net>
Date: Fri, 26 Nov 2010 10:06:41 +1000
> Hi
>
> I would like to contribute a patch to add ASUS A8N-SLI Premium to the
> list of boards that require the quirk to limit DMA to 32bit in the
> skge.c module.
>
> It took 2 hours of fiddling with my machine last night to get the
> network card working - the lights were on but no-one was at home.
>
> I never would have found it if not for the original bug listed on
> redhat for the Gigabyte motherboard.
Please resubmit this with a proper "Signed-off-by: " tag as per
Documentation/SubmittingPatches
Thank you.
^ permalink raw reply
* Re: [PATCH] ipv6: slightly simplify keeping IPv6 addresses on link down
From: David Miller @ 2010-12-01 19:01 UTC (permalink / raw)
To: lorenzo; +Cc: netdev
In-Reply-To: <AANLkTikvmRhkxB0WDUYeTj7qpsud0+qSHd+6Jj+k_eO=@mail.gmail.com>
From: Lorenzo Colitti <lorenzo@google.com>
Date: Fri, 26 Nov 2010 10:06:58 -0800
> @@ -2663,8 +2663,7 @@ static int addrconf_ifdown(struct net_device
> *dev, int how)
Please fix your email client to not corrupt patches.
See Documentation/email-clients.txt
^ permalink raw reply
* Re: [PATCHv6] net: Add batman-adv meshing protocol
From: Sven Eckelmann @ 2010-12-01 19:04 UTC (permalink / raw)
To: David Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
In-Reply-To: <20101201.105615.48506929.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
[-- Attachment #1: Type: Text/Plain, Size: 663 bytes --]
David Miller wrote:
> From: Sven Eckelmann <sven.eckelmann-Mmb7MZpHnFY@public.gmane.org>
> Date: Wed, 1 Dec 2010 19:54:19 +0100
>
> > Do you have any more possible duplication you have in your mind right
> > now?
>
> The hashing code, for the third time.
And I asked in the past about the removal of the hashing stuff without any
reaction. So, we removed most of it. resize and iterate will be dropped too.
So, is it a problem to have a hash_find, hash_remove, hash_add? These were
created to reduce duplicated code and not to create a complete new dynamic
datastructure (which it isn't... it is just the usual hlist stuff)
thanks,
Sven
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ 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