Netdev List
 help / color / mirror / Atom feed
* [PATCH 4/7] SUNRPC: pipefs dentry lookup helper introduced
From: Stanislav Kinsbursky @ 2011-10-28 15:25 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
	devel
In-Reply-To: <20111028142245.5796.89937.stgit@localhost6.localdomain6>

In all places, where pipefs dentries are created, only directory inode is
actually required to create new dentry. And all this directories has root
pipefs dentry as their parent. So we actually don't need this pipefs mount
point at all if some pipefs lookup method will be provided.
IOW, all we really need is just superblock and simple lookup method to find
root's child dentry with appropriate name. And this patch introduces this
method.
Note, that no locking implemented in rpc_d_lookup_sb(). So it can be used only
in case of assurance, that pipefs superblock still exist. IOW, we can use this
method only in pipefs mount-umount notification subscribers callbacks.

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

---
 include/linux/sunrpc/rpc_pipe_fs.h |    3 +++
 net/sunrpc/rpc_pipe.c              |   16 ++++++++++++++++
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index c1cdb2f..4a327ad 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -52,6 +52,9 @@ enum {
 	RPC_PIPEFS_UMOUNT,
 };
 
+extern struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
+				      const unsigned char *dir_name);
+
 extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
 
 struct rpc_clnt;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 8abeb9d..4860a56 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1020,6 +1020,22 @@ static const struct rpc_filelist files[] = {
 	},
 };
 
+/*
+ * This call can be used only in RPC pipefs mount notification hooks.
+ */
+struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
+			       const unsigned char *dir_name)
+{
+	struct qstr dir = {
+		.name = dir_name,
+		.len = strlen(dir_name),
+		.hash = full_name_hash(dir_name, strlen(dir_name)),
+	};
+
+	return d_lookup(sb->s_root, &dir);
+}
+EXPORT_SYMBOL_GPL(rpc_d_lookup_sb);
+
 static int
 rpc_fill_super(struct super_block *sb, void *data, int silent)
 {

^ permalink raw reply related

* [PATCH 3/7] SUNRPC: send notification events on pipefs sb creation and destruction
From: Stanislav Kinsbursky @ 2011-10-28 15:25 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
	devel
In-Reply-To: <20111028142245.5796.89937.stgit@localhost6.localdomain6>

They will be used to notify subscribers about pipefs superblock creation and
destruction.
Subcribers will have to create their dentries on passed superblock on mount
event and destroy otherwise.

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

---
 include/linux/sunrpc/rpc_pipe_fs.h |    8 ++++++++
 net/sunrpc/rpc_pipe.c              |   32 ++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index cf14db9..c1cdb2f 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -44,6 +44,14 @@ RPC_I(struct inode *inode)
 	return container_of(inode, struct rpc_inode, vfs_inode);
 }
 
+extern int rpc_pipefs_notifier_register(struct notifier_block *);
+extern void rpc_pipefs_notifier_unregister(struct notifier_block *);
+
+enum {
+	RPC_PIPEFS_MOUNT,
+	RPC_PIPEFS_UMOUNT,
+};
+
 extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
 
 struct rpc_clnt;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index a717564..8abeb9d 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -28,8 +28,10 @@
 #include <linux/sunrpc/rpc_pipe_fs.h>
 #include <linux/sunrpc/cache.h>
 #include <linux/nsproxy.h>
+#include <linux/notifier.h>
 
 #include "netns.h"
+#include "sunrpc.h"
 
 static struct vfsmount *rpc_mnt __read_mostly;
 static int rpc_mount_count;
@@ -41,6 +43,20 @@ static struct kmem_cache *rpc_inode_cachep __read_mostly;
 
 #define RPC_UPCALL_TIMEOUT (30*HZ)
 
+static BLOCKING_NOTIFIER_HEAD(rpc_pipefs_notifier_list);
+
+int rpc_pipefs_notifier_register(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_cond_register(&rpc_pipefs_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(rpc_pipefs_notifier_register);
+
+void rpc_pipefs_notifier_unregister(struct notifier_block *nb)
+{
+	blocking_notifier_chain_unregister(&rpc_pipefs_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(rpc_pipefs_notifier_unregister);
+
 static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head,
 		void (*destroy_msg)(struct rpc_pipe_msg *), int err)
 {
@@ -1010,6 +1026,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 	struct inode *inode;
 	struct dentry *root;
 	struct net *net = data;
+	int err;
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -1027,8 +1044,20 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 	}
 	if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL))
 		return -ENOMEM;
+	err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
+					   RPC_PIPEFS_MOUNT,
+					   sb);
+	if (err)
+		goto err_depopulate;
 	sb->s_fs_info = get_net(net);
 	return 0;
+
+err_depopulate:
+	blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
+					   RPC_PIPEFS_UMOUNT,
+					   sb);
+	__rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF);
+	return err;
 }
 
 static struct dentry *
@@ -1043,6 +1072,9 @@ void rpc_kill_sb(struct super_block *sb)
 	struct net *net = sb->s_fs_info;
 
 	put_net(net);
+	blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
+					   RPC_PIPEFS_UMOUNT,
+					   sb);
 	kill_litter_super(sb);
 }
 

^ permalink raw reply related

* [PATCH 0/7] SUNRPC: initial part of making pipefs work in net ns
From: Stanislav Kinsbursky @ 2011-10-28 15:25 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
	devel

This patch-set was created in context of clone of git branch:
git://git.linux-nfs.org/projects/trondmy/nfs-2.6.git
and rebased on tag "v3.1".

This patch-set implements pipefs superblock creation per network namespace
context instead of using single one for all possible contexts. Also, it
provides pipefs dentries creation and destruction helpers for kernel routines.

Additional description of the idea about how to make RPC pipefs work per
network namespace context can be found in the letter titled "SUNRPC: "RPC
pipefs per network namespace" preparations", which has been sent already to
linux-nfs@vger.kernel.org.

The following series consists of:

---

Stanislav Kinsbursky (7):
      SUNRPC: create RPC pipefs superblock per network namespace context
      SUNRPC: hold current network namespace while pipefs superblock is active
      SUNRPC: send notification events on pipefs sb creation and destruction
      SUNRPC: pipefs dentry lookup helper introduced
      SUNRPC: put pipefs superblock link on network namespace
      SUNRPC: pipefs per-net operations helper introduced
      SUNRPC: added debug messages to RPC pipefs


 include/linux/sunrpc/rpc_pipe_fs.h |   15 +++++
 net/sunrpc/netns.h                 |    3 +
 net/sunrpc/rpc_pipe.c              |  113 +++++++++++++++++++++++++++++++++++-
 net/sunrpc/sunrpc_syms.c           |    1 
 4 files changed, 130 insertions(+), 2 deletions(-)

^ permalink raw reply

* Re: >Re: [RFC] should VM_BUG_ON(cond) really evaluate cond
From: Linus Torvalds @ 2011-10-28 14:55 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Ben Hutchings, Andi Kleen, linux-kernel, netdev, Andrew Morton
In-Reply-To: <1319813252.23112.122.camel@edumazet-laptop>

On Fri, Oct 28, 2011 at 7:47 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> So we need a similar idea to remove the volatile from :
>
> static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr)
> {
> return ((1UL << (nr % BITS_PER_LONG)) &
>         (addr[nr / BITS_PER_LONG])) != 0;

Ho humm. Yeah, I think "test_bit()" falls under the same logic: we do
not want to combine multiple test-bits into one (because we know there
are people looping on it), and we do want to guarantee "access at most
once" semantics, but as with "atomic_read()" we should be able to
optimize away a totally unused test-bit.

The same "empty asm" trick would work there, I think, rather than
using "volatile" (well, the function declaration would still have
"volatile" because it's legal to use a volatile data type, but we'd
cast it away and use the asm trick for the access instead) .

Maybe we should make it a generic helper macro ("ACCESS_AT_MOST_ONCE()")?

Comments? I think I'm open to tested patches..

                      Linus

^ permalink raw reply

* Re: >Re: [RFC] should VM_BUG_ON(cond) really evaluate cond
From: Eric Dumazet @ 2011-10-28 14:47 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Ben Hutchings, Andi Kleen, linux-kernel, netdev, Andrew Morton
In-Reply-To: <CA+55aFxy6VSBbikFrfXwUPOafihR+MOdi+yKSp_6qz7_Vax_YA@mail.gmail.com>

Le vendredi 28 octobre 2011 à 05:40 -0700, Linus Torvalds a écrit :
> On Fri, Oct 28, 2011 at 5:19 AM, Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
> >
> > "Sane interfaces" are important. Insane interfaces lead to bugs.
> 
> Qutie frankly, if I do "atomic_read()", I do expect to get a single
> value. If I don't get a single value, but some mixture of two values,
> I'd personally go
> 
>   wtf, what does that "atomic" mean in "atomic_read()"?
> 
> and I think that's a reasonable wtf to ask.
> 
> That said, as mentioned, I don't know of any way to tell gcc "at most once".
> 
> Hmm.
> 
> Except perhaps using inline asm. Something like this might work:
> 
>   static inline int atomic_read(const atomic_t *v)
>   {
>        int val;
>        asm("":"=r" (val):"0" (v->value));
>        return val;
>   }
> 
> (totally untested, but you get the idea: use a non-volatile asm to
> make sure that gcc doesn't think it can re-load the value).
> 
> That's the trick we use in asmlinkage_protect() and a couple of other
> places. It *should* make gcc able to optimize the value away entirely
> if it isn't used, but will stop gcc from doing the reload magic.
> 
> Does that work for the test-case with VM_BUG_ON()?


On x86 it seems to work :

c050f80f: 0f 84 ea 00 00 00       je     c050f8ff <tcp_sendmsg+0xa1f>
c050f815: 8b 55 bc                mov    -0x44(%ebp),%edx
c050f818: f0 ff 42 10             lock incl 0x10(%edx)      atomic_inc(&page->count)
c050f81c: 8b 02                   mov    (%edx),%eax        page->flags
c050f81e: 25 00 40 02 00          and    $0x24000,%eax
c050f823: 3d 00 40 02 00          cmp    $0x24000,%eax
c050f828: 0f 84 9f 01 00 00       je     c050f9cd <tcp_sendmsg+0xaed>

On x86_64 (gcc-4.6.1 Debian-4.6.1-4) we still have a page->flags useless load,
but the atomic_read() itself is removed.


This looks like a CONFIG_PAGEFLAGS_EXTENDED difference.

In this case, PageTail() is :

#define TESTPAGEFLAG(uname, lname)                  \
static inline int Page##uname(const struct page *page)          \
	{ return test_bit(PG_##lname, &page->flags); } 


So we need a similar idea to remove the volatile from :

static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr)
{
return ((1UL << (nr % BITS_PER_LONG)) &
	 (addr[nr / BITS_PER_LONG])) != 0;
}

^ permalink raw reply

* [PATCH 2/7] SUNRPC: hold current network namespace while pipefs superblock is active
From: Stanislav Kinsbursky @ 2011-10-28 15:25 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
	devel
In-Reply-To: <20111028142245.5796.89937.stgit@localhost6.localdomain6>

We want to be sure that network namespace is still alive while we have pipefs
mounted.
This will be required later, when RPC pipefs will be mounting only from
user-space context.

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

---
 net/sunrpc/rpc_pipe.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index ad517bd..a717564 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -27,6 +27,9 @@
 #include <linux/workqueue.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
 #include <linux/sunrpc/cache.h>
+#include <linux/nsproxy.h>
+
+#include "netns.h"
 
 static struct vfsmount *rpc_mnt __read_mostly;
 static int rpc_mount_count;
@@ -1024,6 +1027,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 	}
 	if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL))
 		return -ENOMEM;
+	sb->s_fs_info = get_net(net);
 	return 0;
 }
 
@@ -1034,11 +1038,19 @@ rpc_mount(struct file_system_type *fs_type,
 	return mount_ns(fs_type, flags, current->nsproxy->net_ns, rpc_fill_super);
 }
 
+void rpc_kill_sb(struct super_block *sb)
+{
+	struct net *net = sb->s_fs_info;
+
+	put_net(net);
+	kill_litter_super(sb);
+}
+
 static struct file_system_type rpc_pipe_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "rpc_pipefs",
 	.mount		= rpc_mount,
-	.kill_sb	= kill_litter_super,
+	.kill_sb	= rpc_kill_sb,
 };
 
 static void

^ permalink raw reply related

* [PATCH 1/7] SUNRPC: create RPC pipefs superblock per network namespace context
From: Stanislav Kinsbursky @ 2011-10-28 15:25 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
	devel
In-Reply-To: <20111028142245.5796.89937.stgit@localhost6.localdomain6>

This is the initial step of RPC pipefs virtualization. It changes nothing to
current pipefs behaviour except that mount of pipefs in other than init_net
network namespace context will provide only root tree. No other dentries will
be visible.

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

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

diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index b181e34..ad517bd 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1006,6 +1006,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;
 	struct dentry *root;
+	struct net *net = data;
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -1030,7 +1031,7 @@ static struct dentry *
 rpc_mount(struct file_system_type *fs_type,
 		int flags, const char *dev_name, void *data)
 {
-	return mount_single(fs_type, flags, data, rpc_fill_super);
+	return mount_ns(fs_type, flags, current->nsproxy->net_ns, rpc_fill_super);
 }
 
 static struct file_system_type rpc_pipe_fs_type = {

^ permalink raw reply related

* Re: [PATCH v7 0/7] SUNRPC: make rpcbind clients allocated and destroyed dynamically
From: J. Bruce Fields @ 2011-10-28 14:23 UTC (permalink / raw)
  To: Stanislav Kinsbursky
  Cc: Trond.Myklebust, linux-nfs, xemul, neilb, netdev, linux-kernel,
	davem, devel
In-Reply-To: <20111028104530.24628.23631.stgit@localhost6.localdomain6>

On Fri, Oct 28, 2011 at 02:52:09PM +0300, Stanislav Kinsbursky wrote:
> This patch-set was created in context of clone of git branch:
> git://git.linux-nfs.org/projects/trondmy/nfs-2.6.git
> and rebased on tag "v3.1".
> 
> v7:
> 1) Implemented "goto pattern" in __svc_create().
> 2) Pathes 5 and 6 from perious patch-set were squashed to make things looks
> clearer and to allow safe bisecting of the patch-set.

This series looks fine to me; thanks!

--b.

> 
> v6:
> 1) Fixes in rpcb_clients management.
> 
> v4:
> 1) creation and destruction on rpcbind clients now depends on service program
> versions "vs_hidden" flag.
> 
> This patch is required for further RPC layer virtualization, because rpcbind
> clients have to be per network namespace.
> To achive this, we have to untie network namespace from rpcbind clients sockets.
> The idea of this patch set is to make rpcbind clients non-static. I.e. rpcbind
> clients will be created during first RPC service creation, and destroyed when
> last RPC service is stopped.
> With this patch set rpcbind clients can be virtualized easely.
> 
> The following series consists of:
> 
> ---
> 
> Stanislav Kinsbursky (7):
>       SUNRPC: introduce helpers for reference counted rpcbind clients
>       SUNRPC: use rpcbind reference counting helpers
>       SUNRPC: introduce svc helpers for prepairing rpcbind infrastructure
>       SUNRPC: setup rpcbind clients if service requires it
>       SUNRPC: cleanup service destruction
>       SUNRPC: remove rpcbind clients creation during service registering
>       SUNRPC: remove rpcbind clients destruction on module cleanup
> 
> 
>  fs/nfsd/nfssvc.c            |    2 +
>  include/linux/sunrpc/clnt.h |    2 +
>  include/linux/sunrpc/svc.h  |    1 
>  net/sunrpc/rpcb_clnt.c      |   88 ++++++++++++++++++++++++++++---------------
>  net/sunrpc/sunrpc_syms.c    |    3 -
>  net/sunrpc/svc.c            |   57 ++++++++++++++++++++++++----
>  6 files changed, 113 insertions(+), 40 deletions(-)
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v7 5/7] SUNRPC: cleanup service destruction
From: J. Bruce Fields @ 2011-10-28 14:22 UTC (permalink / raw)
  To: Stanislav Kinsbursky
  Cc: Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA, xemul-bzQdu9zFT3WakBO8gow8eQ,
	neilb-l3A5Bk7waGM, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	devel-GEFAQzZX7r8dnm+yROfE0A
In-Reply-To: <20111028105326.24628.81582.stgit-bi+AKbBUZKagILUCTcTcHdKyNwTtLsGr@public.gmane.org>

On Fri, Oct 28, 2011 at 02:53:43PM +0300, Stanislav Kinsbursky wrote:
> svc_unregister() call have to be removed from svc_destroy() since it will be
> called in sv_shutdown callback.
> This also means, that we have to call svc_rpcb_cleanup() explicitly from
> nfsd_last_thread() since this function is registered as service shutdown
> callback and thus nobody else will done it for us.
> 
> Signed-off-by: Stanislav Kinsbursky <skinsbursky-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>

Acked-by: J. Bruce Fields <bfields-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

> 
> ---
>  fs/nfsd/nfssvc.c           |    2 ++
>  include/linux/sunrpc/svc.h |    1 +
>  net/sunrpc/svc.c           |    4 ++--
>  3 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
> index dc5a1bf..52cd976 100644
> --- a/fs/nfsd/nfssvc.c
> +++ b/fs/nfsd/nfssvc.c
> @@ -256,6 +256,8 @@ static void nfsd_last_thread(struct svc_serv *serv)
>  	nfsd_serv = NULL;
>  	nfsd_shutdown();
>  
> +	svc_rpcb_cleanup(serv);
> +
>  	printk(KERN_WARNING "nfsd: last server has exited, flushing export "
>  			    "cache\n");
>  	nfsd_export_flush();
> diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
> index 223588a..5e71a30 100644
> --- a/include/linux/sunrpc/svc.h
> +++ b/include/linux/sunrpc/svc.h
> @@ -401,6 +401,7 @@ struct svc_procedure {
>  /*
>   * Function prototypes.
>   */
> +void svc_rpcb_cleanup(struct svc_serv *serv);
>  struct svc_serv *svc_create(struct svc_program *, unsigned int,
>  			    void (*shutdown)(struct svc_serv *));
>  struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
> diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
> index 87a67b2..96df2ba 100644
> --- a/net/sunrpc/svc.c
> +++ b/net/sunrpc/svc.c
> @@ -367,11 +367,12 @@ static int svc_rpcb_setup(struct svc_serv *serv)
>  	return 0;
>  }
>  
> -static void svc_rpcb_cleanup(struct svc_serv *serv)
> +void svc_rpcb_cleanup(struct svc_serv *serv)
>  {
>  	svc_unregister(serv);
>  	rpcb_put_local();
>  }
> +EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
>  
>  static int svc_uses_rpcbind(struct svc_serv *serv)
>  {
> @@ -531,7 +532,6 @@ svc_destroy(struct svc_serv *serv)
>  	if (svc_serv_is_pooled(serv))
>  		svc_pool_map_put();
>  
> -	svc_unregister(serv);
>  	kfree(serv->sv_pools);
>  	kfree(serv);
>  }
> 
> --
> 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
--
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

* Re: [PATCH v7 4/7] SUNRPC: setup rpcbind clients if service requires it
From: J. Bruce Fields @ 2011-10-28 14:22 UTC (permalink / raw)
  To: Stanislav Kinsbursky
  Cc: Trond.Myklebust, linux-nfs, xemul, neilb, netdev, linux-kernel,
	davem, devel
In-Reply-To: <20111028105307.24628.89889.stgit@localhost6.localdomain6>

On Fri, Oct 28, 2011 at 02:53:18PM +0300, Stanislav Kinsbursky wrote:
> New function ("svc_uses_rpcbind") will be used to detect, that new service will
> send portmapper register calls. For such services we will create rpcbind
> clients and remove all stale portmap registrations.
> Also, svc_rpcb_cleanup() will be set as sv_shutdown callback for such services
> in case of this field wasn't initialized earlier. This will allow to destroy
> rpcbind clients when no other users of them left.
> 
> Note: Currently, any creating service will be detected as portmap user.
> Probably, this is wrong. But now it depends on program versions "vs_hidden"
> flag.
> 
> Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

Acked-by: J. Bruce Fields <bfields@redhat.com>

> 
> ---
>  net/sunrpc/svc.c |   20 ++++++++++++++------
>  1 files changed, 14 insertions(+), 6 deletions(-)
> 
> diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
> index d2d61bf..87a67b2 100644
> --- a/net/sunrpc/svc.c
> +++ b/net/sunrpc/svc.c
> @@ -436,10 +436,8 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
>  	serv->sv_pools =
>  		kcalloc(serv->sv_nrpools, sizeof(struct svc_pool),
>  			GFP_KERNEL);
> -	if (!serv->sv_pools) {
> -		kfree(serv);
> -		return NULL;
> -	}
> +	if (!serv->sv_pools)
> +		goto err_serv;
>  
>  	for (i = 0; i < serv->sv_nrpools; i++) {
>  		struct svc_pool *pool = &serv->sv_pools[i];
> @@ -454,10 +452,20 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
>  		spin_lock_init(&pool->sp_lock);
>  	}
>  
> -	/* Remove any stale portmap registrations */
> -	svc_unregister(serv);
> +	if (svc_uses_rpcbind(serv)) {
> +	       	if (svc_rpcb_setup(serv) < 0)
> +			goto err_rpcb;
> +		if (!serv->sv_shutdown)
> +			serv->sv_shutdown = svc_rpcb_cleanup;
> +	}
>  
>  	return serv;
> +
> +err_rpcb:
> +	kfree(serv->sv_pools);
> +err_serv:
> +	kfree(serv);
> +	return NULL;
>  }
>  
>  struct svc_serv *
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v7 3/7] SUNRPC: introduce svc helpers for prepairing rpcbind infrastructure
From: J. Bruce Fields @ 2011-10-28 14:22 UTC (permalink / raw)
  To: Stanislav Kinsbursky
  Cc: Trond.Myklebust, linux-nfs, xemul, neilb, netdev, linux-kernel,
	davem, devel
In-Reply-To: <20111028105254.24628.49150.stgit@localhost6.localdomain6>

On Fri, Oct 28, 2011 at 02:52:59PM +0300, Stanislav Kinsbursky wrote:
> This helpers will be used only for those services, that will send portmapper
> registration calls.
> 
> Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

Acked-by: J. Bruce Fields <bfields@redhat.com>

> 
> ---
>  include/linux/sunrpc/clnt.h |    2 ++
>  net/sunrpc/rpcb_clnt.c      |    2 +-
>  net/sunrpc/svc.c            |   35 +++++++++++++++++++++++++++++++++++
>  3 files changed, 38 insertions(+), 1 deletions(-)
> 
> diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
> index db7bcaf..1eb437d 100644
> --- a/include/linux/sunrpc/clnt.h
> +++ b/include/linux/sunrpc/clnt.h
> @@ -135,6 +135,8 @@ void		rpc_shutdown_client(struct rpc_clnt *);
>  void		rpc_release_client(struct rpc_clnt *);
>  void		rpc_task_release_client(struct rpc_task *);
>  
> +int		rpcb_create_local(void);
> +void		rpcb_put_local(void);
>  int		rpcb_register(u32, u32, int, unsigned short);
>  int		rpcb_v4_register(const u32 program, const u32 version,
>  				 const struct sockaddr *address,
> diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
> index 115df11..c144b95 100644
> --- a/net/sunrpc/rpcb_clnt.c
> +++ b/net/sunrpc/rpcb_clnt.c
> @@ -320,7 +320,7 @@ out:
>   * Returns zero on success, otherwise a negative errno value
>   * is returned.
>   */
> -static int rpcb_create_local(void)
> +int rpcb_create_local(void)
>  {
>  	static DEFINE_MUTEX(rpcb_create_local_mutex);
>  	int result = 0;
> diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
> index 6a69a11..d2d61bf 100644
> --- a/net/sunrpc/svc.c
> +++ b/net/sunrpc/svc.c
> @@ -354,6 +354,41 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu)
>  	return &serv->sv_pools[pidx % serv->sv_nrpools];
>  }
>  
> +static int svc_rpcb_setup(struct svc_serv *serv)
> +{
> +	int err;
> +
> +	err = rpcb_create_local();
> +	if (err)
> +		return err;
> +
> +	/* Remove any stale portmap registrations */
> +	svc_unregister(serv);
> +	return 0;
> +}
> +
> +static void svc_rpcb_cleanup(struct svc_serv *serv)
> +{
> +	svc_unregister(serv);
> +	rpcb_put_local();
> +}
> +
> +static int svc_uses_rpcbind(struct svc_serv *serv)
> +{
> +	struct svc_program	*progp;
> +	unsigned int		i;
> +
> +	for (progp = serv->sv_program; progp; progp = progp->pg_next) {
> +		for (i = 0; i < progp->pg_nvers; i++) {
> +			if (progp->pg_vers[i] == NULL)
> +				continue;
> +			if (progp->pg_vers[i]->vs_hidden == 0)
> +				return 1;
> +		}
> +	}
> +
> +	return 0;
> +}
>  
>  /*
>   * Create an RPC service
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH] ipv6: fix route error binding peer in func icmp6_dst_alloc
From: Gao feng @ 2011-10-28 12:46 UTC (permalink / raw)
  To: davem, eric.dumazet; +Cc: netdev, gaofeng, Gao feng

in func icmp6_dst_alloc,dst_metric_set call ipv6_cow_metrics to set metric.
ipv6_cow_metrics may will call rt6_bind_peer to set rt6_info->rt6i_peer.
So,we should move ipv6_addr_copy before dst_metric_set to make sure rt6_bind_peer success.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 net/ipv6/route.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index fb545ed..57b82dc 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1086,11 +1086,10 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
 	rt->dst.output  = ip6_output;
 	dst_set_neighbour(&rt->dst, neigh);
 	atomic_set(&rt->dst.__refcnt, 1);
-	dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);
-
 	ipv6_addr_copy(&rt->rt6i_dst.addr, addr);
 	rt->rt6i_dst.plen = 128;
 	rt->rt6i_idev     = idev;
+	dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);
 
 	spin_lock_bh(&icmp6_dst_lock);
 	rt->dst.next = icmp6_dst_gc_list;
-- 
1.7.5.4

^ permalink raw reply related

* Re: >Re: [RFC] should VM_BUG_ON(cond) really evaluate cond
From: Linus Torvalds @ 2011-10-28 12:40 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Ben Hutchings, Andi Kleen, linux-kernel, netdev, Andrew Morton
In-Reply-To: <CA+55aFxzgc5pC1p6J8YADNDwmAjUYNRKLvir6OQMueWqUXOaEQ@mail.gmail.com>

On Fri, Oct 28, 2011 at 5:19 AM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> "Sane interfaces" are important. Insane interfaces lead to bugs.

Qutie frankly, if I do "atomic_read()", I do expect to get a single
value. If I don't get a single value, but some mixture of two values,
I'd personally go

  wtf, what does that "atomic" mean in "atomic_read()"?

and I think that's a reasonable wtf to ask.

That said, as mentioned, I don't know of any way to tell gcc "at most once".

Hmm.

Except perhaps using inline asm. Something like this might work:

  static inline int atomic_read(const atomic_t *v)
  {
       int val;
       asm("":"=r" (val):"0" (v->value));
       return val;
  }

(totally untested, but you get the idea: use a non-volatile asm to
make sure that gcc doesn't think it can re-load the value).

That's the trick we use in asmlinkage_protect() and a couple of other
places. It *should* make gcc able to optimize the value away entirely
if it isn't used, but will stop gcc from doing the reload magic.

Does that work for the test-case with VM_BUG_ON()?

                          Linus

^ permalink raw reply

* Re: >Re: [RFC] should VM_BUG_ON(cond) really evaluate cond
From: Linus Torvalds @ 2011-10-28 12:19 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Ben Hutchings, Andi Kleen, linux-kernel, netdev, Andrew Morton
In-Reply-To: <1319803781.23112.113.camel@edumazet-laptop>

On Fri, Oct 28, 2011 at 5:09 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> What you describe is true for non atomic variables as well, its not part
> of the atomic_ops documented semantic.

Eric - your "documentation" is so much toilet paper. So don't bother
talkign about "documented semantics". Start talking about SANE
INTERFACES.

What I described is very much true of non-atomics. Nobody doubts that.

THE QUESTION IS WHETHER IT MAKES SENSE FOR ATOMICS, DAMMIT!

And quite frankly, the behavior I described does not seem to make any
sense for atomics.

"Sane interfaces" are important. Insane interfaces lead to bugs.

                      Linus

^ permalink raw reply

* Re: >Re: [RFC] should VM_BUG_ON(cond) really evaluate cond
From: Eric Dumazet @ 2011-10-28 12:09 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Ben Hutchings, Andi Kleen, linux-kernel, netdev, Andrew Morton
In-Reply-To: <CA+55aFzHf563auNYdNeJnsbbry1OUfkepkiVHt7Fy-bG64Fruw@mail.gmail.com>

Le vendredi 28 octobre 2011 à 04:37 -0700, Linus Torvalds a écrit :
> On Thu, Oct 27, 2011 at 9:43 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> >
> > The only requirement of atomic_read() is that it must return value
> > before or after an atomic_write(), not a garbled value.
> 
> The problem is that gcc *can* return a garbled value.
> 
> > In fact, if a compiler is stupid enough to issue two reads on following
> > code :
> 
> The compiler really *can* be that "stupid". Except the code tends to
> look like this:
> 
>    int value = atomic_read(&atomic_var);
>    if (value > 10)
>      return;
>    .. do something with value ..
> 
> and gcc may decide - under register pressure, and in the absense of a
> 'volatile' - to read 'value' first once for that "> 10" check, and
> then it drops the registers and instead of saving it on the stack
> frame, it can decide to re-load it from atomic_var.
> 
> IOW, "value" could be two or more different values: one value when
> testing, and *another* value in "do something with value".
> 
> This is why we have "ACCESS_ONCE()".
> 
> Whether atomics guarantee ACCESS_ONCE() semantics or not is not
> entirely clear. But afaik, there is no way to tell gcc "access at
> *most* once, and never ever reload".
> 

What you describe is true for non atomic variables as well, its not part
of the atomic_ops documented semantic.

And we do use ACCESS_ONCE() on the rare cases we need to make sure no
reload is done.

RCU use makes this implied (ACCESS_ONCE() being done in
rcu_dereference()), so we dont have many raw ACCESS_ONCE() in our code.

int value = ACCESS_ONCE(atomic_read(&atomic_var));
if (value > 10)
     return;
.. do something with value ..

One of such rare use is explained in commit f1987257
(tcp: protect sysctl_tcp_cookie_size reads)

Since its a bit ugly, I suggested :

int value = atomic_read_once(&atomic_var);
if (value > 10)
     return;
    .. do something with value ..

I dont know, it seems the right way, but yes it might break things.

We can take the otherway and patch thousand atomic_read() to
atomic_read_stable(), its safer but very boring :)

^ permalink raw reply

* [PATCH v7 7/7] SUNRPC: remove rpcbind clients destruction on module cleanup
From: Stanislav Kinsbursky @ 2011-10-28 11:54 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
	devel
In-Reply-To: <20111028104530.24628.23631.stgit@localhost6.localdomain6>

Rpcbind clients destruction during SUNRPC module removing is obsolete since now
those clients are destroying during last RPC service shutdown.

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

---
 net/sunrpc/rpcb_clnt.c   |   12 ------------
 net/sunrpc/sunrpc_syms.c |    3 ---
 2 files changed, 0 insertions(+), 15 deletions(-)

diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 115c691..983b74f 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -1100,15 +1100,3 @@ static struct rpc_program rpcb_program = {
 	.version	= rpcb_version,
 	.stats		= &rpcb_stats,
 };
-
-/**
- * cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
- *
- */
-void cleanup_rpcb_clnt(void)
-{
-	if (rpcb_local_clnt4)
-		rpc_shutdown_client(rpcb_local_clnt4);
-	if (rpcb_local_clnt)
-		rpc_shutdown_client(rpcb_local_clnt);
-}
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 9d08091..8ec9778 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -61,8 +61,6 @@ static struct pernet_operations sunrpc_net_ops = {
 
 extern struct cache_detail unix_gid_cache;
 
-extern void cleanup_rpcb_clnt(void);
-
 static int __init
 init_sunrpc(void)
 {
@@ -102,7 +100,6 @@ out:
 static void __exit
 cleanup_sunrpc(void)
 {
-	cleanup_rpcb_clnt();
 	rpcauth_remove_module();
 	cleanup_socket_xprt();
 	svc_cleanup_xprt_sock();

^ permalink raw reply related

* [PATCH v7 6/7] SUNRPC: remove rpcbind clients creation during service registering
From: Stanislav Kinsbursky @ 2011-10-28 11:53 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
	devel
In-Reply-To: <20111028104530.24628.23631.stgit@localhost6.localdomain6>

We don't need this code since rpcbind clients are creating during RPC service
creation.

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

---
 net/sunrpc/rpcb_clnt.c |    9 ---------
 1 files changed, 0 insertions(+), 9 deletions(-)

diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index c144b95..115c691 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -431,11 +431,6 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
 	struct rpc_message msg = {
 		.rpc_argp	= &map,
 	};
-	int error;
-
-	error = rpcb_create_local();
-	if (error)
-		return error;
 
 	dprintk("RPC:       %sregistering (%u, %u, %d, %u) with local "
 			"rpcbind\n", (port ? "" : "un"),
@@ -571,11 +566,7 @@ int rpcb_v4_register(const u32 program, const u32 version,
 	struct rpc_message msg = {
 		.rpc_argp	= &map,
 	};
-	int error;
 
-	error = rpcb_create_local();
-	if (error)
-		return error;
 	if (rpcb_local_clnt4 == NULL)
 		return -EPROTONOSUPPORT;
 

^ permalink raw reply related

* [PATCH v7 5/7] SUNRPC: cleanup service destruction
From: Stanislav Kinsbursky @ 2011-10-28 11:53 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
	devel
In-Reply-To: <20111028104530.24628.23631.stgit@localhost6.localdomain6>

svc_unregister() call have to be removed from svc_destroy() since it will be
called in sv_shutdown callback.
This also means, that we have to call svc_rpcb_cleanup() explicitly from
nfsd_last_thread() since this function is registered as service shutdown
callback and thus nobody else will done it for us.

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

---
 fs/nfsd/nfssvc.c           |    2 ++
 include/linux/sunrpc/svc.h |    1 +
 net/sunrpc/svc.c           |    4 ++--
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index dc5a1bf..52cd976 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -256,6 +256,8 @@ static void nfsd_last_thread(struct svc_serv *serv)
 	nfsd_serv = NULL;
 	nfsd_shutdown();
 
+	svc_rpcb_cleanup(serv);
+
 	printk(KERN_WARNING "nfsd: last server has exited, flushing export "
 			    "cache\n");
 	nfsd_export_flush();
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 223588a..5e71a30 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -401,6 +401,7 @@ struct svc_procedure {
 /*
  * Function prototypes.
  */
+void svc_rpcb_cleanup(struct svc_serv *serv);
 struct svc_serv *svc_create(struct svc_program *, unsigned int,
 			    void (*shutdown)(struct svc_serv *));
 struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 87a67b2..96df2ba 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -367,11 +367,12 @@ static int svc_rpcb_setup(struct svc_serv *serv)
 	return 0;
 }
 
-static void svc_rpcb_cleanup(struct svc_serv *serv)
+void svc_rpcb_cleanup(struct svc_serv *serv)
 {
 	svc_unregister(serv);
 	rpcb_put_local();
 }
+EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
 
 static int svc_uses_rpcbind(struct svc_serv *serv)
 {
@@ -531,7 +532,6 @@ svc_destroy(struct svc_serv *serv)
 	if (svc_serv_is_pooled(serv))
 		svc_pool_map_put();
 
-	svc_unregister(serv);
 	kfree(serv->sv_pools);
 	kfree(serv);
 }

^ permalink raw reply related

* [PATCH v7 4/7] SUNRPC: setup rpcbind clients if service requires it
From: Stanislav Kinsbursky @ 2011-10-28 11:53 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
	devel
In-Reply-To: <20111028104530.24628.23631.stgit@localhost6.localdomain6>

New function ("svc_uses_rpcbind") will be used to detect, that new service will
send portmapper register calls. For such services we will create rpcbind
clients and remove all stale portmap registrations.
Also, svc_rpcb_cleanup() will be set as sv_shutdown callback for such services
in case of this field wasn't initialized earlier. This will allow to destroy
rpcbind clients when no other users of them left.

Note: Currently, any creating service will be detected as portmap user.
Probably, this is wrong. But now it depends on program versions "vs_hidden"
flag.

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

---
 net/sunrpc/svc.c |   20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index d2d61bf..87a67b2 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -436,10 +436,8 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
 	serv->sv_pools =
 		kcalloc(serv->sv_nrpools, sizeof(struct svc_pool),
 			GFP_KERNEL);
-	if (!serv->sv_pools) {
-		kfree(serv);
-		return NULL;
-	}
+	if (!serv->sv_pools)
+		goto err_serv;
 
 	for (i = 0; i < serv->sv_nrpools; i++) {
 		struct svc_pool *pool = &serv->sv_pools[i];
@@ -454,10 +452,20 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
 		spin_lock_init(&pool->sp_lock);
 	}
 
-	/* Remove any stale portmap registrations */
-	svc_unregister(serv);
+	if (svc_uses_rpcbind(serv)) {
+	       	if (svc_rpcb_setup(serv) < 0)
+			goto err_rpcb;
+		if (!serv->sv_shutdown)
+			serv->sv_shutdown = svc_rpcb_cleanup;
+	}
 
 	return serv;
+
+err_rpcb:
+	kfree(serv->sv_pools);
+err_serv:
+	kfree(serv);
+	return NULL;
 }
 
 struct svc_serv *

^ permalink raw reply related

* [PATCH v7 3/7] SUNRPC: introduce svc helpers for prepairing rpcbind infrastructure
From: Stanislav Kinsbursky @ 2011-10-28 11:52 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
	devel
In-Reply-To: <20111028104530.24628.23631.stgit@localhost6.localdomain6>

This helpers will be used only for those services, that will send portmapper
registration calls.

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

---
 include/linux/sunrpc/clnt.h |    2 ++
 net/sunrpc/rpcb_clnt.c      |    2 +-
 net/sunrpc/svc.c            |   35 +++++++++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+), 1 deletions(-)

diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index db7bcaf..1eb437d 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -135,6 +135,8 @@ void		rpc_shutdown_client(struct rpc_clnt *);
 void		rpc_release_client(struct rpc_clnt *);
 void		rpc_task_release_client(struct rpc_task *);
 
+int		rpcb_create_local(void);
+void		rpcb_put_local(void);
 int		rpcb_register(u32, u32, int, unsigned short);
 int		rpcb_v4_register(const u32 program, const u32 version,
 				 const struct sockaddr *address,
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 115df11..c144b95 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -320,7 +320,7 @@ out:
  * Returns zero on success, otherwise a negative errno value
  * is returned.
  */
-static int rpcb_create_local(void)
+int rpcb_create_local(void)
 {
 	static DEFINE_MUTEX(rpcb_create_local_mutex);
 	int result = 0;
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 6a69a11..d2d61bf 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -354,6 +354,41 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu)
 	return &serv->sv_pools[pidx % serv->sv_nrpools];
 }
 
+static int svc_rpcb_setup(struct svc_serv *serv)
+{
+	int err;
+
+	err = rpcb_create_local();
+	if (err)
+		return err;
+
+	/* Remove any stale portmap registrations */
+	svc_unregister(serv);
+	return 0;
+}
+
+static void svc_rpcb_cleanup(struct svc_serv *serv)
+{
+	svc_unregister(serv);
+	rpcb_put_local();
+}
+
+static int svc_uses_rpcbind(struct svc_serv *serv)
+{
+	struct svc_program	*progp;
+	unsigned int		i;
+
+	for (progp = serv->sv_program; progp; progp = progp->pg_next) {
+		for (i = 0; i < progp->pg_nvers; i++) {
+			if (progp->pg_vers[i] == NULL)
+				continue;
+			if (progp->pg_vers[i]->vs_hidden == 0)
+				return 1;
+		}
+	}
+
+	return 0;
+}
 
 /*
  * Create an RPC service

^ permalink raw reply related

* [PATCH v7 2/7] SUNRPC: use rpcbind reference counting helpers
From: Stanislav Kinsbursky @ 2011-10-28 11:52 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
	devel
In-Reply-To: <20111028104530.24628.23631.stgit@localhost6.localdomain6>

All is simple: we just increase users counter if rpcbind clients has been
created already. Otherwise we create them and set users counter to 1.

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

---
 net/sunrpc/rpcb_clnt.c |   12 ++++--------
 1 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 9830d87..115df11 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -258,9 +258,7 @@ static int rpcb_create_local_unix(void)
 		clnt4 = NULL;
 	}
 
-	/* Protected by rpcb_create_local_mutex */
-	rpcb_local_clnt = clnt;
-	rpcb_local_clnt4 = clnt4;
+	rpcb_set_local(clnt, clnt4);
 
 out:
 	return result;
@@ -312,9 +310,7 @@ static int rpcb_create_local_net(void)
 		clnt4 = NULL;
 	}
 
-	/* Protected by rpcb_create_local_mutex */
-	rpcb_local_clnt = clnt;
-	rpcb_local_clnt4 = clnt4;
+	rpcb_set_local(clnt, clnt4);
 
 out:
 	return result;
@@ -329,11 +325,11 @@ static int rpcb_create_local(void)
 	static DEFINE_MUTEX(rpcb_create_local_mutex);
 	int result = 0;
 
-	if (rpcb_local_clnt)
+	if (rpcb_get_local())
 		return result;
 
 	mutex_lock(&rpcb_create_local_mutex);
-	if (rpcb_local_clnt)
+	if (rpcb_get_local())
 		goto out;
 
 	if (rpcb_create_local_unix() != 0)

^ permalink raw reply related

* [PATCH v7 0/7] SUNRPC: make rpcbind clients allocated and destroyed dynamically
From: Stanislav Kinsbursky @ 2011-10-28 11:52 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
	devel

This patch-set was created in context of clone of git branch:
git://git.linux-nfs.org/projects/trondmy/nfs-2.6.git
and rebased on tag "v3.1".

v7:
1) Implemented "goto pattern" in __svc_create().
2) Pathes 5 and 6 from perious patch-set were squashed to make things looks
clearer and to allow safe bisecting of the patch-set.

v6:
1) Fixes in rpcb_clients management.

v4:
1) creation and destruction on rpcbind clients now depends on service program
versions "vs_hidden" flag.

This patch is required for further RPC layer virtualization, because rpcbind
clients have to be per network namespace.
To achive this, we have to untie network namespace from rpcbind clients sockets.
The idea of this patch set is to make rpcbind clients non-static. I.e. rpcbind
clients will be created during first RPC service creation, and destroyed when
last RPC service is stopped.
With this patch set rpcbind clients can be virtualized easely.

The following series consists of:

---

Stanislav Kinsbursky (7):
      SUNRPC: introduce helpers for reference counted rpcbind clients
      SUNRPC: use rpcbind reference counting helpers
      SUNRPC: introduce svc helpers for prepairing rpcbind infrastructure
      SUNRPC: setup rpcbind clients if service requires it
      SUNRPC: cleanup service destruction
      SUNRPC: remove rpcbind clients creation during service registering
      SUNRPC: remove rpcbind clients destruction on module cleanup


 fs/nfsd/nfssvc.c            |    2 +
 include/linux/sunrpc/clnt.h |    2 +
 include/linux/sunrpc/svc.h  |    1 
 net/sunrpc/rpcb_clnt.c      |   88 ++++++++++++++++++++++++++++---------------
 net/sunrpc/sunrpc_syms.c    |    3 -
 net/sunrpc/svc.c            |   57 ++++++++++++++++++++++++----
 6 files changed, 113 insertions(+), 40 deletions(-)

^ permalink raw reply

* Re: >Re: [RFC] should VM_BUG_ON(cond) really evaluate cond
From: Linus Torvalds @ 2011-10-28 11:37 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Ben Hutchings, Andi Kleen, linux-kernel, netdev, Andrew Morton
In-Reply-To: <1319777025.23112.67.camel@edumazet-laptop>

On Thu, Oct 27, 2011 at 9:43 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> The only requirement of atomic_read() is that it must return value
> before or after an atomic_write(), not a garbled value.

The problem is that gcc *can* return a garbled value.

> In fact, if a compiler is stupid enough to issue two reads on following
> code :

The compiler really *can* be that "stupid". Except the code tends to
look like this:

   int value = atomic_read(&atomic_var);
   if (value > 10)
     return;
   .. do something with value ..

and gcc may decide - under register pressure, and in the absense of a
'volatile' - to read 'value' first once for that "> 10" check, and
then it drops the registers and instead of saving it on the stack
frame, it can decide to re-load it from atomic_var.

IOW, "value" could be two or more different values: one value when
testing, and *another* value in "do something with value".

This is why we have "ACCESS_ONCE()".

Whether atomics guarantee ACCESS_ONCE() semantics or not is not
entirely clear. But afaik, there is no way to tell gcc "access at
*most* once, and never ever reload".

                             Linus

^ permalink raw reply

* Hello
From: lisa hedstrand @ 2011-10-28 11:24 UTC (permalink / raw)


My name is Miss Lisa Please accept my apology if my mode of contacting you will in any way offend you. I am compelled to contact you via this medium because i needed a friend from that part of the world. We will get to know each other in details if my proposition accepted. l am a student in UK but originally from USA.

^ permalink raw reply

* Re: [net-next PATCH] net: allow vlan traffic to be received under bond
From: Eric Dumazet @ 2011-10-28 11:06 UTC (permalink / raw)
  To: David Miller
  Cc: jesse, john.r.fastabend, hans.schillstrom, jpirko, mbizon, netdev,
	fubar
In-Reply-To: <1319796053.23112.92.camel@edumazet-laptop>

Le vendredi 28 octobre 2011 à 12:00 +0200, Eric Dumazet a écrit :

> Oh well, this broke my setup, a very basic one.
> 
> eth1 and eth2 on a bonding device, bond0, active-backup
> 
> some vlans on top of bond0, say vlan.103
> 
> $ ip link show dev vlan.103
> 8: vlan.103@bond0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc
> pfifo_fast state UP qlen 100
>     link/ether 00:1e:0b:ec:d3:d2 brd ff:ff:ff:ff:ff:ff
> 
> 
> arp_rcv() now gets packets with skb->type PACKET_OTHERHOST and drops
> such packets.
> 
>      [000] 52870.115435: skb_gro_reset_offset <-napi_gro_receive
>      [000] 52870.115435: dev_gro_receive <-napi_gro_receive
>      [000] 52870.115435: napi_skb_finish <-napi_gro_receive
>      [000] 52870.115435: netif_receive_skb <-napi_skb_finish
>      [000] 52870.115435: get_rps_cpu <-netif_receive_skb
>      [000] 52870.115435: __netif_receive_skb <-netif_receive_skb
>      [000] 52870.115436: vlan_do_receive <-__netif_receive_skb
>      [000] 52870.115436: bond_handle_frame <-__netif_receive_skb
>      [000] 52870.115436: vlan_do_receive <-__netif_receive_skb
>      [000] 52870.115436: arp_rcv <-__netif_receive_skb
>      [000] 52870.115436: kfree_skb <-arp_rcv
>      [000] 52870.115437: __kfree_skb <-kfree_skb
>      [000] 52870.115437: skb_release_head_state <-__kfree_skb
>      [000] 52870.115437: skb_release_data <-__kfree_skb
>      [000] 52870.115437: kfree <-skb_release_data
>      [000] 52870.115437: kmem_cache_free <-__kfree_skb
> 
> 
> By the way, we have no SNMP counter here so I spent some time to track
> this. I'll send a patch for this.
> 
> If this host initiates the trafic, all is well.
> 
> Please guys, can we get back ARP or revert this patch ?

Following patch cures the problem, I am not sure its the right fix.

Problem is we dont know how many times vlan_do_receive() can be called
for a packet.

Only last call should set/mess pkt_type to PACKET_OTHERHOST.

So the caller should be responsible for this, not vlan_do_receive()


Alternative would be to check skb->dev->rx_handler being NULL,
but its not clean.

Following patch is a hack because it handles multicast/broadcast trafic
only. Unicast is already handled in lines 26-33, this is why we didnt
catch the problem.

diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index f1f2f7b..6861899 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -13,7 +13,7 @@ bool vlan_do_receive(struct sk_buff **skbp)
 
 	vlan_dev = vlan_find_dev(skb->dev, vlan_id);
 	if (!vlan_dev) {
-		if (vlan_id)
+		if (vlan_id && skb->pkt_type == PACKET_HOST)
 			skb->pkt_type = PACKET_OTHERHOST;
 		return false;
 	}

^ permalink raw reply related


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