Netdev List
 help / color / mirror / Atom feed
* [PATCH] netfilter: xt_recent: Add optional mask option for xt_recent
From: Denys Fedoryshchenko @ 2012-05-17 20:07 UTC (permalink / raw)
  To: Linux netdev; +Cc: Pablo Neira Ayuso, Denys Fedoryshchenko

Use case for this feature:
1)In some occasions if you need to allow,block,match specific subnet.
2)I can use recent as a trigger when netfilter rule matches, with mask 0.0.0.0

Tested for backward compatibility:
)old (userspace) iptables, new kernel
)old kernel, new iptables
)new kernel, new iptables

For v2:
 As Pablo Neira Ayuso suggested, moved nf_inet_addr_mask to xt_recent.h
 and made info_v1 as a stack variable.

Signed-off-by: Denys Fedoryshchenko <denys@visp.net.lb>
CC: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/linux/netfilter/xt_recent.h |   20 +++++++++++
 net/netfilter/xt_recent.c           |   62 ++++++++++++++++++++++++++++++----
 2 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/include/linux/netfilter/xt_recent.h b/include/linux/netfilter/xt_recent.h
index 83318e0..5f69ebc 100644
--- a/include/linux/netfilter/xt_recent.h
+++ b/include/linux/netfilter/xt_recent.h
@@ -32,4 +32,24 @@ struct xt_recent_mtinfo {
 	__u8 side;
 };
 
+struct xt_recent_mtinfo_v1 {
+	__u32 seconds;
+	__u32 hit_count;
+	__u8 check_set;
+	__u8 invert;
+	char name[XT_RECENT_NAME_LEN];
+	__u8 side;
+	union nf_inet_addr mask;
+};
+
+static inline void nf_inet_addr_mask(const union nf_inet_addr *a1,
+				    union nf_inet_addr *result,
+				    const union nf_inet_addr *mask)
+{
+	result->all[0] = a1->all[0] & mask->all[0];
+	result->all[1] = a1->all[1] & mask->all[1];
+	result->all[2] = a1->all[2] & mask->all[2];
+	result->all[3] = a1->all[3] & mask->all[3];
+}
+
 #endif /* _LINUX_NETFILTER_XT_RECENT_H */
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index fc0d6db..ca4375c 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -75,6 +75,7 @@ struct recent_entry {
 struct recent_table {
 	struct list_head	list;
 	char			name[XT_RECENT_NAME_LEN];
+	union nf_inet_addr	mask;
 	unsigned int		refcnt;
 	unsigned int		entries;
 	struct list_head	lru_list;
@@ -228,10 +229,11 @@ recent_mt(const struct sk_buff *skb, struct xt_action_param *par)
 {
 	struct net *net = dev_net(par->in ? par->in : par->out);
 	struct recent_net *recent_net = recent_pernet(net);
-	const struct xt_recent_mtinfo *info = par->matchinfo;
+	const struct xt_recent_mtinfo_v1 *info = par->matchinfo;
 	struct recent_table *t;
 	struct recent_entry *e;
 	union nf_inet_addr addr = {};
+	union nf_inet_addr addr_masked;
 	u_int8_t ttl;
 	bool ret = info->invert;
 
@@ -261,12 +263,15 @@ recent_mt(const struct sk_buff *skb, struct xt_action_param *par)
 
 	spin_lock_bh(&recent_lock);
 	t = recent_table_lookup(recent_net, info->name);
-	e = recent_entry_lookup(t, &addr, par->family,
+
+	nf_inet_addr_mask(&addr, &addr_masked, &t->mask);
+
+	e = recent_entry_lookup(t, &addr_masked, par->family,
 				(info->check_set & XT_RECENT_TTL) ? ttl : 0);
 	if (e == NULL) {
 		if (!(info->check_set & XT_RECENT_SET))
 			goto out;
-		e = recent_entry_init(t, &addr, par->family, ttl);
+		e = recent_entry_init(t, &addr_masked, par->family, ttl);
 		if (e == NULL)
 			par->hotdrop = true;
 		ret = !ret;
@@ -306,10 +311,10 @@ out:
 	return ret;
 }
 
-static int recent_mt_check(const struct xt_mtchk_param *par)
+static int recent_mt_check(const struct xt_mtchk_param *par,
+	const struct xt_recent_mtinfo_v1 *info)
 {
 	struct recent_net *recent_net = recent_pernet(par->net);
-	const struct xt_recent_mtinfo *info = par->matchinfo;
 	struct recent_table *t;
 #ifdef CONFIG_PROC_FS
 	struct proc_dir_entry *pde;
@@ -361,6 +366,8 @@ static int recent_mt_check(const struct xt_mtchk_param *par)
 		goto out;
 	}
 	t->refcnt = 1;
+
+	memcpy(&t->mask, &info->mask, sizeof(t->mask));
 	strcpy(t->name, info->name);
 	INIT_LIST_HEAD(&t->lru_list);
 	for (i = 0; i < ip_list_hash_size; i++)
@@ -385,10 +392,29 @@ out:
 	return ret;
 }
 
+static int recent_mt_check_v0(const struct xt_mtchk_param *par)
+{
+	const struct xt_recent_mtinfo_v0 *info_v0 = par->matchinfo;
+	struct xt_recent_mtinfo_v1 info_v1;
+	int ret;
+
+	/* Copy old data */
+	memcpy(&info_v1, info_v0, sizeof(struct xt_recent_mtinfo));
+	/* Default mask will make same behavior as old recent */
+	memset(info_v1.mask.all, 0xFF, sizeof(info_v1.mask.all));
+	ret = recent_mt_check(par, &info_v1);
+	return ret;
+}
+
+static int recent_mt_check_v1(const struct xt_mtchk_param *par)
+{
+	return recent_mt_check(par, par->matchinfo);
+}
+
 static void recent_mt_destroy(const struct xt_mtdtor_param *par)
 {
 	struct recent_net *recent_net = recent_pernet(par->net);
-	const struct xt_recent_mtinfo *info = par->matchinfo;
+	const struct xt_recent_mtinfo_v1 *info = par->matchinfo;
 	struct recent_table *t;
 
 	mutex_lock(&recent_mutex);
@@ -625,7 +651,7 @@ static struct xt_match recent_mt_reg[] __read_mostly = {
 		.family     = NFPROTO_IPV4,
 		.match      = recent_mt,
 		.matchsize  = sizeof(struct xt_recent_mtinfo),
-		.checkentry = recent_mt_check,
+		.checkentry = recent_mt_check_v0,
 		.destroy    = recent_mt_destroy,
 		.me         = THIS_MODULE,
 	},
@@ -635,10 +661,30 @@ static struct xt_match recent_mt_reg[] __read_mostly = {
 		.family     = NFPROTO_IPV6,
 		.match      = recent_mt,
 		.matchsize  = sizeof(struct xt_recent_mtinfo),
-		.checkentry = recent_mt_check,
+		.checkentry = recent_mt_check_v0,
+		.destroy    = recent_mt_destroy,
+		.me         = THIS_MODULE,
+	},
+	{
+		.name       = "recent",
+		.revision   = 1,
+		.family     = NFPROTO_IPV4,
+		.match      = recent_mt,
+		.matchsize  = sizeof(struct xt_recent_mtinfo_v1),
+		.checkentry = recent_mt_check_v1,
 		.destroy    = recent_mt_destroy,
 		.me         = THIS_MODULE,
 	},
+	{
+		.name       = "recent",
+		.revision   = 1,
+		.family     = NFPROTO_IPV6,
+		.match      = recent_mt,
+		.matchsize  = sizeof(struct xt_recent_mtinfo_v1),
+		.checkentry = recent_mt_check_v1,
+		.destroy    = recent_mt_destroy,
+		.me         = THIS_MODULE,
+	}
 };
 
 static int __init recent_mt_init(void)
-- 
1.7.3.4

^ permalink raw reply related

* [PATCH v3] drop_monitor: convert to modular building
From: Neil Horman @ 2012-05-17 20:04 UTC (permalink / raw)
  To: netdev; +Cc: Neil Horman, David S. Miller, Eric Dumazet, Ben Hutchings
In-Reply-To: <1337178426-2470-1-git-send-email-nhorman@tuxdriver.com>

When I first wrote drop monitor I wrote it to just build monolithically.  There
is no reason it can't be built modularly as well, so lets give it that
flexibiity.

I've tested this by building it as both a module and monolithically, and it
seems to work quite well

Change notes:

v2)
* fixed for_each_present_cpu loops to be more correct as per Eric D.
* Converted exit path failures to BUG_ON as per Ben H.

v3)
* Converted del_timer to del_timer_sync to close race noted by Ben H.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: "David S. Miller" <davem@davemloft.net>
CC: Eric Dumazet <eric.dumazet@gmail.com>
CC: Ben Hutchings <bhutchings@solarflare.com>
---
 net/Kconfig             |    2 +-
 net/core/drop_monitor.c |   46 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/net/Kconfig b/net/Kconfig
index e07272d..76ad6fa 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -295,7 +295,7 @@ config NET_TCPPROBE
 	module will be called tcp_probe.
 
 config NET_DROP_MONITOR
-	boolean "Network packet drop alerting service"
+	tristate "Network packet drop alerting service"
 	depends on INET && EXPERIMENTAL && TRACEPOINTS
 	---help---
 	This feature provides an alerting service to userspace in the
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index cfeeef8..f93f985 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -24,6 +24,7 @@
 #include <linux/timer.h>
 #include <linux/bitops.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <net/genetlink.h>
 #include <net/netevent.h>
 
@@ -225,9 +226,15 @@ static int set_all_monitor_traces(int state)
 
 	switch (state) {
 	case TRACE_ON:
+		if (!try_module_get(THIS_MODULE)) {
+			rc = -ENODEV;
+			break;
+		}
+
 		rc |= register_trace_kfree_skb(trace_kfree_skb_hit, NULL);
 		rc |= register_trace_napi_poll(trace_napi_poll_hit, NULL);
 		break;
+
 	case TRACE_OFF:
 		rc |= unregister_trace_kfree_skb(trace_kfree_skb_hit, NULL);
 		rc |= unregister_trace_napi_poll(trace_napi_poll_hit, NULL);
@@ -243,6 +250,9 @@ static int set_all_monitor_traces(int state)
 				kfree_rcu(new_stat, rcu);
 			}
 		}
+
+		module_put(THIS_MODULE);
+
 		break;
 	default:
 		rc = 1;
@@ -368,7 +378,7 @@ static int __init init_net_drop_monitor(void)
 
 	rc = 0;
 
-	for_each_present_cpu(cpu) {
+	for_each_possible_cpu(cpu) {
 		data = &per_cpu(dm_cpu_data, cpu);
 		reset_per_cpu_data(data);
 		INIT_WORK(&data->dm_alert_work, send_dm_alert);
@@ -385,4 +395,36 @@ out:
 	return rc;
 }
 
-late_initcall(init_net_drop_monitor);
+static void exit_net_drop_monitor(void)
+{
+	struct per_cpu_dm_data *data;
+	int cpu;
+
+	BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier));
+
+	/*
+	 * Because of the module_get/put we do in the trace state change path
+	 * we are guarnateed not to have any current users when we get here
+	 * all we need to do is make sure that we don't have any running timers
+	 * or pending schedule calls
+	 */
+
+	for_each_possible_cpu(cpu) {
+		data = &per_cpu(dm_cpu_data, cpu);
+		del_timer_sync(&data->send_timer);
+		cancel_work_sync(&data->dm_alert_work);
+		/*
+		 * At this point, we should have exclusive access
+		 * to this struct and can free the skb inside it
+		 */
+		kfree_skb(data->skb);
+	}
+
+	BUG_ON(genl_unregister_family(&net_drop_monitor_family));
+}
+
+module_init(init_net_drop_monitor);
+module_exit(exit_net_drop_monitor);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Neil Horman <nhorman@tuxdriver.com>");
-- 
1.7.7.6

^ permalink raw reply related

* Re: Stable regression with 'tcp: allow splice() to build full TSO packets'
From: Willy Tarreau @ 2012-05-17 20:04 UTC (permalink / raw)
  To: David Miller; +Cc: eric.dumazet, netdev
In-Reply-To: <20120517.155503.2294382162578627387.davem@davemloft.net>

Hi David,

On Thu, May 17, 2012 at 03:55:03PM -0400, David Miller wrote:
> From: Willy Tarreau <w@1wt.eu>
> Date: Thu, 17 May 2012 17:01:57 +0200
> 
> >>From 6da6a21798d0156e647a993c31782eec739fa5df Mon Sep 17 00:00:00 2001
> > From: Willy Tarreau <w@1wt.eu>
> > Date: Thu, 17 May 2012 16:48:56 +0200
> > Subject: [PATCH] tcp: force push data out when buffers are missing
> > 
> > Commit 2f533844242 (tcp: allow splice() to build full TSO packets)
> > significantly improved splice() performance for some workloads but
> > caused stalls when pipe buffers were larger than socket buffers.
> > 
> > The issue seems to happen when no data can be copied at all due to
> > lack of buffers, which results in pending data never being pushed.
> > 
> > This change checks if all pending data has been pushed or not and
> > pushes them when waiting for send buffers.
> 
> Eric, please indicate whether we need Willy's patch here.
> 
> I want to propagate this fix as fast as possible if so.

I think you should hold off for now, because it's possible that my patch
hides another issue instead of fixing it.

I'm having the same stall issue again since I applied Eric's build_skb
patch, but not for all data sizes. So if the same issue is still there,
it's possible that we're playing hide-and-seek with it. That's rather
strange.

Thanks,
Willy

^ permalink raw reply

* Re: Stable regression with 'tcp: allow splice() to build full TSO packets'
From: David Miller @ 2012-05-17 19:55 UTC (permalink / raw)
  To: w; +Cc: eric.dumazet, netdev
In-Reply-To: <20120517150157.GA19274@1wt.eu>

From: Willy Tarreau <w@1wt.eu>
Date: Thu, 17 May 2012 17:01:57 +0200

>>From 6da6a21798d0156e647a993c31782eec739fa5df Mon Sep 17 00:00:00 2001
> From: Willy Tarreau <w@1wt.eu>
> Date: Thu, 17 May 2012 16:48:56 +0200
> Subject: [PATCH] tcp: force push data out when buffers are missing
> 
> Commit 2f533844242 (tcp: allow splice() to build full TSO packets)
> significantly improved splice() performance for some workloads but
> caused stalls when pipe buffers were larger than socket buffers.
> 
> The issue seems to happen when no data can be copied at all due to
> lack of buffers, which results in pending data never being pushed.
> 
> This change checks if all pending data has been pushed or not and
> pushes them when waiting for send buffers.

Eric, please indicate whether we need Willy's patch here.

I want to propagate this fix as fast as possible if so.

^ permalink raw reply

* Re: [PATCH net-next] net: netdev_alloc_skb() use build_skb()
From: David Miller @ 2012-05-17 19:53 UTC (permalink / raw)
  To: eric.dumazet; +Cc: w, netdev
In-Reply-To: <1337276056.3403.37.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 17 May 2012 19:34:16 +0200

> [PATCH net-next] net: netdev_alloc_skb() use build_skb()
> 
> netdev_alloc_skb() is used by networks driver in their RX path to
> allocate an skb to receive an incoming frame.
> 
> With recent skb->head_frag infrastructure, it makes sense to change
> netdev_alloc_skb() to use build_skb() and a frag allocator.
> 
> This permits a zero copy splice(socket->pipe), and better GRO or TCP
> coalescing.
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Applied, we can sort out any fallout very easily before 3.5 is released.

Awesome work Eric.

^ permalink raw reply

* Re: [PATCH] ipv6: correct the ipv6 option name - Pad0 to Pad1
From: David Miller @ 2012-05-17 19:50 UTC (permalink / raw)
  To: eldad
  Cc: yoshfuji, netdev, bridge, hadi, jmorris, linux-kernel, kuznet,
	shemminger
In-Reply-To: <1337270425-21873-1-git-send-email-eldad@fogrefinery.com>

From: Eldad Zack <eldad@fogrefinery.com>
Date: Thu, 17 May 2012 18:00:25 +0200

> The padding destination or hop-by-hop option is called Pad1 and not Pad0.
> 
> See RFC2460 (4.2) or the IANA ipv6-parameters registry:
> http://www.iana.org/assignments/ipv6-parameters/ipv6-parameters.xml
> 
> Signed-off-by: Eldad Zack <eldad@fogrefinery.com>

Applied to net-next.

^ permalink raw reply

* Re: [PATCH net-next] etherdevice: fix comments
From: David Miller @ 2012-05-17 19:37 UTC (permalink / raw)
  To: shemminger; +Cc: netdev
In-Reply-To: <20120517081728.54719129@nehalam.linuxnetplumber.net>

From: Stephen Hemminger <shemminger@vyatta.com>
Date: Thu, 17 May 2012 08:17:28 -0700

> Fix some minor problems in comments of etherdevice.h
>  * Warning is out dated, file hasn't moved or disappeared in many years and
>     is unlikely to do so soon.
>  * Capitalize Ethernet consistently since it is a proper name
>  * Fix descriptive comment of padding
>  * Spelling and grammar fix for alignment comment
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH net-next-2.6] pppoe: remove unused return value from two methods.
From: David Miller @ 2012-05-17 19:35 UTC (permalink / raw)
  To: ramirose; +Cc: netdev
In-Reply-To: <CAHLOa7RiNcZBLE7z7JTY-7WJGOL_DTYq33hmwyTdM0HWqn_WgA@mail.gmail.com>

From: Rami Rosen <ramirose@gmail.com>
Date: Thu, 17 May 2012 18:04:50 +0300

> Hi,
> 
>  The patch removes unused return value from __delete_item() and
>  delete_item() methods in drivers/net/ppp/pppoe.c.
> 
> Signed-off-by: Rami Rosen <ramirose@gmail.com>

Applied, but please in the future:

1) Don't put "hi," "how are you" and things like in your message
   body, I have to edit them out every time when I commit your
   changes.

2) Remove that leading space from your commit message lines, I have
   to edit those out as well.

Thank you.

^ permalink raw reply

* Re: [net-next 2/4] e1000: remove workaround for Errata 23 from jumbo alloc
From: David Miller @ 2012-05-17 19:32 UTC (permalink / raw)
  To: bhutchings; +Cc: jeffrey.t.kirsher, bigeasy, netdev, gospo, sassmann
In-Reply-To: <1337265630.2496.11.camel@bwh-desktop.uk.solarflarecom.com>

From: Ben Hutchings <bhutchings@solarflare.com>
Date: Thu, 17 May 2012 15:40:30 +0100

> I don't believe PAGE_SIZE is >64K on any architecture, but perhaps you
> should replace the run-time check with:

powerpc can be built with PAGE_SHIFT == 18

^ permalink raw reply

* Re: [PATCH v2] drop_monitor: convert to modular building
From: Neil Horman @ 2012-05-17 19:33 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: netdev, David S. Miller, Eric Dumazet
In-Reply-To: <1337278445.2496.17.camel@bwh-desktop.uk.solarflarecom.com>

On Thu, May 17, 2012 at 07:14:05PM +0100, Ben Hutchings wrote:
> On Thu, 2012-05-17 at 13:49 -0400, Neil Horman wrote:
> > When I first wrote drop monitor I wrote it to just build monolithically.  There
> > is no reason it can't be built modularly as well, so lets give it that
> > flexibiity.
> > 
> > I've tested this by building it as both a module and monolithically, and it
> > seems to work quite well
> > 
> > Change notes:
> > 
> > v2)
> > * fixed for_each_present_cpu loops to be more correct as per Eric D.
> > * Converted exit path failures to BUG_ON as per Ben H.
> 
> Sorry I didn't pick up on this the first time:
> 
> [...]
> > -late_initcall(init_net_drop_monitor);
> > +static void exit_net_drop_monitor(void)
> > +{
> > +	struct per_cpu_dm_data *data;
> > +	int cpu;
> > +
> > +	BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier));
> > +
> > +	/*
> > +	 * Because of the module_get/put we do in the trace state change path
> > +	 * we are guarnateed not to have any current users when we get here
> > +	 * all we need to do is make sure that we don't have any running timers
> > +	 * or pending schedule calls
> > +	 */
> > +
> > +	for_each_possible_cpu(cpu) {
> > +		data = &per_cpu(dm_cpu_data, cpu);
> > +		del_timer(&data->send_timer);
> 
> Doesn't this need to be del_timer_sync()?
> 
Yeah, good catch.  I was thinking it didn't need to be as the timer doesn't
re-arm itself and the cancel_work_sync would undo anything that a running timer
did, but thinking about it, its possible that a timer could fire on cpu A, and
cpu B could execute and complete the cancel_work_sync prior to cpu A scheduling
it, so there is a race window there.  I'll fix that up.
Neil
 

^ permalink raw reply

* Re: [net-next 0/4][pull request] Intel Wired LAN Driver Updates
From: David Miller @ 2012-05-17 19:12 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: netdev, gospo, sassmann
In-Reply-To: <1337254070-32500-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Thu, 17 May 2012 04:27:46 -0700

> This series of patches contains updates for e1000, e1000e and igb.
> 
> The following are changes since commit dc6b9b78234fecdc6d2ca5e1629185718202bcf5:
>   net: include/net/sock.h cleanup
> and are available in the git repository at:
>   git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next master

Pulled, thanks.

^ permalink raw reply

* Re: [PATCH net-next] tcp: bool conversions
From: David Miller @ 2012-05-17 19:03 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev
In-Reply-To: <1337246134.4740.5.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 17 May 2012 11:15:34 +0200

> From: Eric Dumazet <edumazet@google.com>
> 
> bool conversions where possible.
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Applied, with commit message updated to reflect reality :-)

^ permalink raw reply

* Re: Stable regression with 'tcp: allow splice() to build full TSO packets'
From: Ben Hutchings @ 2012-05-17 18:38 UTC (permalink / raw)
  To: Willy Tarreau; +Cc: Eric Dumazet, netdev
In-Reply-To: <20120517155621.GK14498@1wt.eu>

On Thu, 2012-05-17 at 17:56 +0200, Willy Tarreau wrote:
[...]
> The NIC does not support TSO but I've seen an alternate driver for this
> NIC which pretends to do TSO and in fact builds header frags so that the
> NIC is able to send all frames at once. I think it's already what GSO is
> doing but I'm wondering whether it would be possible to get more speed
> by doing this than by relying on GSO to (possibly) split the frags earlier.
[...]

Yes, GSO has some overhead for skb allocation and additional function
calls that you can avoid by doing 'TSO' in the driver.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
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 v2] drop_monitor: convert to modular building
From: Ben Hutchings @ 2012-05-17 18:14 UTC (permalink / raw)
  To: Neil Horman; +Cc: netdev, David S. Miller, Eric Dumazet
In-Reply-To: <1337276940-5025-1-git-send-email-nhorman@tuxdriver.com>

On Thu, 2012-05-17 at 13:49 -0400, Neil Horman wrote:
> When I first wrote drop monitor I wrote it to just build monolithically.  There
> is no reason it can't be built modularly as well, so lets give it that
> flexibiity.
> 
> I've tested this by building it as both a module and monolithically, and it
> seems to work quite well
> 
> Change notes:
> 
> v2)
> * fixed for_each_present_cpu loops to be more correct as per Eric D.
> * Converted exit path failures to BUG_ON as per Ben H.

Sorry I didn't pick up on this the first time:

[...]
> -late_initcall(init_net_drop_monitor);
> +static void exit_net_drop_monitor(void)
> +{
> +	struct per_cpu_dm_data *data;
> +	int cpu;
> +
> +	BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier));
> +
> +	/*
> +	 * Because of the module_get/put we do in the trace state change path
> +	 * we are guarnateed not to have any current users when we get here
> +	 * all we need to do is make sure that we don't have any running timers
> +	 * or pending schedule calls
> +	 */
> +
> +	for_each_possible_cpu(cpu) {
> +		data = &per_cpu(dm_cpu_data, cpu);
> +		del_timer(&data->send_timer);

Doesn't this need to be del_timer_sync()?

Ben.

> +		cancel_work_sync(&data->dm_alert_work);
> +		/*
> +		 * At this point, we should have exclusive access
> +		 * to this struct and can free the skb inside it
> +		 */
> +		kfree_skb(data->skb);
> +	}
> +
> +	BUG_ON(genl_unregister_family(&net_drop_monitor_family));
> +}
> +
> +module_init(init_net_drop_monitor);
> +module_exit(exit_net_drop_monitor);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("Neil Horman <nhorman@tuxdriver.com>");

-- 
Ben Hutchings, Staff Engineer, Solarflare
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: tcp timestamp issues with google servers
From: Eric Dumazet @ 2012-05-17 18:12 UTC (permalink / raw)
  To: Miklos Szeredi; +Cc: netdev, linux-kernel
In-Reply-To: <87r4ujno34.fsf@tucsk.pomaz.szeredi.hu>

On Thu, 2012-05-17 at 11:39 +0200, Miklos Szeredi wrote:
> Sometimes connection to google.com, gmail.com and other google servers
> doesn't work or takes ages to connect.  When this hits it hits all
> google servers at the same time and it's persistent.  It never happens
> to anything other than google.  Rebooting helps.  Rarely it goes away
> spontaneously.
> 
> Apparently google is sometimes replying with an invalid TSecr timestamp
> value (smaller than the one sent in the last packet) and this confuses
> the Linux TCP stack which either discards the packet or sends a Reset.
> 
> Network dump attached.
> 
> I found only a couple of references to this issue:
> 
> http://gotchas.livejournal.com/3028.html
> 
> http://groups.google.com/group/comp.os.linux.networking/browse_thread/thread/29f56feded11b42a
> 
> Turning tcp timestamps fixes the issue:
> 
>   sysctl -w net.ipv4.tcp_timestamps=0
> 
> Not sure why this happens only to me and a very few others.
> 
> It appears to be an issue with google TCP stack (is it a modified
> stack?) but I thought about issues in my network switch (restarting it
> doesn't help) or something in the ISP, but those look unlikely.
> 
> Any ideas?
> 
> Thanks,
> Miklos
> 
> 
> 
>   1   0.000000 192.168.28.100 -> 74.125.232.226 TCP 51303 > http [SYN] Seq=0 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSV=35355050 TSER=0 WS=5
>   2   0.002730 74.125.232.226 -> 192.168.28.100 TCP http > 51303 [SYN, ACK] Seq=0 Ack=1 Win=14180 Len=0 MSS=1430 SACK_PERM=1 TSV=1184565067 TSER=35325344 WS=6


Do you really have 2730 usec RTT between you and this (Google ?)
server ?

Are you sure this is not a broken middle box ?

^ permalink raw reply

* Re: [RFC 13/13] USB: Disable hub-initiated LPM for comms devices.
From: Andre Bella @ 2012-05-17 17:50 UTC (permalink / raw)
  To: Tilman Schmidt, Sarah Sharp
  Cc: gigaset307x-common, libertas-dev, Greg Kroah-Hartman, linux-usb,
	linux-wireless, users, linux-bluetooth, ath9k-devel, Alan Stern,
	Hansjoerg Lipp, netdev
In-Reply-To: <20120517173150.GE4967@xanatos>


[-- Attachment #1.1: Type: text/plain, Size: 2381 bytes --]

I dont know, sorry,

--- On Thu, 5/17/12, Sarah Sharp <sarah.a.sharp@linux.intel.com> wrote:

From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Subject: Re: [RFC 13/13] USB: Disable hub-initiated LPM for comms devices.
To: "Tilman Schmidt" <tilman@imap.cc>
Cc: gigaset307x-common@lists.sourceforge.net, libertas-dev@lists.infradead.org, "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>, linux-usb@vger.kernel.org, linux-wireless@vger.kernel.org, users@rt2x00.serialmonkey.com, linux-bluetooth@vger.kernel.org, ath9k-devel@lists.ath9k.org, "Alan Stern" <stern@rowland.harvard.edu>, "Hansjoerg Lipp" <hjlipp@web.de>, netdev@vger.kernel.org
Date: Thursday, May 17, 2012, 1:31 PM

On Thu, May 17, 2012 at 07:07:32PM +0200, Tilman Schmidt wrote:
> Am 16.05.2012 23:55, schrieb Sarah Sharp:
> > Set the disable_hub_initiated_lpm flag for for all USB communications
> > drivers.  I know there aren't currently any USB 3.0 devices that
> > implement these class specifications, but we should be ready if they do.
> 
> I follow the argument for class drivers. But this patch also
> modifies drivers for specific existing USB 2.0 only devices
> which are unlikely to ever grow USB 3.0 support, such as the
> Gigaset ISDN driver:
> 
> >  drivers/isdn/gigaset/bas-gigaset.c            |    1 +
> >  drivers/isdn/gigaset/usb-gigaset.c            |    1 +

Is there a particular reason why you think that driver is unlikely to
ever get USB 3.0 support?  I pretty much grabbed any USB driver that
looked like a communications driver without looking too closely at the
code.

> What is the interest of setting the disable_hub_initiated_lpm
> flag for these?

It's partially to lay the foundation for anyone who wants to make a USB
3.0 communications driver in the future.  They're likely to start from
some USB 2.0 class driver, and copy a lot of code.  If they notice that
flag is set in all the USB communications class drivers, they're likely
to set it as well.

I'm not quite sure where the best place to provide documentation on the
flag is.  I've added the kernel doc comments to the structure, but maybe
it needs to be documented somewhere in Documentation/usb/?

Sarah Sharp

_______________________________________________
libertas-dev mailing list
libertas-dev@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/libertas-dev

[-- Attachment #1.2: Type: text/html, Size: 3157 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel

^ permalink raw reply

* [PATCH v2] drop_monitor: convert to modular building
From: Neil Horman @ 2012-05-17 17:49 UTC (permalink / raw)
  To: netdev; +Cc: Neil Horman, David S. Miller, Eric Dumazet, Ben Hutchings
In-Reply-To: <1337178426-2470-1-git-send-email-nhorman@tuxdriver.com>

When I first wrote drop monitor I wrote it to just build monolithically.  There
is no reason it can't be built modularly as well, so lets give it that
flexibiity.

I've tested this by building it as both a module and monolithically, and it
seems to work quite well

Change notes:

v2)
* fixed for_each_present_cpu loops to be more correct as per Eric D.
* Converted exit path failures to BUG_ON as per Ben H.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: "David S. Miller" <davem@davemloft.net>
CC: Eric Dumazet <eric.dumazet@gmail.com>
CC: Ben Hutchings <bhutchings@solarflare.com>
---
 net/Kconfig             |    2 +-
 net/core/drop_monitor.c |   46 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/net/Kconfig b/net/Kconfig
index e07272d..76ad6fa 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -295,7 +295,7 @@ config NET_TCPPROBE
 	module will be called tcp_probe.
 
 config NET_DROP_MONITOR
-	boolean "Network packet drop alerting service"
+	tristate "Network packet drop alerting service"
 	depends on INET && EXPERIMENTAL && TRACEPOINTS
 	---help---
 	This feature provides an alerting service to userspace in the
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index cfeeef8..b6760a6 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -24,6 +24,7 @@
 #include <linux/timer.h>
 #include <linux/bitops.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <net/genetlink.h>
 #include <net/netevent.h>
 
@@ -225,9 +226,15 @@ static int set_all_monitor_traces(int state)
 
 	switch (state) {
 	case TRACE_ON:
+		if (!try_module_get(THIS_MODULE)) {
+			rc = -ENODEV;
+			break;
+		}
+
 		rc |= register_trace_kfree_skb(trace_kfree_skb_hit, NULL);
 		rc |= register_trace_napi_poll(trace_napi_poll_hit, NULL);
 		break;
+
 	case TRACE_OFF:
 		rc |= unregister_trace_kfree_skb(trace_kfree_skb_hit, NULL);
 		rc |= unregister_trace_napi_poll(trace_napi_poll_hit, NULL);
@@ -243,6 +250,9 @@ static int set_all_monitor_traces(int state)
 				kfree_rcu(new_stat, rcu);
 			}
 		}
+
+		module_put(THIS_MODULE);
+
 		break;
 	default:
 		rc = 1;
@@ -368,7 +378,7 @@ static int __init init_net_drop_monitor(void)
 
 	rc = 0;
 
-	for_each_present_cpu(cpu) {
+	for_each_possible_cpu(cpu) {
 		data = &per_cpu(dm_cpu_data, cpu);
 		reset_per_cpu_data(data);
 		INIT_WORK(&data->dm_alert_work, send_dm_alert);
@@ -385,4 +395,36 @@ out:
 	return rc;
 }
 
-late_initcall(init_net_drop_monitor);
+static void exit_net_drop_monitor(void)
+{
+	struct per_cpu_dm_data *data;
+	int cpu;
+
+	BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier));
+
+	/*
+	 * Because of the module_get/put we do in the trace state change path
+	 * we are guarnateed not to have any current users when we get here
+	 * all we need to do is make sure that we don't have any running timers
+	 * or pending schedule calls
+	 */
+
+	for_each_possible_cpu(cpu) {
+		data = &per_cpu(dm_cpu_data, cpu);
+		del_timer(&data->send_timer);
+		cancel_work_sync(&data->dm_alert_work);
+		/*
+		 * At this point, we should have exclusive access
+		 * to this struct and can free the skb inside it
+		 */
+		kfree_skb(data->skb);
+	}
+
+	BUG_ON(genl_unregister_family(&net_drop_monitor_family));
+}
+
+module_init(init_net_drop_monitor);
+module_exit(exit_net_drop_monitor);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Neil Horman <nhorman@tuxdriver.com>");
-- 
1.7.7.6

^ permalink raw reply related

* From Mr. Sameh Jawad
From: Mr. Sameh @ 2012-05-17 17:38 UTC (permalink / raw)



Good day,
Please I am looking for a profitable business where my client can invest some money.
I will be waiting for your positive investment idea/advice.
Best Regards,
Mr. Sameh Jawad.
 

^ permalink raw reply

* Re: [PATCH net-next] net: netdev_alloc_skb() use build_skb()
From: Willy Tarreau @ 2012-05-17 17:45 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1337276056.3403.37.camel@edumazet-glaptop>

On Thu, May 17, 2012 at 07:34:16PM +0200, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
> 
> Please note I havent tested yet this patch, lacking hardware for this.
> 
> (tg3/bnx2/bnx2x use build_skb, r8169 does a copy of incoming frames,
> ixgbe uses fragments...)
> 
> Any volunteer ?
> 
> Thanks
> 
> [PATCH net-next] net: netdev_alloc_skb() use build_skb()
> 
> netdev_alloc_skb() is used by networks driver in their RX path to
> allocate an skb to receive an incoming frame.
> 
> With recent skb->head_frag infrastructure, it makes sense to change
> netdev_alloc_skb() to use build_skb() and a frag allocator.
> 
> This permits a zero copy splice(socket->pipe), and better GRO or TCP
> coalescing.

Impressed !

For the first time I could proxy HTTP traffic at gigabit speed on this
little box powered by USB ! I've long believed that proper splicing
would make this possible and now I'm seeing it is. Congrats Eric !

I'm still observing some stalls on medium-sized files (eg: 100k,
smaller than the pipe size, don't know yet if there is any relation).
I'll check closer and try to report something more exploitable.

Cheers,
Willy

^ permalink raw reply

* [PATCH net-next] net: netdev_alloc_skb() use build_skb()
From: Eric Dumazet @ 2012-05-17 17:34 UTC (permalink / raw)
  To: Willy Tarreau, David Miller; +Cc: netdev
In-Reply-To: <1337273387.3403.24.camel@edumazet-glaptop>

From: Eric Dumazet <edumazet@google.com>

Please note I havent tested yet this patch, lacking hardware for this.

(tg3/bnx2/bnx2x use build_skb, r8169 does a copy of incoming frames,
ixgbe uses fragments...)

Any volunteer ?

Thanks

[PATCH net-next] net: netdev_alloc_skb() use build_skb()

netdev_alloc_skb() is used by networks driver in their RX path to
allocate an skb to receive an incoming frame.

With recent skb->head_frag infrastructure, it makes sense to change
netdev_alloc_skb() to use build_skb() and a frag allocator.

This permits a zero copy splice(socket->pipe), and better GRO or TCP
coalescing.

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 net/core/skbuff.c |   32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 2a18719..c02a8ec 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -293,6 +293,12 @@ struct sk_buff *build_skb(void *data, unsigned int frag_size)
 }
 EXPORT_SYMBOL(build_skb);
 
+struct netdev_alloc_cache {
+	struct page *page;
+	unsigned int offset;
+};
+static DEFINE_PER_CPU(struct netdev_alloc_cache, netdev_alloc_cache);
+
 /**
  *	__netdev_alloc_skb - allocate an skbuff for rx on a specific device
  *	@dev: network device to receive on
@@ -310,8 +316,32 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
 		unsigned int length, gfp_t gfp_mask)
 {
 	struct sk_buff *skb;
+	unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) +
+			      SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 
-	skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, NUMA_NO_NODE);
+	if (fragsz <= PAGE_SIZE && !(gfp_mask & __GFP_WAIT)) {
+		struct netdev_alloc_cache *nc;
+		void *data = NULL;
+
+		nc = &get_cpu_var(netdev_alloc_cache);
+		if (!nc->page) {
+refill:			nc->page = alloc_page(gfp_mask);
+			nc->offset = 0;
+		}
+		if (likely(nc->page)) {
+			if (nc->offset + fragsz > PAGE_SIZE) {
+				put_page(nc->page);
+				goto refill;
+			}
+			data = page_address(nc->page) + nc->offset;
+			nc->offset += fragsz;
+			get_page(nc->page);
+		}
+		put_cpu_var(netdev_alloc_cache);
+		skb = data ? build_skb(data, fragsz) : NULL;
+	} else {
+		skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, NUMA_NO_NODE);
+	}
 	if (likely(skb)) {
 		skb_reserve(skb, NET_SKB_PAD);
 		skb->dev = dev;

^ permalink raw reply related

* Re: [RFC 13/13] USB: Disable hub-initiated LPM for comms devices.
From: Sarah Sharp @ 2012-05-17 17:31 UTC (permalink / raw)
  To: Tilman Schmidt
  Cc: Greg Kroah-Hartman, linux-usb-u79uwXL29TY76Z2rM5mHXA, Alan Stern,
	Hansjoerg Lipp, linux-bluetooth-u79uwXL29TY76Z2rM5mHXA,
	gigaset307x-common-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	ath9k-devel-xDcbHBWguxHbcTqmT+pZeQ,
	libertas-dev-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	users-poMEt7QlJxcwIE2E9O76wjtx2kNaKg5H
In-Reply-To: <4FB53054.9070309-ZTO5kqT2PaM@public.gmane.org>

On Thu, May 17, 2012 at 07:07:32PM +0200, Tilman Schmidt wrote:
> Am 16.05.2012 23:55, schrieb Sarah Sharp:
> > Set the disable_hub_initiated_lpm flag for for all USB communications
> > drivers.  I know there aren't currently any USB 3.0 devices that
> > implement these class specifications, but we should be ready if they do.
> 
> I follow the argument for class drivers. But this patch also
> modifies drivers for specific existing USB 2.0 only devices
> which are unlikely to ever grow USB 3.0 support, such as the
> Gigaset ISDN driver:
> 
> >  drivers/isdn/gigaset/bas-gigaset.c            |    1 +
> >  drivers/isdn/gigaset/usb-gigaset.c            |    1 +

Is there a particular reason why you think that driver is unlikely to
ever get USB 3.0 support?  I pretty much grabbed any USB driver that
looked like a communications driver without looking too closely at the
code.

> What is the interest of setting the disable_hub_initiated_lpm
> flag for these?

It's partially to lay the foundation for anyone who wants to make a USB
3.0 communications driver in the future.  They're likely to start from
some USB 2.0 class driver, and copy a lot of code.  If they notice that
flag is set in all the USB communications class drivers, they're likely
to set it as well.

I'm not quite sure where the best place to provide documentation on the
flag is.  I've added the kernel doc comments to the structure, but maybe
it needs to be documented somewhere in Documentation/usb/?

Sarah Sharp
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: Stable regression with 'tcp: allow splice() to build full TSO packets'
From: Willy Tarreau @ 2012-05-17 17:22 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1337273387.3403.24.camel@edumazet-glaptop>

On Thu, May 17, 2012 at 06:49:47PM +0200, Eric Dumazet wrote:
> On Thu, 2012-05-17 at 18:40 +0200, Willy Tarreau wrote:
> >  try to port your patch (8d4057 tg3: provide frags as skb head) to
> > mv643xx_eth as an exercise. If I succeed and notice an improvement, I'll
> > send a patch :-)
> 
> 
> tg3 uses build_skb(), thats an API that allocates the skb after frame is
> filled by the device, to have less cache misses in RX path.
> 
> But for most devices, netdev_alloc_skb() would be more than enough.

OK, so that's out of reach for me right now.

> I'll send a patch once tested.

I'll happily give it a try.

BTW, net-next gave me around 13-14% improvement over 3.0/3.2+splice
patches ! Now I'm seeing splice() being 75% faster than recv/send, while
it used to be slower on this hardware not that long ago! That's really
impressive, great work!

Willy

^ permalink raw reply

* [PATCH V3] CS89x0 : Use ioread16/iowrite16 on all platforms
From: Jaccon Bastiaansen @ 2012-05-17 17:11 UTC (permalink / raw)
  To: arnd
  Cc: joe, romieu, s.hauer, gfm, davem, festevam, linux-arm-kernel,
	netdev, Jaccon Bastiaansen

The use of the inw/outw functions by the cs89x0 platform driver
results in NULL pointer references on ARM platforms and
platforms that do not provide ISA-style programmed I/O accessors.

Using inw/outw also accesses the wrong address space on platforms
that have a PCI I/O space that is not identity-mapped into the
physical address space.

Signed-off-by: Jaccon Bastiaansen <jaccon.bastiaansen@gmail.com>
---
 drivers/net/ethernet/cirrus/cs89x0.c |  341 ++++++++++++++++++----------------
 1 files changed, 183 insertions(+), 158 deletions(-)

diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c
index b9406cb..1d59030 100644
--- a/drivers/net/ethernet/cirrus/cs89x0.c
+++ b/drivers/net/ethernet/cirrus/cs89x0.c
@@ -222,6 +222,8 @@ struct net_local {
 	int send_underrun;	/* keep track of how many underruns in a row we get */
 	int force;		/* force various values; see FORCE* above. */
 	spinlock_t lock;
+	void __iomem *virt_addr;/* CS89x0 virtual address. */
+	unsigned long size;	/* Length of CS89x0 memory region. */
 #if ALLOW_DMA
 	int use_dma;		/* Flag: we're using dma */
 	int dma;		/* DMA channel */
@@ -230,16 +232,9 @@ struct net_local {
 	unsigned char *end_dma_buff;	/* points to the end of the buffer */
 	unsigned char *rx_dma_ptr;	/* points to the next packet  */
 #endif
-#ifdef CONFIG_CS89x0_PLATFORM
-	void __iomem *virt_addr;/* Virtual address for accessing the CS89x0. */
-	unsigned long phys_addr;/* Physical address for accessing the CS89x0. */
-	unsigned long size;	/* Length of CS89x0 memory region. */
-#endif
 };
 
 /* Index to functions, as function prototypes. */
-
-static int cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular);
 static int net_open(struct net_device *dev);
 static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t net_interrupt(int irq, void *dev_id);
@@ -267,7 +262,8 @@ static void release_dma_buff(struct net_local *lp);
 /*
  * Permit 'cs89x0_dma=N' in the kernel boot environment
  */
-#if !defined(MODULE) && (ALLOW_DMA != 0)
+#if !defined(MODULE)
+#if ALLOW_DMA
 static int g_cs89x0_dma;
 
 static int __init dma_fn(char *str)
@@ -277,9 +273,8 @@ static int __init dma_fn(char *str)
 }
 
 __setup("cs89x0_dma=", dma_fn);
-#endif	/* !defined(MODULE) && (ALLOW_DMA != 0) */
+#endif	/* ALLOW_DMA */
 
-#ifndef MODULE
 static int g_cs89x0_media__force;
 
 static int __init media_fn(char *str)
@@ -291,58 +286,6 @@ static int __init media_fn(char *str)
 }
 
 __setup("cs89x0_media=", media_fn);
-
-
-#ifndef CONFIG_CS89x0_PLATFORM
-/* Check for a network adaptor of this type, and return '0' iff one exists.
-   If dev->base_addr == 0, probe all likely locations.
-   If dev->base_addr == 1, always return failure.
-   If dev->base_addr == 2, allocate space for the device and return success
-   (detachable devices only).
-   Return 0 on success.
-   */
-
-struct net_device * __init cs89x0_probe(int unit)
-{
-	struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
-	unsigned *port;
-	int err = 0;
-	int irq;
-	int io;
-
-	if (!dev)
-		return ERR_PTR(-ENODEV);
-
-	sprintf(dev->name, "eth%d", unit);
-	netdev_boot_setup_check(dev);
-	io = dev->base_addr;
-	irq = dev->irq;
-
-	if (net_debug)
-		printk("cs89x0:cs89x0_probe(0x%x)\n", io);
-
-	if (io > 0x1ff)	{	/* Check a single specified location. */
-		err = cs89x0_probe1(dev, io, 0);
-	} else if (io != 0) {	/* Don't probe at all. */
-		err = -ENXIO;
-	} else {
-		for (port = netcard_portlist; *port; port++) {
-			if (cs89x0_probe1(dev, *port, 0) == 0)
-				break;
-			dev->irq = irq;
-		}
-		if (!*port)
-			err = -ENODEV;
-	}
-	if (err)
-		goto out;
-	return dev;
-out:
-	free_netdev(dev);
-	printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected.  Be sure to disable PnP with SETUP\n");
-	return ERR_PTR(err);
-}
-#endif
 #endif
 
 #if defined(CONFIG_MACH_IXDP2351)
@@ -369,36 +312,22 @@ writeword(unsigned long base_addr, int portno, u16 value)
 {
 	__raw_writel(value, base_addr + (portno << 1));
 }
-#else
-static u16
-readword(unsigned long base_addr, int portno)
-{
-	return inw(base_addr + portno);
-}
-
-static void
-writeword(unsigned long base_addr, int portno, u16 value)
-{
-	outw(value, base_addr + portno);
-}
 #endif
 
-static void
-readwords(unsigned long base_addr, int portno, void *buf, int length)
+static void readwords(struct net_local *lp, int portno, void *buf, int length)
 {
 	u8 *buf8 = (u8 *)buf;
 
 	do {
 		u16 tmp16;
 
-		tmp16 = readword(base_addr, portno);
+		tmp16 = ioread16(lp->virt_addr + portno);
 		*buf8++ = (u8)tmp16;
 		*buf8++ = (u8)(tmp16 >> 8);
 	} while (--length);
 }
 
-static void
-writewords(unsigned long base_addr, int portno, void *buf, int length)
+static void writewords(struct net_local *lp, int portno, void *buf, int length)
 {
 	u8 *buf8 = (u8 *)buf;
 
@@ -407,22 +336,26 @@ writewords(unsigned long base_addr, int portno, void *buf, int length)
 
 		tmp16 = *buf8++;
 		tmp16 |= (*buf8++) << 8;
-		writeword(base_addr, portno, tmp16);
+		iowrite16(tmp16, lp->virt_addr + portno);
 	} while (--length);
 }
 
 static u16
 readreg(struct net_device *dev, u16 regno)
 {
-	writeword(dev->base_addr, ADD_PORT, regno);
-	return readword(dev->base_addr, DATA_PORT);
+	struct net_local *lp = netdev_priv(dev);
+
+	iowrite16(regno, lp->virt_addr + ADD_PORT);
+	return ioread16(lp->virt_addr + DATA_PORT);
 }
 
 static void
 writereg(struct net_device *dev, u16 regno, u16 value)
 {
-	writeword(dev->base_addr, ADD_PORT, regno);
-	writeword(dev->base_addr, DATA_PORT, value);
+	struct net_local *lp = netdev_priv(dev);
+
+	iowrite16(regno, lp->virt_addr + ADD_PORT);
+	iowrite16(value, lp->virt_addr + DATA_PORT);
 }
 
 static int __init
@@ -505,7 +438,7 @@ static const struct net_device_ops net_ops = {
  */
 
 static int __init
-cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular)
+cs89x0_probe1(struct net_device *dev, void __iomem *ioaddr, int modular)
 {
 	struct net_local *lp = netdev_priv(dev);
 	static unsigned version_printed;
@@ -529,50 +462,22 @@ cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular)
 #endif
 		lp->force = g_cs89x0_media__force;
 #endif
-
         }
 
-	/* Grab the region so we can find another board if autoIRQ fails. */
-	/* WTF is going on here? */
-	if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) {
-		printk(KERN_ERR "%s: request_region(0x%lx, 0x%x) failed\n",
-				DRV_NAME, ioaddr, NETCARD_IO_EXTENT);
-		retval = -EBUSY;
-		goto out1;
-	}
+	printk(KERN_DEBUG "PP_addr at %p[%x]: 0x%x\n",
+	       ioaddr, ADD_PORT, ioread16(ioaddr + ADD_PORT));
+	iowrite16(PP_ChipID, ioaddr + ADD_PORT);
 
-	/* if they give us an odd I/O address, then do ONE write to
-           the address port, to get it back to address zero, where we
-           expect to find the EISA signature word. An IO with a base of 0x3
-	   will skip the test for the ADD_PORT. */
-	if (ioaddr & 1) {
-		if (net_debug > 1)
-			printk(KERN_INFO "%s: odd ioaddr 0x%lx\n", dev->name, ioaddr);
-	        if ((ioaddr & 2) != 2)
-	        	if ((readword(ioaddr & ~3, ADD_PORT) & ADD_MASK) != ADD_SIG) {
-				printk(KERN_ERR "%s: bad signature 0x%x\n",
-					dev->name, readword(ioaddr & ~3, ADD_PORT));
-		        	retval = -ENODEV;
-				goto out2;
-			}
-	}
-
-	ioaddr &= ~3;
-	printk(KERN_DEBUG "PP_addr at %lx[%x]: 0x%x\n",
-			ioaddr, ADD_PORT, readword(ioaddr, ADD_PORT));
-	writeword(ioaddr, ADD_PORT, PP_ChipID);
-
-	tmp = readword(ioaddr, DATA_PORT);
+	tmp = ioread16(ioaddr + DATA_PORT);
 	if (tmp != CHIP_EISA_ID_SIG) {
-		printk(KERN_DEBUG "%s: incorrect signature at %lx[%x]: 0x%x!="
+		printk(KERN_DEBUG "%s: incorrect signature at %p[%x]: 0x%x!="
 			CHIP_EISA_ID_SIG_STR "\n",
 			dev->name, ioaddr, DATA_PORT, tmp);
   		retval = -ENODEV;
-  		goto out2;
+		goto out1;
 	}
 
-	/* Fill in the 'dev' fields. */
-	dev->base_addr = ioaddr;
+	lp->virt_addr = ioaddr;
 
 	/* get the chip type */
 	rev_type = readreg(dev, PRODUCT_ID_ADD);
@@ -590,12 +495,12 @@ cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular)
 	if (net_debug  &&  version_printed++ == 0)
 		printk(version);
 
-	printk(KERN_INFO "%s: cs89%c0%s rev %c found at %#3lx ",
+	printk(KERN_INFO "%s: cs89%c0%s rev %c found at %p ",
 	       dev->name,
 	       lp->chip_type==CS8900?'0':'2',
 	       lp->chip_type==CS8920M?"M":"",
 	       lp->chip_revision,
-	       dev->base_addr);
+	       lp->virt_addr);
 
 	reset_chip(dev);
 
@@ -787,16 +692,125 @@ cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular)
 
 	retval = register_netdev(dev);
 	if (retval)
-		goto out3;
+		goto out2;
 	return 0;
-out3:
-	writeword(dev->base_addr, ADD_PORT, PP_ChipID);
 out2:
-	release_region(ioaddr & ~3, NETCARD_IO_EXTENT);
+	iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT);
 out1:
 	return retval;
 }
 
+#ifndef CONFIG_CS89x0_PLATFORM
+/*
+ * This function converts the I/O port addres used by the cs89x0_probe() and
+ * init_module() functions to the I/O memory address used by the
+ * cs89x0_probe1() function.
+ */
+static int __init
+cs89x0_ioport_probe(struct net_device *dev, unsigned long ioport, int modular)
+{
+	struct net_local *lp = netdev_priv(dev);
+	int ret;
+	void __iomem *io_mem;
+
+	if (!lp)
+		return -ENOMEM;
+
+	dev->base_addr = ioport;
+
+	if (!request_region(ioport, NETCARD_IO_EXTENT, DRV_NAME)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	io_mem = ioport_map(ioport & ~3, NETCARD_IO_EXTENT);
+	if (!io_mem) {
+		ret = -ENOMEM;
+		goto release;
+	}
+
+	/* if they give us an odd I/O address, then do ONE write to
+	   the address port, to get it back to address zero, where we
+	   expect to find the EISA signature word. An IO with a base of 0x3
+	   will skip the test for the ADD_PORT. */
+	if (ioport & 1) {
+		if (net_debug > 1)
+			printk(KERN_INFO "%s: odd ioaddr 0x%lx\n",
+			       dev->name,
+			       ioport);
+		if ((ioport & 2) != 2)
+			if ((ioread16(io_mem + ADD_PORT) & ADD_MASK) !=
+			    ADD_SIG) {
+				printk(KERN_ERR "%s: bad signature 0x%x\n",
+					dev->name,
+					ioread16(io_mem + ADD_PORT));
+				ret = -ENODEV;
+				goto unmap;
+			}
+	}
+
+	ret = cs89x0_probe1(dev, io_mem, modular);
+	if (!ret)
+		goto out;
+unmap:
+	ioport_unmap(io_mem);
+release:
+	release_region(ioport, NETCARD_IO_EXTENT);
+out:
+	return ret;
+}
+
+#ifndef MODULE
+/* Check for a network adaptor of this type, and return '0' iff one exists.
+   If dev->base_addr == 0, probe all likely locations.
+   If dev->base_addr == 1, always return failure.
+   If dev->base_addr == 2, allocate space for the device and return success
+   (detachable devices only).
+   Return 0 on success.
+   */
+
+struct net_device * __init cs89x0_probe(int unit)
+{
+	struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+	unsigned *port;
+	int err = 0;
+	int irq;
+	int io;
+
+	if (!dev)
+		return ERR_PTR(-ENODEV);
+
+	sprintf(dev->name, "eth%d", unit);
+	netdev_boot_setup_check(dev);
+	io = dev->base_addr;
+	irq = dev->irq;
+
+	if (net_debug)
+		printk(KERN_INFO "cs89x0:cs89x0_probe(0x%x)\n", io);
+
+	if (io > 0x1ff)	{	/* Check a single specified location. */
+		err = cs89x0_ioport_probe(dev, io, 0);
+	} else if (io != 0) {	/* Don't probe at all. */
+		err = -ENXIO;
+	} else {
+		for (port = netcard_portlist; *port; port++) {
+			if (cs89x0_ioport_probe(dev, *port, 0) == 0)
+				break;
+			dev->irq = irq;
+		}
+		if (!*port)
+			err = -ENODEV;
+	}
+	if (err)
+		goto out;
+	return dev;
+out:
+	free_netdev(dev);
+	printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected.  Be sure to disable PnP with SETUP\n");
+	return ERR_PTR(err);
+}
+#endif
+#endif
 
 /*********************************
  * This page contains DMA routines
@@ -956,7 +970,6 @@ static void __init reset_chip(struct net_device *dev)
 #if !defined(CONFIG_MACH_MX31ADS)
 #if !defined(CS89x0_NONISA_IRQ)
 	struct net_local *lp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
 #endif /* CS89x0_NONISA_IRQ */
 	int reset_start_time;
 
@@ -968,13 +981,15 @@ static void __init reset_chip(struct net_device *dev)
 #if !defined(CS89x0_NONISA_IRQ)
 	if (lp->chip_type != CS8900) {
 		/* Hardware problem requires PNP registers to be reconfigured after a reset */
-		writeword(ioaddr, ADD_PORT, PP_CS8920_ISAINT);
-		outb(dev->irq, ioaddr + DATA_PORT);
-		outb(0,      ioaddr + DATA_PORT + 1);
-
-		writeword(ioaddr, ADD_PORT, PP_CS8920_ISAMemB);
-		outb((dev->mem_start >> 16) & 0xff, ioaddr + DATA_PORT);
-		outb((dev->mem_start >> 8) & 0xff,   ioaddr + DATA_PORT + 1);
+		iowrite16(PP_CS8920_ISAINT, lp->virt_addr + ADD_PORT);
+		iowrite8(dev->irq, lp->virt_addr + DATA_PORT);
+		iowrite8(0, lp->virt_addr + DATA_PORT + 1);
+
+		iowrite16(PP_CS8920_ISAMemB, lp->virt_addr + ADD_PORT);
+		iowrite8((dev->mem_start >> 16) & 0xff,
+			 lp->virt_addr + DATA_PORT);
+		iowrite8((dev->mem_start >> 8) & 0xff,
+			 lp->virt_addr + DATA_PORT + 1);
 	}
 #endif /* CS89x0_NONISA_IRQ */
 
@@ -1092,6 +1107,7 @@ detect_tp(struct net_device *dev)
 static int
 send_test_pkt(struct net_device *dev)
 {
+	struct net_local *lp = netdev_priv(dev);
 	char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,
 				 0, 46, /* A 46 in network order */
 				 0, 0, /* DSAP=0 & SSAP=0 fields */
@@ -1103,8 +1119,8 @@ send_test_pkt(struct net_device *dev)
 	memcpy(test_packet,          dev->dev_addr, ETH_ALEN);
 	memcpy(test_packet+ETH_ALEN, dev->dev_addr, ETH_ALEN);
 
-        writeword(dev->base_addr, TX_CMD_PORT, TX_AFTER_ALL);
-        writeword(dev->base_addr, TX_LEN_PORT, ETH_ZLEN);
+	iowrite16(TX_AFTER_ALL, lp->virt_addr + TX_CMD_PORT);
+	iowrite16(ETH_ZLEN, lp->virt_addr + TX_LEN_PORT);
 
 	/* Test to see if the chip has allocated memory for the packet */
 	while (jiffies - timenow < 5)
@@ -1114,7 +1130,7 @@ send_test_pkt(struct net_device *dev)
 		return 0;	/* this shouldn't happen */
 
 	/* Write the contents of the packet */
-	writewords(dev->base_addr, TX_FRAME_PORT,test_packet,(ETH_ZLEN+1) >>1);
+	writewords(lp, TX_FRAME_PORT, test_packet, (ETH_ZLEN+1) >> 1);
 
 	if (net_debug > 1) printk("Sending test packet ");
 	/* wait a couple of jiffies for packet to be received */
@@ -1458,8 +1474,8 @@ static netdev_tx_t net_send_packet(struct sk_buff *skb,struct net_device *dev)
 	netif_stop_queue(dev);
 
 	/* initiate a transmit sequence */
-	writeword(dev->base_addr, TX_CMD_PORT, lp->send_cmd);
-	writeword(dev->base_addr, TX_LEN_PORT, skb->len);
+	iowrite16(lp->send_cmd, lp->virt_addr + TX_CMD_PORT);
+	iowrite16(skb->len, lp->virt_addr + TX_LEN_PORT);
 
 	/* Test to see if the chip has allocated memory for the packet */
 	if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
@@ -1473,7 +1489,7 @@ static netdev_tx_t net_send_packet(struct sk_buff *skb,struct net_device *dev)
 		return NETDEV_TX_BUSY;
 	}
 	/* Write the contents of the packet */
-	writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
+	writewords(lp, TX_FRAME_PORT, skb->data, (skb->len+1) >> 1);
 	spin_unlock_irqrestore(&lp->lock, flags);
 	dev->stats.tx_bytes += skb->len;
 	dev_kfree_skb (skb);
@@ -1499,10 +1515,9 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
 {
 	struct net_device *dev = dev_id;
 	struct net_local *lp;
-	int ioaddr, status;
+	int status;
  	int handled = 0;
 
-	ioaddr = dev->base_addr;
 	lp = netdev_priv(dev);
 
 	/* we MUST read all the events out of the ISQ, otherwise we'll never
@@ -1512,7 +1527,7 @@ static irqreturn_t net_interrupt(int irq, void *dev_id)
            course, if you're on a slow machine, and packets are arriving
            faster than you can read them off, you're screwed.  Hasta la
            vista, baby!  */
-	while ((status = readword(dev->base_addr, ISQ_PORT))) {
+	while ((status = ioread16(lp->virt_addr + ISQ_PORT))) {
 		if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status);
 		handled = 1;
 		switch(status & ISQ_EVENT_MASK) {
@@ -1608,12 +1623,12 @@ count_rx_errors(int status, struct net_device *dev)
 static void
 net_rx(struct net_device *dev)
 {
+	struct net_local *lp = netdev_priv(dev);
 	struct sk_buff *skb;
 	int status, length;
 
-	int ioaddr = dev->base_addr;
-	status = readword(ioaddr, RX_FRAME_PORT);
-	length = readword(ioaddr, RX_FRAME_PORT);
+	status = ioread16(lp->virt_addr + RX_FRAME_PORT);
+	length = ioread16(lp->virt_addr + RX_FRAME_PORT);
 
 	if ((status & RX_OK) == 0) {
 		count_rx_errors(status, dev);
@@ -1631,9 +1646,9 @@ net_rx(struct net_device *dev)
 	}
 	skb_reserve(skb, 2);	/* longword align L3 header */
 
-	readwords(ioaddr, RX_FRAME_PORT, skb_put(skb, length), length >> 1);
+	readwords(lp, RX_FRAME_PORT, skb_put(skb, length), length >> 1);
 	if (length & 1)
-		skb->data[length-1] = readword(ioaddr, RX_FRAME_PORT);
+		skb->data[length-1] = ioread16(lp->virt_addr + RX_FRAME_PORT);
 
 	if (net_debug > 3) {
 		printk(	"%s: received %d byte packet of type %x\n",
@@ -1886,7 +1901,7 @@ int __init init_module(void)
 		goto out;
 	}
 #endif
-	ret = cs89x0_probe1(dev, io, 1);
+	ret = cs89x0_ioport_probe(dev, io, 1);
 	if (ret)
 		goto out;
 
@@ -1900,8 +1915,11 @@ out:
 void __exit
 cleanup_module(void)
 {
+	struct net_local *lp = netdev_priv(dev_cs89x0);
+
 	unregister_netdev(dev_cs89x0);
-	writeword(dev_cs89x0->base_addr, ADD_PORT, PP_ChipID);
+	iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT);
+	ioport_unmap(lp->virt_addr);
 	release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
 	free_netdev(dev_cs89x0);
 }
@@ -1913,6 +1931,7 @@ static int __init cs89x0_platform_probe(struct platform_device *pdev)
 	struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
 	struct net_local *lp;
 	struct resource *mem_res;
+	void __iomem *virt_addr;
 	int err;
 
 	if (!dev)
@@ -1928,22 +1947,21 @@ static int __init cs89x0_platform_probe(struct platform_device *pdev)
 		goto free;
 	}
 
-	lp->phys_addr = mem_res->start;
 	lp->size = resource_size(mem_res);
-	if (!request_mem_region(lp->phys_addr, lp->size, DRV_NAME)) {
+	if (!request_mem_region(mem_res->start, lp->size, DRV_NAME)) {
 		dev_warn(&dev->dev, "request_mem_region() failed.\n");
 		err = -EBUSY;
 		goto free;
 	}
 
-	lp->virt_addr = ioremap(lp->phys_addr, lp->size);
-	if (!lp->virt_addr) {
+	virt_addr = ioremap(mem_res->start, lp->size);
+	if (!virt_addr) {
 		dev_warn(&dev->dev, "ioremap() failed.\n");
 		err = -ENOMEM;
 		goto release;
 	}
 
-	err = cs89x0_probe1(dev, (unsigned long)lp->virt_addr, 0);
+	err = cs89x0_probe1(dev, virt_addr, 0);
 	if (err) {
 		dev_warn(&dev->dev, "no cs8900 or cs8920 detected.\n");
 		goto unmap;
@@ -1953,9 +1971,9 @@ static int __init cs89x0_platform_probe(struct platform_device *pdev)
 	return 0;
 
 unmap:
-	iounmap(lp->virt_addr);
+	iounmap(virt_addr);
 release:
-	release_mem_region(lp->phys_addr, lp->size);
+	release_mem_region(mem_res->start, lp->size);
 free:
 	free_netdev(dev);
 	return err;
@@ -1965,10 +1983,17 @@ static int cs89x0_platform_remove(struct platform_device *pdev)
 {
 	struct net_device *dev = platform_get_drvdata(pdev);
 	struct net_local *lp = netdev_priv(dev);
+	struct resource *mem_res;
 
+	/*
+	 * This platform_get_resource() call will not return NULL, because
+	 * the same call in cs89x0_platform_probe() has returned a non NULL
+	 * value.
+	 */
+	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	unregister_netdev(dev);
 	iounmap(lp->virt_addr);
-	release_mem_region(lp->phys_addr, lp->size);
+	release_mem_region(mem_res->start, lp->size);
 	free_netdev(dev);
 	return 0;
 }
-- 
1.7.1

^ permalink raw reply related

* Re: [RFC 13/13] USB: Disable hub-initiated LPM for comms devices.
From: Tilman Schmidt @ 2012-05-17 17:07 UTC (permalink / raw)
  To: Sarah Sharp
  Cc: Greg Kroah-Hartman, linux-usb-u79uwXL29TY76Z2rM5mHXA, Alan Stern,
	Hansjoerg Lipp, linux-bluetooth-u79uwXL29TY76Z2rM5mHXA,
	gigaset307x-common-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	ath9k-devel-xDcbHBWguxHbcTqmT+pZeQ,
	libertas-dev-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	users-poMEt7QlJxcwIE2E9O76wjtx2kNaKg5H
In-Reply-To: <3c634afbbe15598cdcbf77bb9393d22ad4bfa373.1337203535.git.sarah.a.sharp-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 892 bytes --]

Am 16.05.2012 23:55, schrieb Sarah Sharp:
> Set the disable_hub_initiated_lpm flag for for all USB communications
> drivers.  I know there aren't currently any USB 3.0 devices that
> implement these class specifications, but we should be ready if they do.

I follow the argument for class drivers. But this patch also
modifies drivers for specific existing USB 2.0 only devices
which are unlikely to ever grow USB 3.0 support, such as the
Gigaset ISDN driver:

>  drivers/isdn/gigaset/bas-gigaset.c            |    1 +
>  drivers/isdn/gigaset/usb-gigaset.c            |    1 +

What is the interest of setting the disable_hub_initiated_lpm
flag for these?

Thanks,
Tilman

-- 
Tilman Schmidt                    E-Mail: tilman-ZTO5kqT2PaM@public.gmane.org
Bonn, Germany
In theory there is no difference between theory and practice.
In practice there is. (Yogi Berra)


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply

* Re: [PATCH v5 2/2] decrement static keys on real destroy time
From: Andrew Morton @ 2012-05-17 17:02 UTC (permalink / raw)
  To: Glauber Costa
  Cc: cgroups, linux-mm, devel, kamezawa.hiroyu, netdev, Tejun Heo,
	Li Zefan, Johannes Weiner, Michal Hocko
In-Reply-To: <4FB4CA4D.50608@parallels.com>

On Thu, 17 May 2012 13:52:13 +0400 Glauber Costa <glommer@parallels.com> wrote:

> Andrew is right. It seems we will need that mutex after all. Just this 
> is not a race, and neither something that should belong in the 
> static_branch interface.

Well, a mutex is one way.  Or you could do something like

	if (!test_and_set_bit(CGPROTO_ACTIVATED, &cg_proto->flags))
		static_key_slow_inc(&memcg_socket_limit_enabled);

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ 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