Netdev List
 help / color / mirror / Atom feed
* [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: 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 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: 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

* 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

* [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: [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

* 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 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

* [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: 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

* 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: kill an RCU warning in inet_fill_link_af()
From: Eric Dumazet @ 2010-12-01 17:31 UTC (permalink / raw)
  To: Thomas Graf
  Cc: Amerigo Wang, linux-kernel, David S. Miller, Alexey Kuznetsov,
	Pekka Savola (ipv6), James Morris, Hideaki YOSHIFUJI,
	Patrick McHardy, netdev
In-Reply-To: <20101201171801.GA22009@canuck.infradead.org>

Le mercredi 01 décembre 2010 à 12:18 -0500, Thomas Graf a écrit :
> On Wed, Dec 01, 2010 at 05:03:06PM +0100, Eric Dumazet wrote:
> > [PATCH net-next-2.6] net: kill an RCU warning in inet_fill_link_af()
> > 
> > commits 9f0f7272 (ipv4: AF_INET link address family) and cf7afbfeb8c
> > (rtnl: make link af-specific updates atomic) used incorrect
> > __in_dev_get_rcu() in RTNL protected contexts, triggering PROVE_RCU
> > warnings.
> > 
> > Switch to __in_dev_get_rtnl(), wich is more appropriate, since we hold
> > RTNL.
> > 
> > Based on a report and initial patch from Amerigo Wang.
> 
> RTNL is not held while dumping, it is only held for get and set, but we
> still hold rcu readlocks while dumping so there should be no asserts
> triggered. Thanks for fixing this.

Are you sure RTNL is not held while dumping ? 

Patrick did the change to hold RTNL while dumping too, 3.5 years ago.
Check commits 6313c1e0992fea, 1c2d670f3660e9103 ([RTNETLINK]: Hold
rtnl_mutex during netlink dump callbacks)

If this was the case (not holding RTNL), we should use
rcu_dereference(), not rtnl_dereference()

^ permalink raw reply

* Re: multi bpf filter will impact performance?
From: Hagen Paul Pfeifer @ 2010-12-01 17:22 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Changli Gao, Rui, netdev
In-Reply-To: <1291192967.2856.492.camel@edumazet-laptop>


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!? ... ;)



Hagen



^ permalink raw reply

* Re: [Patch] net: kill an RCU warning in inet_fill_link_af()
From: Thomas Graf @ 2010-12-01 17:18 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Amerigo Wang, linux-kernel, David S. Miller, Alexey Kuznetsov,
	Pekka Savola (ipv6), James Morris, Hideaki YOSHIFUJI,
	Patrick McHardy, netdev
In-Reply-To: <1291219386.2856.924.camel@edumazet-laptop>

On Wed, Dec 01, 2010 at 05:03:06PM +0100, Eric Dumazet wrote:
> [PATCH net-next-2.6] net: kill an RCU warning in inet_fill_link_af()
> 
> commits 9f0f7272 (ipv4: AF_INET link address family) and cf7afbfeb8c
> (rtnl: make link af-specific updates atomic) used incorrect
> __in_dev_get_rcu() in RTNL protected contexts, triggering PROVE_RCU
> warnings.
> 
> Switch to __in_dev_get_rtnl(), wich is more appropriate, since we hold
> RTNL.
> 
> Based on a report and initial patch from Amerigo Wang.

RTNL is not held while dumping, it is only held for get and set, but we
still hold rcu readlocks while dumping so there should be no asserts
triggered. Thanks for fixing this.

^ permalink raw reply

* Re: [PATCH] net/r8169: Remove the firmware of RTL8111D
From: Ben Hutchings @ 2010-12-01 17:05 UTC (permalink / raw)
  To: Stefan Lippers-Hollmann; +Cc: Francois Romieu, Hayes Wang, netdev, linux-kernel
In-Reply-To: <201012011736.59625.s.L-H@gmx.de>

On Wed, Dec 01, 2010 at 05:36:55PM +0100, Stefan Lippers-Hollmann wrote:
> Hi
> 
> On Wednesday 01 December 2010, Francois Romieu wrote:
> > Hayes Wang <hayeswang@realtek.com> :
> > > Remove the firmware of RTL8111D from the kernel.
> > > The binary file of firmware would be moved to linux-firmware repository.
> > 
> > The driver can not simply go along when request_firmware fails. Though Ben's
> > code did not take care of it, the driver should imho propagate some return
> > code. Ben ?
> [...]
> 
> At least for RTL8111D-1 (rtl8168d_1_hw_phy_config(), phy_reg_init_2[])
> a missing firmware update doesn't seem to be fatal
> 	http://bugs.debian.org/561309#45
[...]

Yes.  Though it does clearly affect operation with some combinations of
cable and link partner.  There was a recent bug report on this, though
I can't find it now.

Ben.

-- 
Ben Hutchings
We get into the habit of living before acquiring the habit of thinking.
                                                              - Albert Camus

^ permalink raw reply

* Re: [PATCH] net/r8169: Remove the firmware of RTL8111D
From: Stefan Lippers-Hollmann @ 2010-12-01 16:36 UTC (permalink / raw)
  To: Francois Romieu; +Cc: Hayes Wang, netdev, linux-kernel, Ben Hutchings
In-Reply-To: <20101201080732.GA3234@electric-eye.fr.zoreil.com>

Hi

On Wednesday 01 December 2010, Francois Romieu wrote:
> Hayes Wang <hayeswang@realtek.com> :
> > Remove the firmware of RTL8111D from the kernel.
> > The binary file of firmware would be moved to linux-firmware repository.
> 
> The driver can not simply go along when request_firmware fails. Though Ben's
> code did not take care of it, the driver should imho propagate some return
> code. Ben ?
[...]

At least for RTL8111D-1 (rtl8168d_1_hw_phy_config(), phy_reg_init_2[])
a missing firmware update doesn't seem to be fatal
	http://bugs.debian.org/561309#45

I'm running that card (onboard of the Intel D945GSEJT mainboard), with
rtl8168d_1_hw_phy_config()/ phy_reg_init_2[] stripped out, without any 
noticable issues for about a year as always-on home server and good 
GBit/s performance.

[    3.861378] r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
[    3.861462] r8169 0000:01:00.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
[    3.861575] r8169 0000:01:00.0: setting latency timer to 64
[    3.861703] r8169 0000:01:00.0: irq 45 for MSI/MSI-X
[    3.865188] r8169 0000:01:00.0: eth0: RTL8168d/8111d at 0xf8406000, 00:1c:c0:ee:22:88, XID 081000c0 IRQ 45

using Debian's firmware removal patch and without the required firmware
image being present
[    3.870663] eth0: unable to apply firmware patch

[   16.364231] r8169 0000:01:00.0: eth0: link up
[   26.562069] eth0: no IPv6 routers present

Debian has been shipping (unstable and a little later squeeze, the 
upcoming stable) kernels with this firmware stripped out since late 
december 2009.

Therefore I'd think it's safe to just make some noise about missing 
firmware images and not cease operations completely for this chipset.

Regards
	Stefan Lippers-Hollmann

^ permalink raw reply

* Re: [Patch] bonding: clean up netpoll code
From: Stephen Hemminger @ 2010-12-01 16:14 UTC (permalink / raw)
  To: Amerigo Wang
  Cc: linux-kernel, Jiri Pirko, Neil Horman, netdev, David S. Miller,
	Eric W. Biederman, Herbert Xu, bonding-devel, Jay Vosburgh
In-Reply-To: <20101201075043.5741.29172.sendpatchset@localhost.localdomain>

On Wed, 1 Dec 2010 02:45:45 -0500
Amerigo Wang <amwang@redhat.com> wrote:

> +	if ((slave_dev->npinfo = bond_netpoll_info(bond))) {

Split assignment and conditional into two lines


-- 

^ permalink raw reply

* Re: [Patch] net: kill an RCU warning in inet_fill_link_af()
From: Eric Dumazet @ 2010-12-01 16:03 UTC (permalink / raw)
  To: Amerigo Wang
  Cc: linux-kernel, David S. Miller, Alexey Kuznetsov,
	Pekka Savola (ipv6), James Morris, Hideaki YOSHIFUJI,
	Patrick McHardy, netdev, Thomas Graf
In-Reply-To: <1291202063-6239-1-git-send-email-amwang@redhat.com>

Le mercredi 01 décembre 2010 à 19:14 +0800, Amerigo Wang a écrit :
> From: WANG Cong <amwang@redhat.com>
> 
> The latest net-next-2.6 triggers an RCU warning during boot,
> lockdep complains that in inet_fill_link_af() we call rcu_dereference_check()
> without rcu_read_lock() protection.
> 
> This patch fixes it by replacing __in_dev_get_rcu() with in_dev_get().

Here is a better version, thanks a lot for your report and initial
patch.


[PATCH net-next-2.6] net: kill an RCU warning in inet_fill_link_af()

commits 9f0f7272 (ipv4: AF_INET link address family) and cf7afbfeb8c
(rtnl: make link af-specific updates atomic) used incorrect
__in_dev_get_rcu() in RTNL protected contexts, triggering PROVE_RCU
warnings.

Switch to __in_dev_get_rtnl(), wich is more appropriate, since we hold
RTNL.

Based on a report and initial patch from Amerigo Wang.

Reported-by: Amerigo Wang <amwang@redhat.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Thomas Graf <tgraf@infradead.org>
---
 net/ipv4/devinet.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index d9f71ba..3b06770 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1258,7 +1258,7 @@ errout:
 
 static size_t inet_get_link_af_size(const struct net_device *dev)
 {
-	struct in_device *in_dev = __in_dev_get_rcu(dev);
+	struct in_device *in_dev = __in_dev_get_rtnl(dev);
 
 	if (!in_dev)
 		return 0;
@@ -1268,7 +1268,7 @@ static size_t inet_get_link_af_size(const struct net_device *dev)
 
 static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
 {
-	struct in_device *in_dev = __in_dev_get_rcu(dev);
+	struct in_device *in_dev = __in_dev_get_rtnl(dev);
 	struct nlattr *nla;
 	int i;
 
@@ -1295,7 +1295,7 @@ static int inet_validate_link_af(const struct net_device *dev,
 	struct nlattr *a, *tb[IFLA_INET_MAX+1];
 	int err, rem;
 
-	if (dev && !__in_dev_get_rcu(dev))
+	if (dev && !__in_dev_get_rtnl(dev))
 		return -EAFNOSUPPORT;
 
 	err = nla_parse_nested(tb, IFLA_INET_MAX, nla, inet_af_policy);
@@ -1319,7 +1319,7 @@ static int inet_validate_link_af(const struct net_device *dev,
 
 static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla)
 {
-	struct in_device *in_dev = __in_dev_get_rcu(dev);
+	struct in_device *in_dev = __in_dev_get_rtnl(dev);
 	struct nlattr *a, *tb[IFLA_INET_MAX+1];
 	int rem;
 

^ permalink raw reply related

* Re: [PATCH 1/2] af_packet: use vmalloc_to_page() instead for the addresss returned by vmalloc()
From: Eric Dumazet @ 2010-12-01 15:13 UTC (permalink / raw)
  To: Changli Gao; +Cc: Neil Horman, David S. Miller, Jiri Pirko, netdev
In-Reply-To: <AANLkTinViD=WpwUFUDF6mKbc-Cap_Tg=SXwOjVQ=5u4B@mail.gmail.com>

Le mercredi 01 décembre 2010 à 22:16 +0800, Changli Gao a écrit :

> Even then, tpacket_fill_skb() is called for every skb, and
> pgv_to_page() is used in it. We have to optimize pgv_to_page().

With the __pure trick I gave, pgv_to_page() is _not_ called for the
typical use case of af_packet : packet sniffing.

Compiler is able to remove the call completely, since

static inline void flush_dcache_page(struct page *page) { }

The only remaining pgv_to_page() call is the one done in mmap packet
send, since we have to do :

page = pgv_to_page(data);
get_page(page);

I personally dont use this path, its known to be buggy...

Optimize if you want, but make all this
ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE conditional.

Its not needed to maintain an array of 'struct page *' if its not needed
at all.

# vi +2448 block/blk-core.c

#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
/**
 * rq_flush_dcache_pages - Helper function to flush all pages in a request
 * @rq: the request to be flushed
 *
 * Description:
 *     Flush all pages in @rq.
 */
void rq_flush_dcache_pages(struct request *rq)
{
        struct req_iterator iter;
        struct bio_vec *bvec;

        rq_for_each_segment(bvec, rq, iter)
                flush_dcache_page(bvec->bv_page);
}
EXPORT_SYMBOL_GPL(rq_flush_dcache_pages);
#endif




^ permalink raw reply

* Re: [PATCH v2] Net-ethtool : Allow ethtool to set interface in loopback mode.
From: Ben Hutchings @ 2010-12-01 14:54 UTC (permalink / raw)
  To: Mahesh Bandewar; +Cc: David Miller, linux-netdev, laurent chavey
In-Reply-To: <AANLkTimJJzQ6f06CoWJuofwS0m2Bn3gAcfWTOEiYyjEZ@mail.gmail.com>

On Tue, 2010-11-30 at 15:57 -0800, Mahesh Bandewar wrote:
> This patch enables ethtool to set the loopback mode on a given
> interface. By configuring the interface in loopback mode in conjunction
> with a policy route / rule, a userland application can stress the egress /
> ingress path exposing the flows of the change in progress and potentially
> help developer(s) understand the impact of those changes without even
> sending a packet out on the network.
[...]
> --- a/include/linux/ethtool.h
> +++ b/include/linux/ethtool.h
> @@ -616,6 +616,17 @@ void ethtool_ntuple_flush(struct net_device *dev);
>   *     Should validate the magic field.  Don't need to check len for zero
>   *     or wraparound.  Update len to the amount written.  Returns an error
>   *     or zero.
> + *
> + * get_loopback:
> + * set_loopback:
> +    These are the driver specific get / set methods to report / enable-
> +       disable loopback mode. The idea is to stress test the ingress / egress
> +       paths by enabling this mode. There are multiple places this could be
> +       done and choice of place will most likely be affected by the device
> +       capabilities. So as a guiding principle; select a place to implement
> +       loopback mode as close to the host as possible. This would maximize the
> +       soft-path length and maintain parity in terms of comparison with differe
> +       set of drivers.
[...]

I know this is nitpicking, but the comment should have asterisks (*)
repeated down the left edge.  Also, a typo: "differe" should be
"different".

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* Re: [PATCH 1/2] af_packet: use vmalloc_to_page() instead for the addresss returned by vmalloc()
From: Changli Gao @ 2010-12-01 14:16 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Neil Horman, David S. Miller, Jiri Pirko, netdev
In-Reply-To: <1291210691.2856.740.camel@edumazet-laptop>

On Wed, Dec 1, 2010 at 9:38 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le mercredi 01 décembre 2010 à 21:05 +0800, Changli Gao a écrit :
>> On Tue, Nov 30, 2010 at 10:37 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
>> > Off the top of my head, I would think that pgv_to_page could be prototyped such
>> > that it could accept addr, offset and struct page ** arguments.  That way we can
>> > track the current page that we're mapped to, lowering the number of calls to
>> > vmalloc_to_page, and we can still use an increment like we do above (as long as
>> > its wrapped in a subsequent call to pgv_to_page)
>>
>> I'll try to optimize pgv_to_page() after this patch series merged. I
>> am planning to call vmalloc_to_page() previously, and cache its result
>> in a per pgv array for future use. Thanks.
>>
>>
>
> Hmm... fact is flush_dcache_page() is void on some arches.
>
> Maybe the only thing to do is avoid pgv_to_page() calls if
> ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE is 0
>

Even then, tpacket_fill_skb() is called for every skb, and
pgv_to_page() is used in it. We have to optimize pgv_to_page().
Thanks.

-- 
Regards,
Changli Gao(xiaosuo@gmail.com)

^ permalink raw reply

* Re: [PATCH v2] add netdev led trigger
From: Andi Kleen @ 2010-12-01 14:03 UTC (permalink / raw)
  To: Andi Kleen, linux-kernel, linux-doc, Richard Purdie, Randy Dunlap,
	netdev
In-Reply-To: <20101201000300.GJ21496@localhost>

On Tue, Nov 30, 2010 at 07:03:00PM -0500, Eric Cooper wrote:
> On Mon, Nov 29, 2010 at 11:15:51AM +0100, Andi Kleen wrote:
> > Using the device name as an identifier is not reliable, they may not
> > be unique.
> 
> I'm confused about this -- how else can the user specify the desired network
> interface?

For presenting the user the name is probably still the best, but internally
better use the interface index.
> 
> > rwlocks are deprecated.
> 
> In favor of what?  Should I use a spinlock?

spinlocks or mutexes.

-Andi

-- 
ak@linux.intel.com -- Speaking for myself only.

^ permalink raw reply

* Re: [PATCH 1/2] af_packet: use vmalloc_to_page() instead for the addresss returned by vmalloc()
From: Eric Dumazet @ 2010-12-01 13:43 UTC (permalink / raw)
  To: Changli Gao; +Cc: Neil Horman, David S. Miller, Jiri Pirko, netdev
In-Reply-To: <1291210691.2856.740.camel@edumazet-laptop>

Le mercredi 01 décembre 2010 à 14:38 +0100, Eric Dumazet a écrit :
> Le mercredi 01 décembre 2010 à 21:05 +0800, Changli Gao a écrit :
> > On Tue, Nov 30, 2010 at 10:37 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> > > Off the top of my head, I would think that pgv_to_page could be prototyped such
> > > that it could accept addr, offset and struct page ** arguments.  That way we can
> > > track the current page that we're mapped to, lowering the number of calls to
> > > vmalloc_to_page, and we can still use an increment like we do above (as long as
> > > its wrapped in a subsequent call to pgv_to_page)
> > 
> > I'll try to optimize pgv_to_page() after this patch series merged. I
> > am planning to call vmalloc_to_page() previously, and cache its result
> > in a per pgv array for future use. Thanks.
> > 
> > 
> 
> Hmm... fact is flush_dcache_page() is void on some arches.
> 
> Maybe the only thing to do is avoid pgv_to_page() calls if
> ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE is 0
> 
>     The ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE symbol was introduced to avoid
>     pointless empty cache-thrashing loops on architectures for which
>     flush_dcache_page() is a no-op.  Every architecture was provided with this
>     flush pages on architectires where ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE is
>     equal 1 or do nothing otherwise.
> 
> 

I guess using __pure attribute on pgv_to_page() should be enough ;)

static inline __pure struct page *pgv_to_page(void *addr)
{
       if (is_vmalloc_addr(addr))
               return vmalloc_to_page(addr);
       return virt_to_page(addr);
}

Compiler then should optimize away

flush_dcache_page(pgv_to_page(addr));


But the pgv_to_page() done in packet_sendmsg() will stay, of course.



^ permalink raw reply

* Re: [PATCH 1/2] af_packet: use vmalloc_to_page() instead for the addresss returned by vmalloc()
From: Eric Dumazet @ 2010-12-01 13:38 UTC (permalink / raw)
  To: Changli Gao; +Cc: Neil Horman, David S. Miller, Jiri Pirko, netdev
In-Reply-To: <AANLkTim7SSRMkhc_eMz+Bk12kAwfG==j-dH4NOPu-uS2@mail.gmail.com>

Le mercredi 01 décembre 2010 à 21:05 +0800, Changli Gao a écrit :
> On Tue, Nov 30, 2010 at 10:37 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> > Off the top of my head, I would think that pgv_to_page could be prototyped such
> > that it could accept addr, offset and struct page ** arguments.  That way we can
> > track the current page that we're mapped to, lowering the number of calls to
> > vmalloc_to_page, and we can still use an increment like we do above (as long as
> > its wrapped in a subsequent call to pgv_to_page)
> 
> I'll try to optimize pgv_to_page() after this patch series merged. I
> am planning to call vmalloc_to_page() previously, and cache its result
> in a per pgv array for future use. Thanks.
> 
> 

Hmm... fact is flush_dcache_page() is void on some arches.

Maybe the only thing to do is avoid pgv_to_page() calls if
ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE is 0

    The ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE symbol was introduced to avoid
    pointless empty cache-thrashing loops on architectures for which
    flush_dcache_page() is a no-op.  Every architecture was provided with this
    flush pages on architectires where ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE is
    equal 1 or do nothing otherwise.




^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox