Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next] vlan: static functions
From: David Miller @ 2011-12-14  7:47 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, bcrl
In-Reply-To: <1323845874.2846.22.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 14 Dec 2011 07:57:54 +0100

> commit 6d4cdf47d2 (vlan: add 802.1q netpoll support) forgot to declare
> as static some private functions.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied.

^ permalink raw reply

* Re: [patch] vlan: add rtnl_dereference() annotations
From: David Miller @ 2011-12-14  7:47 UTC (permalink / raw)
  To: dan.carpenter; +Cc: kaber, netdev, kernel-janitors, jpirko
In-Reply-To: <20111214062943.GD7499@elgon.mountain>

From: Dan Carpenter <dan.carpenter@oracle.com>
Date: Wed, 14 Dec 2011 09:29:43 +0300

> The original code generates a Sparse warning:
> net/8021q/vlan_core.c:336:9:
> 	error: incompatible types in comparison expression (different address spaces)
> 
> It's ok to dereference __rcu pointers here because we are holding the
> RTNL lock.  I've added some calls to rtnl_dereference() to silence the
> warning.
> 
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

Applied.

^ permalink raw reply

* Re: [PATCH 1/1] tcp: fix spurious undos in CA_Open
From: Ilpo Järvinen @ 2011-12-14  8:57 UTC (permalink / raw)
  To: Neal Cardwell; +Cc: David Miller, Netdev, nanditad, Yuchung Cheng, therbert
In-Reply-To: <CADVnQy=kw6MgySY+xF7WcB+0fXyDYk66Phc1R+dBK8=emu6kXQ@mail.gmail.com>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 5753 bytes --]

On Mon, 12 Dec 2011, Neal Cardwell wrote:

> On Mon, Dec 12, 2011 at 7:05 AM, Ilpo Järvinen
> <ilpo.jarvinen@helsinki.fi> wrote:
> > On Mon, 28 Nov 2011, Neal Cardwell wrote:
> >
> >> On Sun, Nov 27, 2011 at 6:58 PM, David Miller <davem@davemloft.net> wrote:
> >>
> >> >> Also, one (serious) word of caution! This change, by its extending of
> >> >> CA_Open state, is somewhat similar to what I made FRTO years ago, and
> >> >> managed to introduces subtle breaking to the state machine. Please check
> >> >> that the problem similar to what was fixed by
> >> >> a1c1f281b84a751fdb5ff919da3b09df7297619f does not reappear (possibly in
> >> >> some other form causing spurious undos). ...To me it seems that
> >> >> tcp_packet_delayed might be similarly confused after the given patch.
> >> >
> >> > Neil, please look into this so we can have any such issues fixed
> >> > in time for the next merge window.
> >>
> >> Absolutely. I will look into the areas that Ilpo mentioned.
> >
> > Unfortunately nothing has happened? So I finally had to come up something
> > myself. ...Compile tested only.
> 
> Sorry for the radio silence, but I have been looking at this. So far
> it's been a time-consuming process, as we've uncovered a number of
> pre-existing issues in tcp_packet_delayed that seem like quite serious
> bugs:
> 
> 1) tcp_packet_delayed implicitly assumes, but does not verify, that
> the ACK in question (whose ECR field precedes retrans_stamp) covers
> all retransmitted segments. So if we retransmit segments 1 and 2, and
> then get an ACK for 1 that has an ECR indicating it was for the
> original copy of segment 1, then we undo,  even in cases where segment
> 2 really was lost and needed to be retransmitted.

I think this might be an mis-implementation in tcp_try_undo_partial.

> 2) tcp_packet_delayed implicitly assumes that if we retransmit a
> packet that was truly lost then any ACK for the retransmitted instance
> of that packet will echo the timestamp field in the retransmitted
> packet. But if the receiver is implementing delayed ACKs and correctly
> implements timestamps per RFC 1323, then the receiver will be obeying
> this clause: "Thus, when delayed ACKs are in use, the receiver should
> reply with the TSval field from the earliest unacknowledged segment."
> Thus tcp_packet_delayed can cause spurious undos in the following
> circumstances:
>
> - send segment 1 with tsval 10
> - receiver is doing delayed ACKs and does not ACK 1 but sets TS.Recent to 10
> - send segment 2 with tsval 20
> - segment 2 is lost in transit
> - RTO, retransmit segment 2 with tsval 30
> - receiver sends delayed ACK for packets 1 and 2 with TS.Recent of 10
> - sender receives ACK for packet 2 with tsecho of 10, lower than 30,
> and thinks RTO was spurious

About this I'm actually aware of, I have even some long email postponed 
related to this to discuss in context of 1323bis (as 1323bis seems pretty 
much standstill I'm not in a big hurry :-)). I think 1323 algo is flawed 
anyway and it was fixed/clarified/better in the bis (which doesn't 
address this well enough though).

I discovered this while I setup a network with ACK losses to figure out 
other issue. I discovered that the RTT measurements occassionally took 
"the wrong TS" bloating the RTT estimate. As RTT samples included RTO 
delays, with enough ACK losses the RTO eventually hits the max value. 
...As a result, not very nice performance was acquired for that such a 
flow.

I think there are two possible solutions:
  1) Echo latest timestamp for below window packets (I'm not sure if 
  there's can of worms w.r.t. security in this approach). A good thing
  in this would be that it would really solve the rexmit ambiguity problem 
  which the current approach does not do.
  2) Ignore packets with DSACK in RTT measurement.

1323bis is not of much help in this which TS to echo (which is why I 
intented to mention it on tcpm). IIRC, it depended on which takes 
precedence: RFC793 in-window check or the given TS algorithm, which is 
not discussed anywhere.

> For better or worse, both of these bugs appear to be inherited from
> the Eifel Detection Algorithm RFC (RFC 3522).

RFC3522 does not have the issue 1) as it's working after RTO+first ACK 
only. The second issue is valid for it though.

> In any case, we've been working on coming up with a solution for these issues.
> 
> > --
> > [PATCH 1/1] tcp: fix spurious undos in CA_Open
> >
> > There's a landmine in tcp_packet_delayed. In CA_Open the
> > retrans_stamp is very eagerly cleared which falsely triggers
> > packet-delayed detection. Therefore this code cannot be used
> > in CA_Open if the retrans_stamp was already cleared.
> >
> > This became issue once DSACK detection was extended to happen
> > in CA_Open state too (f698204bd0b, tcp: allow undo from
> > reordered DSACKs). Essentially the whole congestion control
> > is disabled because the undos now always restore the previous
> > window. I wonder if this was already in production... ...at
> > least the Internet didn't melt ;-).
> 
> I'm pretty sure this commit is unnecessary. It seems like a NOP. Note
> that tcp_may_undo and tcp_packet_delayed are never called in state
> TCP_CA_Open. tcp_may_undo is only called from tcp_try_undo_recovery,
> tcp_try_undo_partial, and tcp_try_undo_loss, and to call any of these
> functions you must be in either TCP_CA_Loss or TCP_CA_Recovery. Only
> tcp_try_undo_dsack is called from TCP_CA_Open, but it makes no
> reference to retrans_stamp.

It seems that I've missed this difference in tcp_try_undo_dsack (well, 
seen it but never thought it that much). I think you're right. Thanks for 
taking a look.

Some WARN_ON to enforce this !CA_Open condition there might not hurt 
though.

-- 
 i.

^ permalink raw reply

* [PATCH] SUNRPC: make SUNPRC clients list per network namespace context
From: Stanislav Kinsbursky @ 2011-12-14  9:19 UTC (permalink / raw)
  To: Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA
  Cc: linux-nfs-u79uwXL29TY76Z2rM5mHXA, xemul-bzQdu9zFT3WakBO8gow8eQ,
	neilb-l3A5Bk7waGM, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	jbottomley-bzQdu9zFT3WakBO8gow8eQ, bfields-uC3wQj2KruNg9hUCZPvPmw,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, devel-GEFAQzZX7r8dnm+yROfE0A

This patch moves static SUNRPC clients list and it's lock to sunrpc_net
structure.
Currently this list is used only for debug purposes. But later it will be used
also for selecting clients by networks namespace on PipeFS mount/umount events.
Per-network namespace lists will make this faster and simplier.

Note: client list is taken from "init_net" network namespace context in
rpc_show_tasks(). This will be changed with making SUNRPC sysctl's per network
namespace context.

Signed-off-by: Stanislav Kinsbursky <skinsbursky-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>

---
 include/linux/sunrpc/sched.h |    3 ++-
 net/sunrpc/clnt.c            |   26 +++++++++++++++-----------
 net/sunrpc/netns.h           |    3 +++
 net/sunrpc/sunrpc_syms.c     |    3 +++
 net/sunrpc/sysctl.c          |    4 +++-
 5 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index e775689..b16243a 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -244,7 +244,8 @@ int		rpciod_up(void);
 void		rpciod_down(void);
 int		__rpc_wait_for_completion_task(struct rpc_task *task, int (*)(void *));
 #ifdef RPC_DEBUG
-void		rpc_show_tasks(void);
+struct net;
+void		rpc_show_tasks(struct net *);
 #endif
 int		rpc_init_mempool(void);
 void		rpc_destroy_mempool(void);
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index f0268ea..c5f04aa 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -38,6 +38,7 @@
 #include <linux/sunrpc/bc_xprt.h>
 
 #include "sunrpc.h"
+#include "netns.h"
 
 #ifdef RPC_DEBUG
 # define RPCDBG_FACILITY	RPCDBG_CALL
@@ -50,8 +51,6 @@
 /*
  * All RPC clients are linked into this list
  */
-static LIST_HEAD(all_clients);
-static DEFINE_SPINLOCK(rpc_client_lock);
 
 static DECLARE_WAIT_QUEUE_HEAD(destroy_wait);
 
@@ -81,16 +80,20 @@ static int	rpc_ping(struct rpc_clnt *clnt);
 
 static void rpc_register_client(struct rpc_clnt *clnt)
 {
-	spin_lock(&rpc_client_lock);
-	list_add(&clnt->cl_clients, &all_clients);
-	spin_unlock(&rpc_client_lock);
+	struct sunrpc_net *sn = net_generic(clnt->cl_xprt->xprt_net, sunrpc_net_id);
+
+	spin_lock(&sn->rpc_client_lock);
+	list_add(&clnt->cl_clients, &sn->all_clients);
+	spin_unlock(&sn->rpc_client_lock);
 }
 
 static void rpc_unregister_client(struct rpc_clnt *clnt)
 {
-	spin_lock(&rpc_client_lock);
+	struct sunrpc_net *sn = net_generic(clnt->cl_xprt->xprt_net, sunrpc_net_id);
+
+	spin_lock(&sn->rpc_client_lock);
 	list_del(&clnt->cl_clients);
-	spin_unlock(&rpc_client_lock);
+	spin_unlock(&sn->rpc_client_lock);
 }
 
 static int
@@ -1852,14 +1855,15 @@ static void rpc_show_task(const struct rpc_clnt *clnt,
 		task->tk_action, rpc_waitq);
 }
 
-void rpc_show_tasks(void)
+void rpc_show_tasks(struct net *net)
 {
 	struct rpc_clnt *clnt;
 	struct rpc_task *task;
 	int header = 0;
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
-	spin_lock(&rpc_client_lock);
-	list_for_each_entry(clnt, &all_clients, cl_clients) {
+	spin_lock(&sn->rpc_client_lock);
+	list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
 		spin_lock(&clnt->cl_lock);
 		list_for_each_entry(task, &clnt->cl_tasks, tk_task) {
 			if (!header) {
@@ -1870,6 +1874,6 @@ void rpc_show_tasks(void)
 		}
 		spin_unlock(&clnt->cl_lock);
 	}
-	spin_unlock(&rpc_client_lock);
+	spin_unlock(&sn->rpc_client_lock);
 }
 #endif
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index d013bf2..6010c46 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -9,6 +9,9 @@ struct cache_detail;
 struct sunrpc_net {
 	struct proc_dir_entry *proc_net_rpc;
 	struct cache_detail *ip_map_cache;
+
+	struct list_head all_clients;
+	spinlock_t rpc_client_lock;
 };
 
 extern int sunrpc_net_id;
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 8ec9778..e57aa10 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -29,6 +29,7 @@ int sunrpc_net_id;
 static __net_init int sunrpc_init_net(struct net *net)
 {
 	int err;
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
 	err = rpc_proc_init(net);
 	if (err)
@@ -38,6 +39,8 @@ static __net_init int sunrpc_init_net(struct net *net)
 	if (err)
 		goto err_ipmap;
 
+	INIT_LIST_HEAD(&sn->all_clients);
+	spin_lock_init(&sn->rpc_client_lock);
 	return 0;
 
 err_ipmap:
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index e65dcc6..af7d339 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -20,6 +20,8 @@
 #include <linux/sunrpc/stats.h>
 #include <linux/sunrpc/svc_xprt.h>
 
+#include "netns.h"
+
 /*
  * Declare the debug flags here
  */
@@ -110,7 +112,7 @@ proc_dodebug(ctl_table *table, int write,
 		*(unsigned int *) table->data = value;
 		/* Display the RPC tasks on writing to rpc_debug */
 		if (strcmp(table->procname, "rpc_debug") == 0)
-			rpc_show_tasks();
+			rpc_show_tasks(&init_net);
 	} else {
 		if (!access_ok(VERIFY_WRITE, buffer, left))
 			return -EFAULT;

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" 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 related

* Re: [PATCH] bridge: push blocking slaves to forwarding when turning stp off
From: Vitalii Demianets @ 2011-12-14  9:32 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, bridge
In-Reply-To: <20111213161613.0c59ab36@nehalam.linuxnetplumber.net>

On Wednesday 14 December 2011 02:16:13 Stephen Hemminger wrote:
> On Tue, 13 Dec 2011 11:36:25 +0200
>
> Vitalii Demianets <vitas@nppfactor.kiev.ua> wrote:
> > If there is a slave in blocking state when stp is turned off, that slave
> > will remain in blocking state for indefinitely long time until interface
> > state changed. We should push all blocking slaves into forwarding state
> > after turning stp off.
> >
> > Signed-off-by: Vitalii Demianets <vitas@nppfactor.kiev.ua>
>
> Maybe. But if the port was in the blocking state then STP must have
> decided there was a loop in the network if that port was used.
> Therefore blindly putting the port into forwarding state could cause
> disastrous network flood.
>
>
> The user can force the port back out of blocking state (via sysfs).
>

1) That blocking state in the absence of STP is not stable. It will eventually 
flip to forwarding sooner or later on the first call of 
br_port_state_selection(). For example, when user changes MAC address on 
another slave. Or even worse - when any other slave of the bridge changes its 
carrier state. Don't think user wants such unpredictable state changes.

2) There is also another drawback of not pushing ports into forwarding state 
after turning off USER_STP mode. Possible scenario is:
  a) bridge in USER_STP mode, all ports are in non-forwarding state (blocking, 
learning)
  b) user turns off STP. Without the patch ports are not advanced to the 
forwarding state and are left in the states they are (the timers do not work 
because of USER_STP mode)
  c) The bridge stays in no-carrier state until something happens (carrier 
state transition on one of the slaves, MAC address change etc)

You can say again that in the above two cases user can manually set the state 
of the slaves to forwarding.  But to account all possible cases one should 
always unconditionally do it for all the slaves each time when stp is being 
turned off. So why not to automate the task?

3) The initial intention of the code in br_stp_stop() was to get ports out of 
blocking state when stp is being turned off. It fails to achieve the goal, 
and patch just fixes it.

4) If user turns stp off he clearly indicates that she wants all ports to work 
in stateless mode and that he will deal with possible network loops on 
himself. Should we in that case guess network topology basing on loose 
assumptions and leave ports in unstable blocking state (and they will flip 
eventually to the forwarding state in unpredictable times as mentioned 
above)?

-- 
Vitalii Demianets

^ permalink raw reply

* Re: kenel level packet capturing
From: Jasper Spaans @ 2011-12-14  9:34 UTC (permalink / raw)
  To: David Miller; +Cc: raviraj.j1991@gmail.com, netdev@vger.kernel.org
In-Reply-To: <20111213.133629.1213042365300662857.davem@davemloft.net>

On 13/12/11 19:36, David Miller wrote:
> We have decided to use PF_RING(a kernel module to capture packets) for
> the same due to the number of advantages.
> What "advantages"?  The AF_PACKET socket layer already upstream in the
> kernel supports every relevant performance feature PF_RING does, and
> then some.
Some documentation for fanout is one feature that would be nice. (How to
use it from userspace - after 5 minutes of googling, the first place
where I could find an example is in the suricata source code[1]).

Having not tested it in practice, so my assumptions about rxhash might
be untrue: is there an option to override the NIC rxhash
implementations? if you are doing packet capturing, you will probably
see traffic in both directions, so hashing on the address-tuples of both
directions makes sense (or else both half-streams of tcp packets might
end up being sent to different sockets.

It seems hardware vendors are focussed on only hashing the senders
address, which does make sense if you're building a
fileserver/webserver/whatever.

We ended up using atrocious bpfs like "((tcp[0:2] & 1) == (tcp[2:2] &
1)) and tcp" to distribute packets over multiple sockets, and now our
bottleneck has shifted away from the capturing side of our application.

(Note to Raviraj: we're not using PF_RING because of stability issues -
it crashed our testing system one too many times.)

Cheers,
Jasper

[1]
https://redmine.openinfosecfoundation.org/embedded/suricata/source-af-packet_8c-source.html#l00516

-- 
 /\____/\   Ir. Jasper Spaans      
 \   (_)/   Fox-IT Experts in IT Security!
  \    X    T: +31-15-2847999
   \  / \   M: +31-6-41588725   
    \/      KvK Haaglanden 27301624

^ permalink raw reply

* Re: kenel level packet capturing
From: Eric Dumazet @ 2011-12-14  9:56 UTC (permalink / raw)
  To: Jasper Spaans
  Cc: David Miller, raviraj.j1991@gmail.com, netdev@vger.kernel.org
In-Reply-To: <4EE86DB6.5050303@fox-it.com>

Le mercredi 14 décembre 2011 à 10:34 +0100, Jasper Spaans a écrit :
> On 13/12/11 19:36, David Miller wrote:
> > We have decided to use PF_RING(a kernel module to capture packets) for
> > the same due to the number of advantages.
> > What "advantages"?  The AF_PACKET socket layer already upstream in the
> > kernel supports every relevant performance feature PF_RING does, and
> > then some.
> Some documentation for fanout is one feature that would be nice. (How to
> use it from userspace - after 5 minutes of googling, the first place
> where I could find an example is in the suricata source code[1]).
> 
> Having not tested it in practice, so my assumptions about rxhash might
> be untrue: is there an option to override the NIC rxhash
> implementations? if you are doing packet capturing, you will probably
> see traffic in both directions, so hashing on the address-tuples of both
> directions makes sense (or else both half-streams of tcp packets might
> end up being sent to different sockets.
> 

Disabling NIC rxhash is possible :

# ethtool -k eth2 | grep receive-hashing
receive-hashing: on
# ethtool -K eth2 rxhash off
# ethtool -k eth2 | grep receive-hashing
receive-hashing: off

> It seems hardware vendors are focussed on only hashing the senders
> address, which does make sense if you're building a
> fileserver/webserver/whatever.
> 
> We ended up using atrocious bpfs like "((tcp[0:2] & 1) == (tcp[2:2] &
> 1)) and tcp" to distribute packets over multiple sockets, and now our
> bottleneck has shifted away from the capturing side of our application.

If you want to distribute load on tcp sockets, you can take a look at
various tricks documented in Documentation/networking/scaling.txt

(RPS, RFS, ...)


> (Note to Raviraj: we're not using PF_RING because of stability issues -
> it crashed our testing system one too many times.)
> 
> Cheers,
> Jasper
> 
> [1]
> https://redmine.openinfosecfoundation.org/embedded/suricata/source-af-packet_8c-source.html#l00516
> 

^ permalink raw reply

* [PATCH net-next 1/1] bnx2x: handle vpd data longer than 128 bytes
From: Barak Witkowski @ 2011-12-14 10:14 UTC (permalink / raw)
  To: davem, netdev; +Cc: Barak Witkowski, Eilon Greenstein
In-Reply-To: <Barak Witkowski <barak@broadcom.com>

Signed-off-by: Barak Witkowski <barak@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c |   35 +++++++++++++++++----
 1 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index b45baf9..ffeaaa9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -9931,30 +9931,49 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
 static void __devinit bnx2x_read_fwinfo(struct bnx2x *bp)
 {
 	int cnt, i, block_end, rodi;
-	char vpd_data[BNX2X_VPD_LEN+1];
+	char vpd_start[BNX2X_VPD_LEN+1];
 	char str_id_reg[VENDOR_ID_LEN+1];
 	char str_id_cap[VENDOR_ID_LEN+1];
+	char *vpd_data;
+	char *vpd_extended_data = NULL;
 	u8 len;
 
-	cnt = pci_read_vpd(bp->pdev, 0, BNX2X_VPD_LEN, vpd_data);
+	cnt = pci_read_vpd(bp->pdev, 0, BNX2X_VPD_LEN, vpd_start);
 	memset(bp->fw_ver, 0, sizeof(bp->fw_ver));
 
 	if (cnt < BNX2X_VPD_LEN)
 		goto out_not_found;
 
-	i = pci_vpd_find_tag(vpd_data, 0, BNX2X_VPD_LEN,
+	/* VPD RO tag should be first tag after identifier string, hence
+	 * we should be able to find it in first BNX2X_VPD_LEN chars
+	 */
+	i = pci_vpd_find_tag(vpd_start, 0, BNX2X_VPD_LEN,
 			     PCI_VPD_LRDT_RO_DATA);
 	if (i < 0)
 		goto out_not_found;
 
-
 	block_end = i + PCI_VPD_LRDT_TAG_SIZE +
-		    pci_vpd_lrdt_size(&vpd_data[i]);
+		    pci_vpd_lrdt_size(&vpd_start[i]);
 
 	i += PCI_VPD_LRDT_TAG_SIZE;
 
-	if (block_end > BNX2X_VPD_LEN)
-		goto out_not_found;
+	if (block_end > BNX2X_VPD_LEN) {
+		vpd_extended_data = kmalloc(block_end, GFP_KERNEL);
+		if (vpd_extended_data  == NULL)
+			goto out_not_found;
+
+		/* read rest of vpd image into vpd_extended_data */
+		memcpy(vpd_extended_data, vpd_start, BNX2X_VPD_LEN);
+		cnt = pci_read_vpd(bp->pdev, BNX2X_VPD_LEN,
+				   block_end - BNX2X_VPD_LEN,
+				   vpd_extended_data + BNX2X_VPD_LEN);
+		if (cnt < (block_end - BNX2X_VPD_LEN))
+			goto out_not_found;
+		vpd_data = vpd_extended_data;
+	} else
+		vpd_data = vpd_start;
+
+	/* now vpd_data holds full vpd content in both cases */
 
 	rodi = pci_vpd_find_info_keyword(vpd_data, i, block_end,
 				   PCI_VPD_RO_KEYWORD_MFR_ID);
@@ -9986,9 +10005,11 @@ static void __devinit bnx2x_read_fwinfo(struct bnx2x *bp)
 				bp->fw_ver[len] = ' ';
 			}
 		}
+		kfree(vpd_extended_data);
 		return;
 	}
 out_not_found:
+	kfree(vpd_extended_data);
 	return;
 }
 
-- 
1.7.7.4

^ permalink raw reply related

* Re: [WARNING - VERY LONG] A sysadmin's understanding of HFSC and IFB
From: John A. Sullivan III @ 2011-12-14 10:32 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1323817279.8451.7.camel@denise.theartistscloset.com>

On Tue, 2011-12-13 at 18:01 -0500, John A. Sullivan III wrote:
> On Fri, 2011-12-09 at 08:59 +0100, Eric Dumazet wrote:
> > Le vendredi 09 décembre 2011 à 02:17 -0500, John A. Sullivan III a
> > écrit :
> > > Hello, all.  I've been trying to summarize my last week's worth of
> > > research into HFSC and IFB.  Being neither a developer nor a
> > > mathematician, I found most of the existing documentation daunting and
> > > am truly grateful for the help I received on this list to understand the
> > > technologies.
> > > 
> > > I do not currently have a blog to post this research and so was thinking
> > > of posting it to this list so that it could be archived and searchable
> > > for other poor sysadmin types like me to save them the days of
> > > struggling to get their practical heads around the concepts.
> > > 
> > > However, since this is probably a 15 page or so document, I realized
> > > this could be quite rude to those on dial up or metered connections.
> > > Would it be appropriate to post my summary here? Thanks - John
> > > 
> > 
> > Please post here, thats definitely a good idea.
> > 
> > I am pretty sure your contribution could serve to add a page to 
> > 
> > http://www.linuxfoundation.org/collaborate/workgroups/networking/group
> > 
> > I believe we lack documentation. A lot.
> <snip>
> OK - it's almost ready.  The only problem I know if is that, when I do
> the math based upon my explanation, I sometimes violate an rt curve when
> I should not.  I posed that in an email to the list entitled "An error
> in my HFSC sysadmin documentation".  If anyone can figure out where my
> error is, I will gladly change the documentation.  Here's what I have.
> The graphics except the ASCII art are obviously missing.  All
> corrections and suggestions very gratefully accepted - John
> 
<snip>
Thanks to Michal's help, I took the time to understand how service
curves are updated and the practical implications for system
administration.  I thus added two sections to the very end of the
document - one on service curve update details and the other on general
guidelines.  I'll paste in those additions here. They bring the entire
document to somewhere around 22 pages.  Unfortunately, the non-ascii
graphics will be lost in the email.

PLEASE PROTECT OTHERS FROM ME :) This document is based upon my very new
and raw knowledge.  I have not yet run this through our lab and do not
have practical experience.  I would hate for this email to become an
authoritative document simply by its presence.  If there is something
wrong, please point it out.  Thanks.  Here goes:


Service curve updates in detail
This section is probably beyond what most system administrators need to
know to configure their systems but is included for completeness or for
those who may need more information to troubleshoot a configuration
which may not be behaving as expected.  If you do not need this much
detail, skip to the summary guidelines section.
As mentioned above, it is the complicated subject of updating service
curves which transforms HFSC's ability to guarantee latency separately
from bandwidth from an interesting theory with little practical
application into a fabulously powerful and practical traffic shaping
tool.  So how do these updates work?
Service curves are usually represented as a two dimensional graph - a
line with either one or two slopes with an x and y axis.  The x axis is
elapsed time and the y axis is service or work rendered.  Translated out
of mathematical formula terms and into system administrator terms, the
work or service rendered is the number of bits sent out of the queue.
That's why the slope of the line equals the bandwidth.  If we choose a
dot on the line (curve) where the y coordinate is 100kbits dequeued and
the x coordinate is 100ms elapsed, then the slope is 100kbits/0.1s = 1
Mbps.
When a queue first becomes backlogged, i.e., when it first has packets
to send, it starts to track the service curve, i.e., how many bits have
been delivered over how much time.  While it is backlogged, i.e., has
packets to send, the queue is active.  Once the packets are all dequeued
and there are no more to send, the queue becomes passive.  Now more
packets arrive and the queue becomes active, backlogged.  At this point,
the service curve needs to be updated.  We'll walk through this process
in several stages of increasing complexity.
The bottom line is that HFSC will dequeue the packets at the lesser of
the work which would have been rendered if we had been continually using
the previous service curve (the curve we were using when the queue was
last backlogged) or the work that would be rendered if we started the
queue over again.  What in the world does that mean?! Once we understand
it, it is actually a very practical way of making sure we can always
meet our guarantees and not overrun our circuit as long as the sum of
the rt m2 curves does not exceed the total bandwidth, i.e., as long as
we sys admins have done our job properly.  Let's take it apart piece by
piece to understand it.
Let's start with a very simple, monolinear rt service curve (i.e., the
m1 slope = the m2 slope) with no link sharing (no extra bandwidth
allocated).  Let's say the guaranteed bandwidth is 100 kbps.  Let's say
the queue initially goes active for one second so we have transmitted
100 kbits:
        |
200kbits|
        |
        |
100kbits|  x/
        |  /
        | /
  0kbits|/_________
        0s 1s 2s
Now let's say the queue goes passive, i.e., nothing to transmit, for one
second taking us to a total elapsed time of 2 seconds and the goes
active again.  HFSC will extrapolate what the total number of bits
dequeued (in HFSC terms, work performed) would have been if there had
been no passive period.  It then compares this to the total number of
bits transmitted so far (work already performed) plus how many new bits
we would transmit if we started the rt curve over again (this will make
more sense when we demonstrate this with dilinear curves).  It chooses
whichever would result is the least amount of work performed, i.e., the
fewest bits dequeued.  I'll represent this in the graph below by
extrapolating the first curve, sliding the amount of data already
transmitted (the x) over to the new elapsed time (the time the queue
became backlogged again), and then starting the original line from that
point:
300kbits|        z/
        |        /
        |       /
200kbits|      / z/ 
        |     /  /
        |    /  /
100kbits|  x/.x/
        |  /
        | /
  0kbits|/_________
        0s 1  2  3
Using the rt curve starting over again results in less work than if we
had been continually transmitting using the previous service curve (z)
so that is the rate at which we will dequeue.  In the case of monolinear
curves, that will always be the case.  It may not be the case in
dilinear curves.  Look at this illustration taken once more from
http://www.sonycsl.co.jp/~kjc/software/TIPS.txt :
                                                     ________
                                     ________--------
                                    /                  ______
                                   /   ________--------
                       ________---+----        
                      /          /             
                     /          /              
    total    ->     /          + new coordinate                
                   /                           
                  /                            
           service curve       |
                 of            +
          previous period   current
                             time

                        Update Operation

                                                       ______
                                       ________--------
                                  +----        
                                 /             
                                /              
    total    ->                + new coordinate                
                                               
                                               
                               |
                               +
                             current
                             time

                        New Service Curve

That can be a bit confusing. Let's go back and take it one step at a
time.  Unfortunately for those viewing this in text only, the next
several illustrations are difficult to render in ASCII art so we will
use graphics.
Let's consider the same monolinear rt service curve but this time there
will be some additional bandwidth added due to link sharing.
The solid black line is the first backlog period m2 curve, i.e., the
guaranteed bandwidth (100 kbits/s).  It is backlogged for 1s.  However,
more data is transmitted than 100 kbits because link sharing has
allocated another 50 kbps so the total data transmitted is 150 kbps.
This is represented by the green line.  The link goes passive for 1s and
then goes active again for another 1s.  The dashed black line shows the
data trajectory of the previous service curve, i.e., it shows how much
work would have been done (how many bits would have been dequeued) if it
had remained backlogged.  That is one point of comparison. The second
point of comparison is to take the total actual work done (the total
bits transmitted so far) and use that as the y starting point for a new
curve beginning with x at the current time.  This is the blue line.  The
only difference from the first illustration is that the second point
started  at a higher point on the y axis, i.e., with more bits already
dequeued, than the last time because of the link sharing bandwidth.  The
end result is the same - the new curve is chosen as the dequeuing rate.
What happens if link sharing gave us a lot of extra bandwidth, say 200
kbs?
In this case, so much extra data was transmitted that the amount of work
done by starting the curve over again exceeds the amount of work that
would have been done if the previous service curve had remained
backlogged so HFSC will choose to dequeue at the rate of the previous
service curve.  However, once again, the end result is the same because
the slope of the curves are the same, i.e., the bandwidth.




Now let's make the leap to see what happens with dilinear service
curves, i.e., where we are specifying latency separately from bandwidth.
In this case, lets say that m1 (the latency determining, temporary
bandwidth) is 200 kbps for a period of 1s and m2 (the guaranteed,
sustained bandwidth) is still 100 kbps and we have no additional
bandwidth from link sharing.  Let's say the first backlogged period
lasts two seconds, then there are two seconds of idle time followed by
one second of backlog.  HFSC will compare these two curves:

Notice the change in rate at 1s.  Once again, the black line is the
first service curve - the solid part being the actual transmission and
the dotted portion being the extrapolation as if it was continually
backlogged.  The blue line is the second service curve.  Notice that it
starts at the faster m1 rate.  Since the total work done, i.e., bits
dequeued is less when using the second curve, that is the one HFSC uses
to dequeue.  The effect is that the new packets are sent at the
accelerated rate and receive the full benefit of HFSC's ability to
separately guarantee latency and bandwidth.
Now, let's change the scenario.  Let's say the idle time between
backlogs is only 0.5s instead of 2s.  The curve comparison looks like
this:

Notice how the two service curves cross.  For the first half a second,
the number of bits which would be dequeued using the fully reset service
curve would be less than if the previous service curve had been
continually backlogged but, for the next half a second, the number of
bits which would be dequeued using the previous service curve is less.
In this case, HFSC will dequeue bits at the faster m1 rate for the first
half a second and then slow down to the m2 rate of the previous service
curve for the next half a second.  The service curve is "partially
reset" and the packets receive a partial "acceleration."
Let's consider one last scenario.  It is the same as the previous
scenario except that link sharing has added 50 kbps to the first two
seconds of dequeuing.  Because more work has been done, i.e., more bits
have been dequeued, the second curve will start its trajectory higher in
the graph because it always starts with how much work has already been
done, i.e., how many bits have already been dequeued.  Thus, the graph
looks like this:

Now note that, for the entire second period of backlog, the
extrapolation of the previous service curve would produce less work,
fewer bits, than starting a fresh curve.  In this case, the service
curve is not "reset" at all, the m2 rate of the previous service curve
is used for the entire dequeuing process and the packets receive no
acceleration however they will all be delivered on time because our m2
rate is guaranteed.
Piecing it all together and bringing the theory back to practical
application, we see that the total number of bits dequeued can never be
more than if the first service curve had remained permanently
backlogged.  This is how we can be sure we will never overrun the
circuit bandwidth assuming we have done our job of ensuring the sum of
the bandwidth guarantees do not exceed the circuit capacity.
However, in practicality, we can cheat a little bit.  In most cases, we
can simply be sure that the sum of the rt m2 service curves do not
exceed the circuit bandwidth.  If we need to set higher m1 curves to
guarantee latency, the sum of the rt m1 service curves could exceed
circuit capacity.  However, any idle time would quickly remedy the
situation (unless our m1 rates are excessively over capacity).
The only situations in which we could not practically cheat are the
extreme scenarios when, under no circumstances whatsoever can we
possibly not meet our guarantees (perhaps life critical systems) or
where the circuits are incredibly saturated and all queues are
constantly backlogged (in which case we probably have a bigger, non-HFSC
problem!).
Summary guidelines
Recall that HFSC classes call for defining any of ul, ls, sc, or rt
service curves.  We can use the following guidelines for the values of
these curves.  Remember these are guidelines.  Your needs may dictate a
different configuration.
ul
Set the ul service curve to just under the circuit capacity in a
dedicated circuit (to avoid tripping the carrier's traffic shaping) or
equal to the circuit capacity in a shared circuit (like DSL or Cable
where other users outside our control are adding traffic to ours so we
cannot avoid the carrier's traffic shaping).
Use a monolinear curve, i.e., only specify rate and not umax and dmax.
Set it at the highest level class and nowhere else (since it, in effect,
flows down through the hierarchy) unless you need to specifically limit
link sharing at a lower level in the hierarchy. Recall that ul does not
limit bandwidth guaranteed by rt.  Thus, one way of limiting bandwidth
at a leaf node is to simply specify the rt curve at the maximum amount
and do not specify an ls curve; this means it will nor borrow additional
bandwidth.  One would only need to specify ul in this case if one wanted
the leaf to be able to borrow above the rt guarantees but only up to a
set amount.  Finally, one might use a lower level ul if one wanted to
limit the bandwidth allocated to a non-leaf node (a branch).  Remember,
branches do not have rt curves and so one cannot limit bandwidth that
way. Thus, the only way to hard limit a branch is to set ul.  To
reiterate, ul is usually set only at the top level class.
When specifying a ul service curve, one must also specify an ls service
curve.  One cannot specify a ul curve  without an ls curve.
ls
The ls service curve is used ONLY to calculate link sharing, i.e., how
to allocate extra available bandwidth.  It does not specify directly how
much bandwidth a queue receives.
If a class does specify an ls service curve either directly or
indirectly (by specifying an sc service curve), it will not receive any
extra bandwidth over its rt service curve.
Only the ratios of ls service curves are important, not the values.
Nonetheless, for sanity's sake, it makes sense to use ls service curve
values which have some relevance to the circuit size.
Use monolinear ls service curves.
ls service curves and ul service curves are the only types of service
curves which can be applied to branches. This is how traffic is divided
between the branches of a hierarchy.  Remember that extra bandwidth is
only divided between peers at the same level in the hierarchy.
Use ls service curves on leaf nodes if you want the leaf node to use
extra bandwidth if it is available.
If the ratio in which extra bandwidth should be allocated is the same
ratio in which it is guaranteed, i.e., the ls service curve is the same
as the rt service curve, both can be specified in a single definition
using the sc service curve, i.e., no need for separate ls and rt
entries.  Use separate ls and rt definitions in a leaf node if the ratio
at which extra bandwidth is allocated is different than the ratio in
which it is guaranteed.  For example, we may have a small amount of
guaranteed bandwidth for our web server and a larger amount of
guaranteed traffic for all the rest of our bulk traffic but, if the web
site needs more bandwidth and there is contention for extra bandwidth
between web and bulk traffic, we want the web server to have top
priority.  Thus, the ratio of the web to bulk rt curves might be 1:5 but
the ratio of the ls curves 5:1.  This is one of the big advantages of
HFSC.
sc
Use sc service curves on leaf nodes when the rt service curve and the ls
service curves are identical.
Use monolinear sc service curves.  By implication, do not use sc service
curves if you want a dilinear rt curve, i.e., to guarantee latency
separately from bandwidth.
rt
The rt service curves are used for guaranteeing bandwidth and have
nothing to do with allocating extra available bandwidth.
If the minimum required latency is greater than the latency provided by
the guaranteed bandwidth, use a monolinear rt service curve.  For
example, let's say we have allocated 2 Mbps to VoIP traffic with a
maximum packet size of 222 bytes and we need latency of no more than 10
ms.  (222 * 8)/2,000,000(b/s) = 0.9ms per packet.  The latency provided
by the guaranteed bandwidth (the m2 curve) is already less than the
minimum latency we need so we do not need to specify a separate m1
curve.
If the minimum required latency is less than the latency provided by the
guaranteed bandwidth, use a dilinear rt service curve.  For example,
let's say we have allocated 2 Mbps to video with a frame size of 8KB and
the minimum latency for those frames should be 10ms.  (8000 *
8)bits/0.010s = 6.4 Mbps.  To meet our minimum latency, we need more
bandwidth than 2 Mbps so we need to specify an m1 curve which is steeper
(more bandwidth) than the m2 curve so rt umax 64kbit dmax 10ms rate
2000kbit.
The rt service curves are NOT limited by the ul service curves.
Ensure that the sum of all the m2 rt curves, i.e., the sum of all the
guaranteed bandwidths, are less than or equal to the top level ul which
should be less than or equal to the circuit capacity.
Unless carried to excess, specify m1 rt curves where needed according to
the queue latency requirements even if the sum of the m1 curves, i.e.,
the sum of all the temporary bandwidths necessary to meet the latency
guarantees, is greater than the top level ul.  Strictly speaking, this
violates the theory that HFSC should be able to meet all bandwidth
guarantees but, practically speaking, one can do this with no
deleterious effects except in the most extreme situations where all
queues are continually backlogged or there can be absolutely no
violation of guarantee whatsoever under any circumstances (perhaps life
critical systems).

^ permalink raw reply

* [PATCH 04/11] SUNRPC: per-net sysctl's set introduced
From: Stanislav Kinsbursky @ 2011-12-14 11:45 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111214103602.3991.20990.stgit@localhost6.localdomain6>

This patch introduces per-net sysctl set and it's initialization routines. Also
it modifies sysctl's registering helpers to make them use these sets.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 include/linux/sunrpc/debug.h    |    7 ++++++-
 net/sunrpc/netns.h              |    3 +++
 net/sunrpc/sunrpc_syms.c        |   13 ++++++++++++-
 net/sunrpc/sysctl.c             |   38 +++++++++++++++++++++++++++++++++-----
 net/sunrpc/xprtrdma/transport.c |    2 +-
 net/sunrpc/xprtsock.c           |    2 +-
 6 files changed, 56 insertions(+), 9 deletions(-)

diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index b5e0c46..f2d825c 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -67,7 +67,12 @@ extern unsigned int		nlm_debug;
 void		rpc_register_sysctl(void);
 void		rpc_unregister_sysctl(void);
 
-struct ctl_table_header *register_sunrpc_sysctl(struct ctl_table *);
+struct net;
+struct ctl_table;
+int debug_sysctl_init(struct net *);
+void debug_sysctl_exit(struct net *);
+struct ctl_table_header *register_sunrpc_sysctl(struct net *,
+						struct ctl_table *);
 
 #endif
 
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index 6010c46..a949ddb 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -12,6 +12,9 @@ struct sunrpc_net {
 
 	struct list_head all_clients;
 	spinlock_t rpc_client_lock;
+#ifdef RPC_DEBUG
+	struct ctl_table_set sysctls;
+#endif
 };
 
 extern int sunrpc_net_id;
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index e57aa10..44759e9 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -38,11 +38,19 @@ static __net_init int sunrpc_init_net(struct net *net)
 	err = ip_map_cache_create(net);
 	if (err)
 		goto err_ipmap;
-
+#ifdef RPC_DEBUG
+	err = debug_sysctl_init(net);
+	if (err)
+		goto err_sysctl;
+#endif
 	INIT_LIST_HEAD(&sn->all_clients);
 	spin_lock_init(&sn->rpc_client_lock);
 	return 0;
 
+#ifdef RPC_DEBUG
+err_sysctl:
+	ip_map_cache_destroy(net);
+#endif
 err_ipmap:
 	rpc_proc_exit(net);
 err_proc:
@@ -51,6 +59,9 @@ err_proc:
 
 static __net_exit void sunrpc_exit_net(struct net *net)
 {
+#ifdef RPC_DEBUG
+	debug_sysctl_exit(net);
+#endif
 	ip_map_cache_destroy(net);
 	rpc_proc_exit(net);
 }
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index f6e7da2..adebf0a 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -40,7 +40,7 @@ EXPORT_SYMBOL_GPL(nlm_debug);
 #ifdef RPC_DEBUG
 
 #include <linux/nsproxy.h>
-#include <net/net_namespace.h>
+#include "netns.h"
 
 static struct ctl_table_header *sunrpc_table_header;
 static ctl_table		debug_table[];
@@ -50,23 +50,51 @@ struct ctl_path sunrpc_path[] = {
 	{ },
 };
 
+static struct ctl_table_set *
+sunrpc_debug_lookup(struct ctl_table_root *root, struct nsproxy *namespaces)
+{
+	struct sunrpc_net *sn = net_generic(namespaces->net_ns, sunrpc_net_id);
+
+	return &sn->sysctls;
+}
+
 static struct ctl_table_root sunrpc_debug_root = {
+	.lookup	= sunrpc_debug_lookup,
 };
 
-struct ctl_table_header *register_sunrpc_sysctl(struct ctl_table *table)
+struct ctl_table_header *register_sunrpc_sysctl(struct net *net,
+						struct ctl_table *table)
 {
-	return __register_sysctl_paths(&sunrpc_debug_root, current->nsproxy,
+	struct nsproxy namespaces;
+
+	namespaces = *current->nsproxy;
+	namespaces.net_ns = net;
+	return __register_sysctl_paths(&sunrpc_debug_root, &namespaces,
 				       sunrpc_path, table);
 }
 EXPORT_SYMBOL_GPL(register_sunrpc_sysctl);
 
+int debug_sysctl_init(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	setup_sysctl_set(&sn->sysctls, NULL, NULL);
+	return 0;
+}
+
+void debug_sysctl_exit(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	WARN_ON(!list_empty(&sn->sysctls.list));
+}
+
 void
 rpc_register_sysctl(void)
 {
 	if (!sunrpc_table_header) {
-		setup_sysctl_set(&sunrpc_debug_root.default_set, NULL, NULL);
 		register_sysctl_root(&sunrpc_debug_root);
-		sunrpc_table_header = register_sunrpc_sysctl(debug_table);
+		sunrpc_table_header = register_sunrpc_sysctl(&init_net, debug_table);
 	}
 }
 
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 53a8622..4a63b35 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -762,7 +762,7 @@ static int __init xprt_rdma_init(void)
 
 #ifdef RPC_DEBUG
 	if (!sunrpc_table_header)
-		sunrpc_table_header = register_sunrpc_sysctl(xr_tunables_table);
+		sunrpc_table_header = register_sunrpc_sysctl(&init_net, xr_tunables_table);
 #endif
 	return 0;
 }
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 6f1be96..1acc9a7 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2878,7 +2878,7 @@ int init_socket_xprt(void)
 {
 #ifdef RPC_DEBUG
 	if (!sunrpc_table_header)
-		sunrpc_table_header = register_sunrpc_sysctl(xs_tunables_table);
+		sunrpc_table_header = register_sunrpc_sysctl(&init_net, xs_tunables_table);
 #endif
 
 	xprt_register_transport(&xs_local_transport);

^ permalink raw reply related

* [PATCH 07/11] SUNRPC: xs tunables per network namespace introduced
From: Stanislav Kinsbursky @ 2011-12-14 11:45 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111214103602.3991.20990.stgit@localhost6.localdomain6>

This patch introduces independent sets of xs tunables for every network
namespace context. Their value is accessible via per-net sysctls.
Static tunables left as a storage for module params and now used for
initialization of new network namespace tunables set.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 net/sunrpc/netns.h    |    6 ++++++
 net/sunrpc/xprtsock.c |   47 ++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index da825e5..23d110d 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -17,6 +17,12 @@ struct sunrpc_net {
 	struct ctl_table_header *debug_ctl_header;
 	struct ctl_table_header *xs_tunables_header;
 #endif
+	unsigned int xprt_udp_slot_table_entries;
+	unsigned int xprt_tcp_slot_table_entries;
+	unsigned int xprt_max_tcp_slot_table_entries;
+	unsigned int xprt_min_resvport;
+	unsigned int xprt_max_resvport;
+	unsigned int xs_tcp_fin_timeout;
 };
 
 extern int sunrpc_net_id;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 9e42db6..fe4b04b 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -89,7 +89,6 @@ static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT;
 static ctl_table xs_tunables_table[] = {
 	{
 		.procname	= "udp_slot_table_entries",
-		.data		= &xprt_udp_slot_table_entries,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
@@ -98,7 +97,6 @@ static ctl_table xs_tunables_table[] = {
 	},
 	{
 		.procname	= "tcp_slot_table_entries",
-		.data		= &xprt_tcp_slot_table_entries,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
@@ -107,7 +105,6 @@ static ctl_table xs_tunables_table[] = {
 	},
 	{
 		.procname	= "tcp_max_slot_table_entries",
-		.data		= &xprt_max_tcp_slot_table_entries,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
@@ -116,7 +113,6 @@ static ctl_table xs_tunables_table[] = {
 	},
 	{
 		.procname	= "min_resvport",
-		.data		= &xprt_min_resvport,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
@@ -125,7 +121,6 @@ static ctl_table xs_tunables_table[] = {
 	},
 	{
 		.procname	= "max_resvport",
-		.data		= &xprt_max_resvport,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
@@ -134,7 +129,6 @@ static ctl_table xs_tunables_table[] = {
 	},
 	{
 		.procname	= "tcp_fin_timeout",
-		.data		= &xs_tcp_fin_timeout,
 		.maxlen		= sizeof(xs_tcp_fin_timeout),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -2874,24 +2868,59 @@ static struct xprt_class	xs_bc_tcp_transport = {
 int create_xs_tunables_table(struct net *net)
 {
 	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	struct ctl_table *table;
+
+	table = xs_tunables_table;
+	if (!net_eq(net, &init_net)) {
+		table = kmemdup(xs_tunables_table, sizeof(xs_tunables_table),
+				GFP_KERNEL);
+		if (table == NULL)
+			goto err_alloc;
+	}
+
+	table[0].data = &sn->xprt_udp_slot_table_entries;
+	table[1].data = &sn->xprt_tcp_slot_table_entries;
+	table[2].data = &sn->xprt_max_tcp_slot_table_entries;
+	table[3].data = &sn->xprt_min_resvport;
+	table[4].data = &sn->xprt_max_resvport;
+	table[5].data = &sn->xs_tcp_fin_timeout;
 
-	sn->xs_tunables_header = register_sunrpc_sysctl(net, xs_tunables_table);
+	sn->xs_tunables_header = register_sunrpc_sysctl(net, table);
 	if (sn->xs_tunables_header == NULL)
-		return -ENOMEM;
+		goto err_reg;
+
 	return 0;
 
+err_reg:
+	if (!net_eq(net, &init_net))
+		kfree(table);
+err_alloc:
+	return -ENOMEM;
 }
+
 void destroy_xs_tunables_table(struct net *net)
 {
 	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	struct ctl_table *table;
+
+	table = sn->xs_tunables_header->ctl_table_arg;
 	unregister_sysctl_table(sn->xs_tunables_header);
 	sn->xs_tunables_header = NULL;
+	if (!net_eq(net, &init_net))
+		kfree(table);
 }
 #endif
 
-
 int socket_sysctl_init(struct net *net)
 {
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	sn->xprt_udp_slot_table_entries = xprt_udp_slot_table_entries;
+	sn->xprt_tcp_slot_table_entries = xprt_tcp_slot_table_entries;
+	sn->xprt_max_tcp_slot_table_entries = xprt_max_tcp_slot_table_entries;
+	sn->xprt_min_resvport = xprt_min_resvport;
+	sn->xprt_max_resvport = xprt_max_resvport;
+	sn->xs_tcp_fin_timeout = xs_tcp_fin_timeout;
 #ifdef RPC_DEBUG
 	return create_xs_tunables_table(net);
 #else

^ permalink raw reply related

* Re: kenel level packet capturing
From: raviraj joshi @ 2011-12-14 10:46 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, netfilter-devel, netfilter
In-Reply-To: <20111213.133629.1213042365300662857.davem@davemloft.net>

On Wed, Dec 14, 2011 at 12:06 AM, David Miller <davem@davemloft.net> wrote:
> From: raviraj joshi <raviraj.j1991@gmail.com>
> Date: Tue, 13 Dec 2011 17:34:22 +0530
>
>> We have decided to use PF_RING(a kernel module to capture packets) for
>> the same due to the number of advantages.
>
> What "advantages"?  The AF_PACKET socket layer already upstream in the
> kernel supports every relevant performance feature PF_RING does, and
> then some.
I refered to the document on "A Measurement Study of Packet Reception
using Linux"[1]  which said pf_ring maintains
a ring buffer, so we dont have to issue a receive system call for each
packet in contrast to AF_PACKET which issues a system call for each
packet(pls correct me if i am wrong).

I would like to know can we use AF_PACKET services from a kernel
module as we are not bound to pf_ring and can use
AF_PACKET if its efficient and easy to use?


thanking,

Raviraj Joshi


[1]
http://www.cs.wustl.edu/~jain/cse567-11/ftp/pkt_recp/index.html

^ permalink raw reply

* Re: BCM43224 hanging [3.2.0-rc5] (was: [3.2.0-rc4-00248-gb835c0f] ...)
From: Nico Schottelius @ 2011-12-14 11:21 UTC (permalink / raw)
  To: Nico Schottelius, Arend van Spriel, LKML, netdev, b43-dev,
	Greg KH
In-Reply-To: <20111212181619.GD1975@schottelius.org>

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

Update:

After several more suspend & resume cycles I managed to get back
into the non-working state where every network call hangs.

I've upgraded to 3.2.0-rc5, which results in same behaviour.

Attached are latest dmesg outputs, with changing behaviour
(3.2.0-rc4-00255-g77a7300.dmesg.xz) and the usual does not
work on bootup status (3.2.0-rc5.dmesg.xz).

Cheers,

Nico

-- 
PGP key: 7ED9 F7D3 6B10 81D7 0EC5  5C09 D7DC C8E4 3187 7DF0

[-- Attachment #2: 3.2.0-rc4-00255-g77a7300.dmesg.xz --]
[-- Type: application/octet-stream, Size: 29892 bytes --]

[-- Attachment #3: 3.2.0-rc5.dmesg.xz --]
[-- Type: application/octet-stream, Size: 11548 bytes --]

^ permalink raw reply

* [PATCH 00/11] SUNRPC: make sysctl per network namespcase context
From: Stanislav Kinsbursky @ 2011-12-14 11:44 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel

This patch set make SUNRPC sysctl created per network namspace context.
It provides the following functionality:
1) Debug sysctl's ( {rpc,nfs,nlm,nfsd}_debug ) content is modifyable only from
init_net network context.
2) Write to rpc_debug prints active RPC tasks in sysctl's creator networks
context.
3) xs tunables are per-net now and modified through per-net sysctl's. IOW,
sysctl creator context is used to get tunable during sysctl read/write access
(not current tone).

The following series consists of:

---

Stanislav Kinsbursky (11):
      SYSCTL: export root ans set handling routines
      SUNRPC: use syctl path instead of dummy parent table
      SUNRPC: sysctl root for debug table introduced
      SUNRPC: per-net sysctl's set introduced
      SUNRPC: register debug sysctl table per network namespace
      SUNRPC: register xs_tunables sysctl table per network namespace
      SUNRPC: xs tunables per network namespace introduced
      SUNRPC: use per-net xs tunables instead of static ones
      SUNRPC: remove xs_tcp_fin_timeout variable
      SUNRPC: allow debug flags modifications only from init_net
      SUNRPC: sysctl table for rpc_debug introduced


 include/linux/sunrpc/debug.h    |    9 ++
 include/linux/sunrpc/sched.h    |    1 
 include/linux/sunrpc/xprtsock.h |    3 +
 include/linux/sysctl.h          |    1 
 kernel/sysctl.c                 |   11 +++
 net/sunrpc/netns.h              |   12 +++
 net/sunrpc/sunrpc_syms.c        |   27 ++++++-
 net/sunrpc/sysctl.c             |  160 ++++++++++++++++++++++++++++++++-------
 net/sunrpc/xprtrdma/transport.c |   11 ---
 net/sunrpc/xprtsock.c           |  147 ++++++++++++++++++++++++------------
 10 files changed, 293 insertions(+), 89 deletions(-)

^ permalink raw reply

* [PATCH 01/11] SYSCTL: export root and set handling routines
From: Stanislav Kinsbursky @ 2011-12-14 11:44 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111214103602.3991.20990.stgit@localhost6.localdomain6>

These routines are required for making SUNRPC sysctl's per network namespace
context.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 include/linux/sysctl.h |    1 +
 kernel/sysctl.c        |   11 +++++++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 703cfa3..be586a9 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -1084,6 +1084,7 @@ struct ctl_path {
 };
 
 void register_sysctl_root(struct ctl_table_root *root);
+void unregister_sysctl_root(struct ctl_table_root *root);
 struct ctl_table_header *__register_sysctl_paths(
 	struct ctl_table_root *root, struct nsproxy *namespaces,
 	const struct ctl_path *path, struct ctl_table *table);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index ae27196..fb016a9 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1700,6 +1700,15 @@ void register_sysctl_root(struct ctl_table_root *root)
 	list_add_tail(&root->root_list, &sysctl_table_root.root_list);
 	spin_unlock(&sysctl_lock);
 }
+EXPORT_SYMBOL_GPL(register_sysctl_root);
+
+void unregister_sysctl_root(struct ctl_table_root *root)
+{
+	spin_lock(&sysctl_lock);
+	list_del(&root->root_list);
+	spin_unlock(&sysctl_lock);
+}
+EXPORT_SYMBOL_GPL(unregister_sysctl_root);
 
 /*
  * sysctl_perm does NOT grant the superuser all rights automatically, because
@@ -1925,6 +1934,7 @@ struct ctl_table_header *__register_sysctl_paths(
 
 	return header;
 }
+EXPORT_SYMBOL_GPL(__register_sysctl_paths);
 
 /**
  * register_sysctl_table_path - register a sysctl table hierarchy
@@ -2007,6 +2017,7 @@ void setup_sysctl_set(struct ctl_table_set *p,
 	p->parent = parent ? parent : &sysctl_table_root.default_set;
 	p->is_seen = is_seen;
 }
+EXPORT_SYMBOL_GPL(setup_sysctl_set);
 
 #else /* !CONFIG_SYSCTL */
 struct ctl_table_header *register_sysctl_table(struct ctl_table * table)

^ permalink raw reply related

* [PATCH 02/11] SUNRPC: use syctl path instead of dummy parent table
From: Stanislav Kinsbursky @ 2011-12-14 11:44 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111214103602.3991.20990.stgit@localhost6.localdomain6>

This is a cleanup patch. Parent sunrpc table is redundant. Syctl path can be
used instead.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 include/linux/sunrpc/debug.h    |    4 ++++
 net/sunrpc/sysctl.c             |   25 ++++++++++++++-----------
 net/sunrpc/xprtrdma/transport.c |   11 +----------
 net/sunrpc/xprtsock.c           |   11 +----------
 4 files changed, 20 insertions(+), 31 deletions(-)

diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index c2786f2..b5e0c46 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -63,8 +63,12 @@ extern unsigned int		nlm_debug;
  * Sysctl interface for RPC debugging
  */
 #ifdef RPC_DEBUG
+
 void		rpc_register_sysctl(void);
 void		rpc_unregister_sysctl(void);
+
+struct ctl_table_header *register_sunrpc_sysctl(struct ctl_table *);
+
 #endif
 
 #endif /* __KERNEL__ */
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index af7d339..64c0034 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -40,13 +40,25 @@ EXPORT_SYMBOL_GPL(nlm_debug);
 #ifdef RPC_DEBUG
 
 static struct ctl_table_header *sunrpc_table_header;
-static ctl_table		sunrpc_table[];
+static ctl_table		debug_table[];
+
+struct ctl_path sunrpc_path[] = {
+	{ .procname = "sunrpc", },
+	{ },
+};
+
+struct ctl_table_header *register_sunrpc_sysctl(struct ctl_table *table)
+{
+	return register_sysctl_paths(sunrpc_path, table);
+
+}
+EXPORT_SYMBOL_GPL(register_sunrpc_sysctl);
 
 void
 rpc_register_sysctl(void)
 {
 	if (!sunrpc_table_header)
-		sunrpc_table_header = register_sysctl_table(sunrpc_table);
+		sunrpc_table_header = register_sunrpc_sysctl(debug_table);
 }
 
 void
@@ -173,13 +185,4 @@ static ctl_table debug_table[] = {
 	{ }
 };
 
-static ctl_table sunrpc_table[] = {
-	{
-		.procname	= "sunrpc",
-		.mode		= 0555,
-		.child		= debug_table
-	},
-	{ }
-};
-
 #endif
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index b446e10..53a8622 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -137,15 +137,6 @@ static ctl_table xr_tunables_table[] = {
 	{ },
 };
 
-static ctl_table sunrpc_table[] = {
-	{
-		.procname	= "sunrpc",
-		.mode		= 0555,
-		.child		= xr_tunables_table
-	},
-	{ },
-};
-
 #endif
 
 static struct rpc_xprt_ops xprt_rdma_procs;	/* forward reference */
@@ -771,7 +762,7 @@ static int __init xprt_rdma_init(void)
 
 #ifdef RPC_DEBUG
 	if (!sunrpc_table_header)
-		sunrpc_table_header = register_sysctl_table(sunrpc_table);
+		sunrpc_table_header = register_sunrpc_sysctl(xr_tunables_table);
 #endif
 	return 0;
 }
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 55472c4..6f1be96 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -142,15 +142,6 @@ static ctl_table xs_tunables_table[] = {
 	{ },
 };
 
-static ctl_table sunrpc_table[] = {
-	{
-		.procname	= "sunrpc",
-		.mode		= 0555,
-		.child		= xs_tunables_table
-	},
-	{ },
-};
-
 #endif
 
 /*
@@ -2887,7 +2878,7 @@ int init_socket_xprt(void)
 {
 #ifdef RPC_DEBUG
 	if (!sunrpc_table_header)
-		sunrpc_table_header = register_sysctl_table(sunrpc_table);
+		sunrpc_table_header = register_sunrpc_sysctl(xs_tunables_table);
 #endif
 
 	xprt_register_transport(&xs_local_transport);

^ permalink raw reply related

* [PATCH 03/11] SUNRPC: sysctl root for debug table introduced
From: Stanislav Kinsbursky @ 2011-12-14 11:45 UTC (permalink / raw)
  To: Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA
  Cc: linux-nfs-u79uwXL29TY76Z2rM5mHXA, xemul-bzQdu9zFT3WakBO8gow8eQ,
	neilb-l3A5Bk7waGM, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	jbottomley-bzQdu9zFT3WakBO8gow8eQ, bfields-uC3wQj2KruNg9hUCZPvPmw,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, devel-GEFAQzZX7r8dnm+yROfE0A
In-Reply-To: <20111214103602.3991.20990.stgit-bi+AKbBUZKagILUCTcTcHdKyNwTtLsGr@public.gmane.org>

Sysctl root is required for handliong sysctl dentries per network namespace
context. IOW, it's "lookup" method will be used to find per-net sysctl's set in
further patches.
Also this patch modifies sysctl registering helpers to make them use new sysctl
root.

Signed-off-by: Stanislav Kinsbursky <skinsbursky-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>

---
 net/sunrpc/sysctl.c |   16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index 64c0034..f6e7da2 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -39,6 +39,9 @@ EXPORT_SYMBOL_GPL(nlm_debug);
 
 #ifdef RPC_DEBUG
 
+#include <linux/nsproxy.h>
+#include <net/net_namespace.h>
+
 static struct ctl_table_header *sunrpc_table_header;
 static ctl_table		debug_table[];
 
@@ -47,18 +50,24 @@ struct ctl_path sunrpc_path[] = {
 	{ },
 };
 
+static struct ctl_table_root sunrpc_debug_root = {
+};
+
 struct ctl_table_header *register_sunrpc_sysctl(struct ctl_table *table)
 {
-	return register_sysctl_paths(sunrpc_path, table);
-
+	return __register_sysctl_paths(&sunrpc_debug_root, current->nsproxy,
+				       sunrpc_path, table);
 }
 EXPORT_SYMBOL_GPL(register_sunrpc_sysctl);
 
 void
 rpc_register_sysctl(void)
 {
-	if (!sunrpc_table_header)
+	if (!sunrpc_table_header) {
+		setup_sysctl_set(&sunrpc_debug_root.default_set, NULL, NULL);
+		register_sysctl_root(&sunrpc_debug_root);
 		sunrpc_table_header = register_sunrpc_sysctl(debug_table);
+	}
 }
 
 void
@@ -66,6 +75,7 @@ rpc_unregister_sysctl(void)
 {
 	if (sunrpc_table_header) {
 		unregister_sysctl_table(sunrpc_table_header);
+		unregister_sysctl_root(&sunrpc_debug_root);
 		sunrpc_table_header = NULL;
 	}
 }

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" 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 related

* [PATCH 05/11] SUNRPC: register debug sysctl table per network namespace
From: Stanislav Kinsbursky @ 2011-12-14 11:45 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111214103602.3991.20990.stgit@localhost6.localdomain6>

This patch introduces per-net sysctl header for debug table and moves debug
table registration to per-net opreations.
Also, this patch moves SUNRPC sysctl root registration prior to per-net
operations, since now they depends on it.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 net/sunrpc/netns.h       |    1 +
 net/sunrpc/sunrpc_syms.c |    9 ++++++---
 net/sunrpc/sysctl.c      |   17 +++++++----------
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index a949ddb..05ce3b8 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -14,6 +14,7 @@ struct sunrpc_net {
 	spinlock_t rpc_client_lock;
 #ifdef RPC_DEBUG
 	struct ctl_table_set sysctls;
+	struct ctl_table_header *debug_ctl_header;
 #endif
 };
 
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 44759e9..0fd156a 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -90,18 +90,21 @@ init_sunrpc(void)
 
 	cache_initialize();
 
-	err = register_pernet_subsys(&sunrpc_net_ops);
-	if (err)
-		goto out4;
 #ifdef RPC_DEBUG
 	rpc_register_sysctl();
 #endif
+	err = register_pernet_subsys(&sunrpc_net_ops);
+	if (err)
+		goto out4;
 	cache_register(&unix_gid_cache);
 	svc_init_xprt_sock();	/* svc sock transport */
 	init_socket_xprt();	/* clnt sock transport */
 	return 0;
 
 out4:
+#ifdef RPC_DEBUG
+	rpc_unregister_sysctl();
+#endif
 	rpcauth_remove_module();
 out3:
 	rpc_destroy_mempool();
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index adebf0a..eda80cf 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -42,7 +42,6 @@ EXPORT_SYMBOL_GPL(nlm_debug);
 #include <linux/nsproxy.h>
 #include "netns.h"
 
-static struct ctl_table_header *sunrpc_table_header;
 static ctl_table		debug_table[];
 
 struct ctl_path sunrpc_path[] = {
@@ -79,6 +78,9 @@ int debug_sysctl_init(struct net *net)
 	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
 	setup_sysctl_set(&sn->sysctls, NULL, NULL);
+	sn->debug_ctl_header = register_sunrpc_sysctl(net, debug_table);
+	if (sn->debug_ctl_header == NULL)
+		return -ENOMEM;
 	return 0;
 }
 
@@ -86,26 +88,21 @@ void debug_sysctl_exit(struct net *net)
 {
 	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
+	unregister_sysctl_table(sn->debug_ctl_header);
+	sn->debug_ctl_header = NULL;
 	WARN_ON(!list_empty(&sn->sysctls.list));
 }
 
 void
 rpc_register_sysctl(void)
 {
-	if (!sunrpc_table_header) {
-		register_sysctl_root(&sunrpc_debug_root);
-		sunrpc_table_header = register_sunrpc_sysctl(&init_net, debug_table);
-	}
+	register_sysctl_root(&sunrpc_debug_root);
 }
 
 void
 rpc_unregister_sysctl(void)
 {
-	if (sunrpc_table_header) {
-		unregister_sysctl_table(sunrpc_table_header);
-		unregister_sysctl_root(&sunrpc_debug_root);
-		sunrpc_table_header = NULL;
-	}
+	unregister_sysctl_root(&sunrpc_debug_root);
 }
 
 static int proc_do_xprt(ctl_table *table, int write,

^ permalink raw reply related

* [PATCH 06/11] SUNRPC: register xs_tunables sysctl table per network namespace
From: Stanislav Kinsbursky @ 2011-12-14 11:45 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111214103602.3991.20990.stgit@localhost6.localdomain6>

This patch introduces per-net sysctl header for xs_tunables table and moves
xs_tunables table registration to per-net opreations.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 include/linux/sunrpc/xprtsock.h |    3 ++
 net/sunrpc/netns.h              |    1 +
 net/sunrpc/sunrpc_syms.c        |    7 +++++
 net/sunrpc/xprtsock.c           |   52 +++++++++++++++++++++++++++++----------
 4 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/include/linux/sunrpc/xprtsock.h b/include/linux/sunrpc/xprtsock.h
index 3f14a02..3ba4920 100644
--- a/include/linux/sunrpc/xprtsock.h
+++ b/include/linux/sunrpc/xprtsock.h
@@ -9,6 +9,9 @@
 
 #ifdef __KERNEL__
 
+int socket_sysctl_init(struct net *);
+void socket_sysctl_exit(struct net *);
+
 int		init_socket_xprt(void);
 void		cleanup_socket_xprt(void);
 
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index 05ce3b8..da825e5 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -15,6 +15,7 @@ struct sunrpc_net {
 #ifdef RPC_DEBUG
 	struct ctl_table_set sysctls;
 	struct ctl_table_header *debug_ctl_header;
+	struct ctl_table_header *xs_tunables_header;
 #endif
 };
 
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 0fd156a..2b76e18 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -42,12 +42,18 @@ static __net_init int sunrpc_init_net(struct net *net)
 	err = debug_sysctl_init(net);
 	if (err)
 		goto err_sysctl;
+
+	err = socket_sysctl_init(net);
+	if (err)
+		goto err_sock_ctl;
 #endif
 	INIT_LIST_HEAD(&sn->all_clients);
 	spin_lock_init(&sn->rpc_client_lock);
 	return 0;
 
 #ifdef RPC_DEBUG
+err_sock_ctl:
+	debug_sysctl_exit(net);
 err_sysctl:
 	ip_map_cache_destroy(net);
 #endif
@@ -60,6 +66,7 @@ err_proc:
 static __net_exit void sunrpc_exit_net(struct net *net)
 {
 #ifdef RPC_DEBUG
+	socket_sysctl_exit(net);
 	debug_sysctl_exit(net);
 #endif
 	ip_map_cache_destroy(net);
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 1acc9a7..9e42db6 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -74,14 +74,14 @@ static unsigned int xs_tcp_fin_timeout __read_mostly = XS_TCP_LINGER_TO;
 
 #ifdef RPC_DEBUG
 
+#include "netns.h"
+
 static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
 static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
 static unsigned int max_tcp_slot_table_limit = RPC_MAX_SLOT_TABLE_LIMIT;
 static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT;
 static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT;
 
-static struct ctl_table_header *sunrpc_table_header;
-
 /*
  * FIXME: changing the UDP slot table size should also resize the UDP
  *        socket buffers for existing UDP transports
@@ -2870,17 +2870,48 @@ static struct xprt_class	xs_bc_tcp_transport = {
 	.setup		= xs_setup_bc_tcp,
 };
 
+#ifdef RPC_DEBUG
+int create_xs_tunables_table(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	sn->xs_tunables_header = register_sunrpc_sysctl(net, xs_tunables_table);
+	if (sn->xs_tunables_header == NULL)
+		return -ENOMEM;
+	return 0;
+
+}
+void destroy_xs_tunables_table(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	unregister_sysctl_table(sn->xs_tunables_header);
+	sn->xs_tunables_header = NULL;
+}
+#endif
+
+
+int socket_sysctl_init(struct net *net)
+{
+#ifdef RPC_DEBUG
+	return create_xs_tunables_table(net);
+#else
+	return 0;
+#endif
+}
+
+void socket_sysctl_exit(struct net *net)
+{
+#ifdef RPC_DEBUG
+	destroy_xs_tunables_table(net);
+#endif
+}
+
 /**
  * init_socket_xprt - set up xprtsock's sysctls, register with RPC client
  *
  */
 int init_socket_xprt(void)
 {
-#ifdef RPC_DEBUG
-	if (!sunrpc_table_header)
-		sunrpc_table_header = register_sunrpc_sysctl(&init_net, xs_tunables_table);
-#endif
-
 	xprt_register_transport(&xs_local_transport);
 	xprt_register_transport(&xs_udp_transport);
 	xprt_register_transport(&xs_tcp_transport);
@@ -2895,13 +2926,6 @@ int init_socket_xprt(void)
  */
 void cleanup_socket_xprt(void)
 {
-#ifdef RPC_DEBUG
-	if (sunrpc_table_header) {
-		unregister_sysctl_table(sunrpc_table_header);
-		sunrpc_table_header = NULL;
-	}
-#endif
-
 	xprt_unregister_transport(&xs_local_transport);
 	xprt_unregister_transport(&xs_udp_transport);
 	xprt_unregister_transport(&xs_tcp_transport);

^ permalink raw reply related

* [PATCH 08/11] SUNRPC: use per-net xs tunables instead of static ones
From: Stanislav Kinsbursky @ 2011-12-14 11:45 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111214103602.3991.20990.stgit@localhost6.localdomain6>

This patch replaces references to static tunables with per-net ones.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 net/sunrpc/xprtsock.c |   42 ++++++++++++++++++++++++++----------------
 1 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index fe4b04b..49219d2 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1458,6 +1458,7 @@ static void xs_sock_mark_closed(struct rpc_xprt *xprt)
 static void xs_tcp_state_change(struct sock *sk)
 {
 	struct rpc_xprt *xprt;
+	struct sunrpc_net *sn = net_generic(sk->sk_net, sunrpc_net_id);
 
 	read_lock_bh(&sk->sk_callback_lock);
 	if (!(xprt = xprt_from_sock(sk)))
@@ -1496,7 +1497,7 @@ static void xs_tcp_state_change(struct sock *sk)
 		clear_bit(XPRT_CONNECTED, &xprt->state);
 		clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
 		smp_mb__after_clear_bit();
-		xs_tcp_schedule_linger_timeout(xprt, xs_tcp_fin_timeout);
+		xs_tcp_schedule_linger_timeout(xprt, sn->xs_tcp_fin_timeout);
 		break;
 	case TCP_CLOSE_WAIT:
 		/* The server initiated a shutdown of the socket */
@@ -1512,7 +1513,7 @@ static void xs_tcp_state_change(struct sock *sk)
 		break;
 	case TCP_LAST_ACK:
 		set_bit(XPRT_CLOSING, &xprt->state);
-		xs_tcp_schedule_linger_timeout(xprt, xs_tcp_fin_timeout);
+		xs_tcp_schedule_linger_timeout(xprt, sn->xs_tcp_fin_timeout);
 		smp_mb__before_clear_bit();
 		clear_bit(XPRT_CONNECTED, &xprt->state);
 		smp_mb__after_clear_bit();
@@ -1652,11 +1653,13 @@ static void xs_udp_timer(struct rpc_task *task)
 	xprt_adjust_cwnd(task, -ETIMEDOUT);
 }
 
-static unsigned short xs_get_random_port(void)
+static unsigned short xs_get_random_port(struct net *net)
 {
-	unsigned short range = xprt_max_resvport - xprt_min_resvport;
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	unsigned short range = sn->xprt_max_resvport - sn->xprt_min_resvport;
 	unsigned short rand = (unsigned short) net_random() % range;
-	return rand + xprt_min_resvport;
+	return rand + sn->xprt_min_resvport;
 }
 
 /**
@@ -1678,18 +1681,21 @@ static unsigned short xs_get_srcport(struct sock_xprt *transport)
 	unsigned short port = transport->srcport;
 
 	if (port == 0 && transport->xprt.resvport)
-		port = xs_get_random_port();
+		port = xs_get_random_port(transport->xprt.xprt_net);
 	return port;
 }
 
 static unsigned short xs_next_srcport(struct sock_xprt *transport, unsigned short port)
 {
+	struct sunrpc_net *sn = net_generic(transport->xprt.xprt_net,
+					    sunrpc_net_id);
+
 	if (transport->srcport != 0)
 		transport->srcport = 0;
 	if (!transport->xprt.resvport)
 		return 0;
-	if (port <= xprt_min_resvport || port > xprt_max_resvport)
-		return xprt_max_resvport;
+	if (port <= sn->xprt_min_resvport || port > sn->xprt_max_resvport)
+		return sn->xprt_max_resvport;
 	return --port;
 }
 static int xs_bind(struct sock_xprt *transport, struct socket *sock)
@@ -2541,9 +2547,10 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args)
 	struct sock_xprt *transport;
 	struct rpc_xprt *xprt;
 	struct rpc_xprt *ret;
+	struct sunrpc_net *sn = net_generic(args->net, sunrpc_net_id);
 
-	xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries,
-			xprt_max_tcp_slot_table_entries);
+	xprt = xs_setup_xprt(args, sn->xprt_tcp_slot_table_entries,
+			sn->xprt_max_tcp_slot_table_entries);
 	if (IS_ERR(xprt))
 		return xprt;
 	transport = container_of(xprt, struct sock_xprt, xprt);
@@ -2606,9 +2613,10 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
 	struct rpc_xprt *xprt;
 	struct sock_xprt *transport;
 	struct rpc_xprt *ret;
+	struct sunrpc_net *sn = net_generic(args->net, sunrpc_net_id);
 
-	xprt = xs_setup_xprt(args, xprt_udp_slot_table_entries,
-			xprt_udp_slot_table_entries);
+	xprt = xs_setup_xprt(args, sn->xprt_udp_slot_table_entries,
+			sn->xprt_udp_slot_table_entries);
 	if (IS_ERR(xprt))
 		return xprt;
 	transport = container_of(xprt, struct sock_xprt, xprt);
@@ -2683,9 +2691,10 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
 	struct rpc_xprt *xprt;
 	struct sock_xprt *transport;
 	struct rpc_xprt *ret;
+	struct sunrpc_net *sn = net_generic(args->net, sunrpc_net_id);
 
-	xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries,
-			xprt_max_tcp_slot_table_entries);
+	xprt = xs_setup_xprt(args, sn->xprt_tcp_slot_table_entries,
+			sn->xprt_max_tcp_slot_table_entries);
 	if (IS_ERR(xprt))
 		return xprt;
 	transport = container_of(xprt, struct sock_xprt, xprt);
@@ -2754,6 +2763,7 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
 	struct sock_xprt *transport;
 	struct svc_sock *bc_sock;
 	struct rpc_xprt *ret;
+	struct sunrpc_net *sn = net_generic(args->net, sunrpc_net_id);
 
 	if (args->bc_xprt->xpt_bc_xprt) {
 		/*
@@ -2764,8 +2774,8 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
 		 */
 		 return args->bc_xprt->xpt_bc_xprt;
 	}
-	xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries,
-			xprt_tcp_slot_table_entries);
+	xprt = xs_setup_xprt(args, sn->xprt_tcp_slot_table_entries,
+			sn->xprt_tcp_slot_table_entries);
 	if (IS_ERR(xprt))
 		return xprt;
 	transport = container_of(xprt, struct sock_xprt, xprt);

^ permalink raw reply related

* [PATCH 09/11] SUNRPC: remove xs_tcp_fin_timeout variable
From: Stanislav Kinsbursky @ 2011-12-14 11:45 UTC (permalink / raw)
  To: Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA
  Cc: linux-nfs-u79uwXL29TY76Z2rM5mHXA, xemul-bzQdu9zFT3WakBO8gow8eQ,
	neilb-l3A5Bk7waGM, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	jbottomley-bzQdu9zFT3WakBO8gow8eQ, bfields-uC3wQj2KruNg9hUCZPvPmw,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, devel-GEFAQzZX7r8dnm+yROfE0A
In-Reply-To: <20111214103602.3991.20990.stgit-bi+AKbBUZKagILUCTcTcHdKyNwTtLsGr@public.gmane.org>

This is a cleanup patch. Static xs_tcp_fin_timeout is not needed anymore.

Signed-off-by: Stanislav Kinsbursky <skinsbursky-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>

---
 net/sunrpc/xprtsock.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 49219d2..610a74a 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -61,7 +61,6 @@ unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT;
 unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT;
 
 #define XS_TCP_LINGER_TO	(15U * HZ)
-static unsigned int xs_tcp_fin_timeout __read_mostly = XS_TCP_LINGER_TO;
 
 /*
  * We can register our own files under /proc/sys/sunrpc by
@@ -129,7 +128,7 @@ static ctl_table xs_tunables_table[] = {
 	},
 	{
 		.procname	= "tcp_fin_timeout",
-		.maxlen		= sizeof(xs_tcp_fin_timeout),
+		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
@@ -2930,7 +2929,7 @@ int socket_sysctl_init(struct net *net)
 	sn->xprt_max_tcp_slot_table_entries = xprt_max_tcp_slot_table_entries;
 	sn->xprt_min_resvport = xprt_min_resvport;
 	sn->xprt_max_resvport = xprt_max_resvport;
-	sn->xs_tcp_fin_timeout = xs_tcp_fin_timeout;
+	sn->xs_tcp_fin_timeout = XS_TCP_LINGER_TO;
 #ifdef RPC_DEBUG
 	return create_xs_tunables_table(net);
 #else

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" 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 related

* [PATCH 10/11] SUNRPC: allow debug flags modifications only from init_net
From: Stanislav Kinsbursky @ 2011-12-14 11:46 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111214103602.3991.20990.stgit@localhost6.localdomain6>

Debug flags are global (i.e. fo all namespaces). So probably, it is better to
restrict write access and allow it only to processes with "init_net" network
namespace.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 net/sunrpc/sysctl.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index eda80cf..224b075 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -156,7 +156,8 @@ proc_dodebug(ctl_table *table, int write,
 			return -EINVAL;
 		while (left && isspace(*s))
 			left--, s++;
-		*(unsigned int *) table->data = value;
+		if (net_eq(current->nsproxy->net_ns, &init_net))
+			*(unsigned int *) table->data = value;
 		/* Display the RPC tasks on writing to rpc_debug */
 		if (strcmp(table->procname, "rpc_debug") == 0)
 			rpc_show_tasks(&init_net);

^ permalink raw reply related

* [PATCH 11/11] SUNRPC: sysctl table for rpc_debug introduced
From: Stanislav Kinsbursky @ 2011-12-14 11:46 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111214103602.3991.20990.stgit@localhost6.localdomain6>

This patch provides showing of pending RPC tasks for right namespace in case of
write oparation to "rpc_debug" sysctl.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 include/linux/sunrpc/sched.h |    1 
 net/sunrpc/netns.h           |    1 
 net/sunrpc/sysctl.c          |   87 +++++++++++++++++++++++++++++++++++++-----
 3 files changed, 77 insertions(+), 12 deletions(-)

diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index b16243a..02f5fce 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -244,7 +244,6 @@ int		rpciod_up(void);
 void		rpciod_down(void);
 int		__rpc_wait_for_completion_task(struct rpc_task *task, int (*)(void *));
 #ifdef RPC_DEBUG
-struct net;
 void		rpc_show_tasks(struct net *);
 #endif
 int		rpc_init_mempool(void);
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index 23d110d..0926705 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -16,6 +16,7 @@ struct sunrpc_net {
 	struct ctl_table_set sysctls;
 	struct ctl_table_header *debug_ctl_header;
 	struct ctl_table_header *xs_tunables_header;
+	struct ctl_table_header *rpc_debug_ctl_header;
 #endif
 	unsigned int xprt_udp_slot_table_entries;
 	unsigned int xprt_tcp_slot_table_entries;
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index 224b075..52f6fb5 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -44,6 +44,15 @@ EXPORT_SYMBOL_GPL(nlm_debug);
 
 static ctl_table		debug_table[];
 
+static ctl_table rpc_debug_table[] = {
+	{
+		.procname	= "rpc_debug",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+	},
+	{ }
+};
+
 struct ctl_path sunrpc_path[] = {
 	{ .procname = "sunrpc", },
 	{ },
@@ -73,6 +82,48 @@ struct ctl_table_header *register_sunrpc_sysctl(struct net *net,
 }
 EXPORT_SYMBOL_GPL(register_sunrpc_sysctl);
 
+static int proc_rpcdebug(ctl_table *table, int write,
+			 void __user *buffer, size_t *lenp, loff_t *ppos);
+
+static int register_rpc_debug_table(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	struct ctl_table *table;
+
+	table = rpc_debug_table;
+	if (!net_eq(net, &init_net)) {
+		table = kmemdup(rpc_debug_table, sizeof(rpc_debug_table),
+				GFP_KERNEL);
+		if (table == NULL)
+			goto err_alloc;
+	}
+	table[0].data = net;
+	table[0].proc_handler = proc_rpcdebug;
+
+	sn->rpc_debug_ctl_header = register_sunrpc_sysctl(net, table);
+	if (sn->rpc_debug_ctl_header == NULL)
+		goto err_reg;
+	return 0;
+
+err_reg:
+	if (!net_eq(net, &init_net))
+		kfree(table);
+err_alloc:
+	return -ENOMEM;
+}
+
+static void unregister_rpc_debug_table(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	struct ctl_table *table;
+
+	table = sn->rpc_debug_ctl_header->ctl_table_arg;
+	unregister_sysctl_table(sn->rpc_debug_ctl_header);
+	sn->rpc_debug_ctl_header = NULL;
+	if (!net_eq(net, &init_net))
+		kfree(table);
+}
+
 int debug_sysctl_init(struct net *net)
 {
 	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
@@ -80,14 +131,23 @@ int debug_sysctl_init(struct net *net)
 	setup_sysctl_set(&sn->sysctls, NULL, NULL);
 	sn->debug_ctl_header = register_sunrpc_sysctl(net, debug_table);
 	if (sn->debug_ctl_header == NULL)
-		return -ENOMEM;
+		goto err_debug;
+	if (register_rpc_debug_table(net) < 0)
+		goto err_rpc_debug;
 	return 0;
+
+err_rpc_debug:
+	unregister_sysctl_table(sn->debug_ctl_header);
+	sn->debug_ctl_header = NULL;
+err_debug:
+	return -ENOMEM;
 }
 
 void debug_sysctl_exit(struct net *net)
 {
 	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
+	unregister_rpc_debug_table(net);
 	unregister_sysctl_table(sn->debug_ctl_header);
 	sn->debug_ctl_header = NULL;
 	WARN_ON(!list_empty(&sn->sysctls.list));
@@ -158,9 +218,6 @@ proc_dodebug(ctl_table *table, int write,
 			left--, s++;
 		if (net_eq(current->nsproxy->net_ns, &init_net))
 			*(unsigned int *) table->data = value;
-		/* Display the RPC tasks on writing to rpc_debug */
-		if (strcmp(table->procname, "rpc_debug") == 0)
-			rpc_show_tasks(&init_net);
 	} else {
 		if (!access_ok(VERIFY_WRITE, buffer, left))
 			return -EFAULT;
@@ -183,15 +240,23 @@ done:
 }
 
 
+static int
+proc_rpcdebug(ctl_table *table, int write,
+				void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	int err;
+	struct ctl_table tmp = *table;
+
+	tmp.data = &rpc_debug;
+	err = proc_dodebug(&tmp, write, buffer, lenp, ppos);
+	if (!err && write)
+		/* Display the RPC tasks on writing to rpc_debug */
+		rpc_show_tasks(table->data);
+	return err;
+}
+
 static ctl_table debug_table[] = {
 	{
-		.procname	= "rpc_debug",
-		.data		= &rpc_debug,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dodebug
-	},
-	{
 		.procname	= "nfs_debug",
 		.data		= &nfs_debug,
 		.maxlen		= sizeof(int),

^ permalink raw reply related

* [PATCH net-next] cls_flow: remove one dynamic array
From: Eric Dumazet @ 2011-12-14 12:30 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Its better to use a predefined size for this small automatic variable.

Removes a sparse error as well :

net/sched/cls_flow.c:288:13: error: bad constant expression

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 net/sched/cls_flow.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 51ff194..1d8bd0d 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -285,7 +285,7 @@ static int flow_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 	int r;
 
 	list_for_each_entry(f, &head->filters, list) {
-		u32 keys[f->nkeys];
+		u32 keys[FLOW_KEY_MAX + 1];
 		struct flow_keys flow_keys;
 
 		if (!tcf_em_tree_match(skb, &f->ematches, NULL))

^ permalink raw reply related

* Re: [PATCH] can: flexcan: fix irq flooding by clearing all interrupt sources
From: Wolfgang Grandegger @ 2011-12-14 13:21 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: netdev, linux-can, Reuben Dowle, Lothar Waßmann
In-Reply-To: <4EE77BAE.5040702@grandegger.com>

Hi Marc,

On 12/13/2011 05:22 PM, Wolfgang Grandegger wrote:
> On 12/13/2011 01:59 PM, Marc Kleine-Budde wrote:
>> On 12/13/2011 01:53 PM, Wolfgang Grandegger wrote:
>>>> I got my MX35PDK board working and can confirm, that the patch works on
>>>> a i.mx35 as well. My testing also confirms, that the ESR TWRN_INT,
>>>> RWRN_INT, FLEXCAN_ESR_BOFF_INT do not function as documented. These
>>>> flags do show up once, together with ERR_INT, and then, after clearing,
>>>> never again. Obviously a bug in the Flexcan logic. From the feedback we
>>>> can say, that only the i.MX28 does behave differently (==correctly). All
>>>> other seem to work with the current code:
>>>>
>>>>  Flexcan on
>>>>  - i.mx25
>>>>  - i.mx35
>>>>  - i.mx53
>>>>  - P1010/P1020
>>>
>>> But unfortunately, state change reporting looks different with this patch :)
>>
>> Hmm - so not schedule for stable. What about your buf-off-handling, will
>> this change the reporting again?
> 
> Well, as it is a serious problem on i.MX28, I would schedule this patch
> for stable as well. The error and state change reporting is bogus on the
> Flexcan anyhow. Without this patch, I get "active->warning->passive" if
> I send a message with cable disconnect (no ack). With patch just
> "active->warning". That's the same behaviour
> as on the i.MX28, also with my new state and bus-off handling. See:

I now understand the difference. I "flexcan_irq" we have:

	/*
	 * schedule NAPI in case of:
	 * - rx IRQ
	 * - state change IRQ
	 * - bus error IRQ and bus error reporting is activated
	 */
	if ((reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) ||
	    (reg_esr & FLEXCAN_ESR_ERR_STATE) ||
	    flexcan_has_and_handle_berr(priv, reg_esr)) {

Without this patch, "reg_esr & FLEXCAN_ESR_ERR_STATE" is *always* true
because the RWRN_INT is never cleared. This means, *any* message is
scheduled. As a nice side effect, this patch fixes this bug a well.

Only because any message is scheduled, the state change to error passive
is recognized in flexcan_poll(). The state change to error passive is
not signaled by an extra interrupt and is therefore only visible
together with RX, TX done or bus-error events.

Wolfgang.


^ 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