Linux userland API discussions
 help / color / mirror / Atom feed
* Re: [PATCH 1/2] xen: Implement ioctl to restrict privcmd to a specific domain
From: Frediano Ziglio @ 2014-07-31 14:43 UTC (permalink / raw)
  To: David Vrabel
  Cc: xen-devel, Boris Ostrovsky, Ian Campbell, linux-kernel, linux-api
In-Reply-To: <E1XCr4q-0007Nh-3J@lists.xen.org>

On Thu, 2014-07-31 at 15:11 +0100, David Vrabel wrote:
> On 31/07/14 14:53, Ian Campbell wrote:
> > On Thu, 2014-07-31 at 14:16 +0100, Frediano Ziglio wrote:
> > 
> >>  include/xen/interface/domctl.h     | 1090 ++++++++++++++++++++++++++++++++++++
> > 
> > domctl is an stable toolstack only hypervisor interface, so the kernel
> > cannot use it because it would then break.
> 
> Ok.  I guess we'll have to resurrect the idea to do something with XSM.
> 
> David
> 

The code just require that:
- sizeof(struct xen_domctl) does not increase;
- position and size of cmd, domain and interface_version does not
change;
- XEN_DOMCTL_createdomain is 1.

For safety there is a check on interface_version.

Frediano

^ permalink raw reply

* Re: [PATCH 1/2] xen: Implement ioctl to restrict privcmd to a specific domain
From: Ian Campbell @ 2014-07-31 14:58 UTC (permalink / raw)
  To: Frediano Ziglio
  Cc: xen-devel, Boris Ostrovsky, David Vrabel, linux-kernel, linux-api
In-Reply-To: <1406817823.6753.4.camel@hamster.uk.xensource.com>

On Thu, 2014-07-31 at 15:43 +0100, Frediano Ziglio wrote:
> The code just require that:
> - sizeof(struct xen_domctl) does not increase;
> - position and size of cmd, domain and interface_version does not
> change;
> - XEN_DOMCTL_createdomain is 1.

This is not a stable interface, so you cannot actually rely on any of
those.

For the first one in particular its not that hard to imagine someone
needing a larger subop struct at some point.

Ian.

^ permalink raw reply

* Re: [Xen-devel] [PATCH 1/2] xen: Implement ioctl to restrict privcmd to a specific domain
From: George Dunlap @ 2014-07-31 17:49 UTC (permalink / raw)
  To: David Vrabel
  Cc: Ian Campbell, Frediano Ziglio, xen-devel, Boris Ostrovsky,
	linux-api-u79uwXL29TY76Z2rM5mHXA, linux-kernel
In-Reply-To: <E1XCr4p-0007Nh-Qu-GuqFBffKawuEi8DpZVb4nw@public.gmane.org>

On Thu, Jul 31, 2014 at 10:11 AM, David Vrabel <david.vrabel-Sxgqhf6Nn4DQT0dZR+AlfA@public.gmane.org> wrote:
> On 31/07/14 14:53, Ian Campbell wrote:
>> On Thu, 2014-07-31 at 14:16 +0100, Frediano Ziglio wrote:
>>
>>>  include/xen/interface/domctl.h     | 1090 ++++++++++++++++++++++++++++++++++++
>>
>> domctl is an stable toolstack only hypervisor interface, so the kernel
>> cannot use it because it would then break.
>
> Ok.  I guess we'll have to resurrect the idea to do something with XSM.

What kind of thing did you have in mind for XSM?

In general it seems like allowing a vcpu to switch into an XSM label
(not sure I've got the terminology right here) when it context
switches into a particular process might be the most flexible way for
that to work.

But would that actually be easier than implementing stub domains?

 -George

^ permalink raw reply

* Re: [Xen-devel] [PATCH 1/2] xen: Implement ioctl to restrict privcmd to a specific domain
From: David Vrabel @ 2014-07-31 17:58 UTC (permalink / raw)
  To: George Dunlap
  Cc: Ian Campbell, Frediano Ziglio, xen-devel, Boris Ostrovsky,
	linux-api-u79uwXL29TY76Z2rM5mHXA, linux-kernel
In-Reply-To: <CAFLBxZYnaeEGTbuU5QoKJOU62Ck9p_B53bjAd46Z7uVgOxXH8g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On 31/07/14 18:49, George Dunlap wrote:
> On Thu, Jul 31, 2014 at 10:11 AM, David Vrabel <david.vrabel-Sxgqhf6Nn4DQT0dZR+AlfA@public.gmane.org> wrote:
>> On 31/07/14 14:53, Ian Campbell wrote:
>>> On Thu, 2014-07-31 at 14:16 +0100, Frediano Ziglio wrote:
>>>
>>>>  include/xen/interface/domctl.h     | 1090 ++++++++++++++++++++++++++++++++++++
>>>
>>> domctl is an stable toolstack only hypervisor interface, so the kernel
>>> cannot use it because it would then break.
>>
>> Ok.  I guess we'll have to resurrect the idea to do something with XSM.
> 
> What kind of thing did you have in mind for XSM?

A multicall-like hypercall that has an additional parameter for a handle
to a XSM context to use for the contained hypercalls.

> In general it seems like allowing a vcpu to switch into an XSM label
> (not sure I've got the terminology right here) when it context
> switches into a particular process might be the most flexible way for
> that to work.

I think we want something than can a different policy on a per-fd basis.

David

^ permalink raw reply

* Re: [PATCH 2/5] sched: new clone flag CLONE_NEWCGROUP for cgroup namespace
From: Aditya Kali @ 2014-07-31 19:48 UTC (permalink / raw)
  To: Serge Hallyn
  Cc: Tejun Heo, Li Zefan, cgroups-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux API,
	Ingo Molnar, Linux Containers
In-Reply-To: <20140724170119.GR26600@ubuntumail>

On Thu, Jul 24, 2014 at 10:01 AM, Serge Hallyn <serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA@public.gmane.org> wrote:
> Quoting Aditya Kali (adityakali-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org):
>> CLONE_NEWCGROUP will be used to create new cgroup namespace.
>>
>
> This is fine and I'm not looking to bikeshed, but am wondering - did
> you consider any other ways beside unshare (i.e. a new mount option
> to cgroupfs)?  If so, do you have a list of the downsides of those?
> (I mainly ask bc clone flags are still a scarce commodity)
>

I did consider couple of other ways:

(1) having a cgroup.ns_root (or something) cgroup file. If this value
is '1', it would mean that all processes it and its descendant cgroups
will have their cgroup paths in /proc/self/cgroup terminated at this
cgroup.
 For ex:
[A] --> [B] --> C
    | --> [D] --> E

[A], [B] and [D] has cgroup.ns_root = 1.
* all processes in cgroup C & E will see their cgroup path as /C and
/E respectively
* all processes in cgroup B & D will see their own cgroup path as /

In this model, its easy to know what to show if process is looking at
its own cgroup paths (/proc/self/cgroup). It gets tricky when you are
looking at other process's /proc/<pid>/cgroup. We may be able to come
up with some hacky way read correct value, but depending on the
cgroupfs mount, it may not make sense.
One other major drawback of this approach is that "every" process in
the cgroup will now get a restricted view. i.e., you cannot change
cgroups without affecting your view. And this is undesirable for
administrative processes.

(2) Another idea that I didn't pursue further (and is a bit hacky as
above) was having cgroup.ns_procs (like cgroup.procs, but all the pids
in cgroup.ns_procs will have their /proc/self/cgroup restricted).
Writing a pid to cgroup.ns_procs implies that you are writing it to
cgroup.procs too. But, not vise-versa. So, you could move yourself in
another cgroup by writing your pid in cgroup.procs, but not in
cgroup.ns_procs, thus preventing from getting "rooted". I This was to
solve administrative process issue in the above appraoch. But I think
this is very clunky too and I find semantics for this approach to be
non-intuitive. It almost looks like moving towards a separate "ns"
subsystem. But as we already know, its a path to failure.

I didn't think of using a mount option. I imagine the mount option
(something like -o root=/bathjobs/container_1) could be used to
restrict the visibility of cgroupfs inside the container's mount
namespace. i.e., the value you read from /proc/<pid>/cgroup now
depends on what mount namespace you are in. Its similar to cgroup
namespace, but just that the cgroupns_root is now stored in the
'struct mnt_namespace' instead of a separate 'struct
cgroup_namespace'. But, since mount namespace on creation inherits
mounts from its parent, the first cgroupfs mount in a mount namespace
is now treated specially. Also, its not possible to restrict cgroups
without mount namespace now. This is interesting and may not be too
bad. I am willing to give this a try. But I feel the cgroup namespace
approach fits well in-line with other namespaces where it does one
thing - virtualize the view of /proc/<pid>/cgroup file for processes
inside the namespace. The semantics are more intuitive as they are
similar to other namespaces.

Thanks,

>> Signed-off-by: Aditya Kali <adityakali-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
>
> Acked-by: Serge E. Hallyn <serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA@public.gmane.org>
>
>> ---
>>  include/uapi/linux/sched.h | 3 +--
>>  1 file changed, 1 insertion(+), 2 deletions(-)
>>
>> diff --git a/include/uapi/linux/sched.h b/include/uapi/linux/sched.h
>> index 34f9d73..2f90d00 100644
>> --- a/include/uapi/linux/sched.h
>> +++ b/include/uapi/linux/sched.h
>> @@ -21,8 +21,7 @@
>>  #define CLONE_DETACHED               0x00400000      /* Unused, ignored */
>>  #define CLONE_UNTRACED               0x00800000      /* set if the tracing process can't force CLONE_PTRACE on this clone */
>>  #define CLONE_CHILD_SETTID   0x01000000      /* set the TID in the child */
>> -/* 0x02000000 was previously the unused CLONE_STOPPED (Start in stopped state)
>> -   and is now available for re-use. */
>> +#define CLONE_NEWCGROUP              0x02000000      /* New cgroup namespace */
>>  #define CLONE_NEWUTS         0x04000000      /* New utsname group? */
>>  #define CLONE_NEWIPC         0x08000000      /* New ipcs */
>>  #define CLONE_NEWUSER                0x10000000      /* New user namespace */
>> --
>> 2.0.0.526.g5318336
>>
>> _______________________________________________
>> Containers mailing list
>> Containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
>> https://lists.linuxfoundation.org/mailman/listinfo/containers



-- 
Aditya

^ permalink raw reply

* [PATCH 1/5] Add __designated_init, wrapping __attribute__((designated_init))
From: Josh Triplett @ 2014-07-31 23:47 UTC (permalink / raw)
  To: akpm, J. Bruce Fields, Alexander Viro, Christopher Li,
	Ingo Molnar, Jeff Layton, Michal Marek, Neil Brown,
	Steven Rostedt, linux-api, linux-fsdevel, linux-kbuild,
	linux-kernel, linux-raid, linux-sparse

GCC 4.10 and newer, and Sparse, supports
__attribute__((designated_init)), which marks a structure as requiring
a designated initializer rather than a positional one.  This helps
reduce churn and errors when used with _ops structures and similar
structures designed for future extension.

Add a wrapper __designated_init, which turns into
__attribute__((designated_init)) for Sparse or sufficiently new GCC.
Enable the corresponding warning as an error.

The following semantic patch can help mark structures containing
function pointers as requiring designated initializers:

@@
identifier I, f;
type T;
@@

struct I {
	...
	T (*f)(...);
	...
}
+ __designated_init
;

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
---
 Makefile                      | 3 +++
 include/linux/compiler-gcc4.h | 4 ++++
 include/linux/compiler.h      | 5 +++++
 3 files changed, 12 insertions(+)

diff --git a/Makefile b/Makefile
index f6a7794..83773c2 100644
--- a/Makefile
+++ b/Makefile
@@ -744,6 +744,9 @@ KBUILD_CFLAGS   += $(call cc-option,-Werror=strict-prototypes)
 # Prohibit date/time macros, which would make the build non-deterministic
 KBUILD_CFLAGS   += $(call cc-option,-Werror=date-time)
 
+# Disallow positional initialization of designated structs
+KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init)
+
 # use the deterministic mode of AR if available
 KBUILD_ARFLAGS := $(call ar-option,D)
 
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index 2507fd2..5cd3c26 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -85,4 +85,8 @@
 #if GCC_VERSION >= 40800 || (defined(__powerpc__) && GCC_VERSION >= 40600)
 #define __HAVE_BUILTIN_BSWAP16__
 #endif
+
+#if GCC_VERSION >= 41000 || defined(__CHECKER__)
+#define __designated_init __attribute__((designated_init))
+#endif
 #endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index d5ad7b1..c2334b2 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -266,6 +266,11 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
 #define __always_inline inline
 #endif
 
+/* Marks a struct as requiring designated initializers, never positional. */
+#ifndef __designated_init
+#define __designated_init
+#endif
+
 #endif /* __KERNEL__ */
 
 /*
-- 
2.0.1


^ permalink raw reply related

* [PATCH 2/5] raid: Require designated initialization of structures
From: Josh Triplett @ 2014-07-31 23:47 UTC (permalink / raw)
  To: akpm, J. Bruce Fields, Alexander Viro, Christopher Li,
	Ingo Molnar, Jeff Layton, Michal Marek, Neil Brown,
	Steven Rostedt, linux-api, linux-fsdevel, linux-kbuild,
	linux-kernel, linux-raid, linux-sparse
In-Reply-To: <3130b0553b15518e3bef6d14c80280beed0f5ff9.1406850006.git.josh@joshtriplett.org>

Mark raid6_calls and other structures containing function pointers with
__designated_init.  Fix implementations in lib/raid6/ to use designated
initializers; this also simplifies those initializers using the default
initialization of fields to 0.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
---
 include/linux/raid/pq.h    |  4 ++--
 include/linux/raid/xor.h   |  2 +-
 include/linux/raid_class.h |  2 +-
 lib/raid6/altivec.uc       |  7 +++----
 lib/raid6/avx2.c           | 24 ++++++++++++------------
 lib/raid6/int.uc           |  6 ++----
 lib/raid6/mmx.c            | 14 ++++++--------
 lib/raid6/neon.c           |  7 +++----
 lib/raid6/sse1.c           | 16 ++++++++--------
 lib/raid6/sse2.c           | 24 ++++++++++++------------
 lib/raid6/tilegx.uc        |  6 ++----
 11 files changed, 52 insertions(+), 60 deletions(-)

diff --git a/include/linux/raid/pq.h b/include/linux/raid/pq.h
index 73069cb..2147bff 100644
--- a/include/linux/raid/pq.h
+++ b/include/linux/raid/pq.h
@@ -75,7 +75,7 @@ struct raid6_calls {
 	int  (*valid)(void);	/* Returns 1 if this routine set is usable */
 	const char *name;	/* Name of this routine set */
 	int prefer;		/* Has special performance attribute */
-};
+} __designated_init;
 
 /* Selected algorithm */
 extern struct raid6_calls raid6_call;
@@ -109,7 +109,7 @@ struct raid6_recov_calls {
 	int  (*valid)(void);
 	const char *name;
 	int priority;
-};
+} __designated_init;
 
 extern const struct raid6_recov_calls raid6_recov_intx1;
 extern const struct raid6_recov_calls raid6_recov_ssse3;
diff --git a/include/linux/raid/xor.h b/include/linux/raid/xor.h
index 5a21095..c7df59f 100644
--- a/include/linux/raid/xor.h
+++ b/include/linux/raid/xor.h
@@ -17,6 +17,6 @@ struct xor_block_template {
 		     unsigned long *, unsigned long *);
 	void (*do_5)(unsigned long, unsigned long *, unsigned long *,
 		     unsigned long *, unsigned long *, unsigned long *);
-};
+} __designated_init;
 
 #endif
diff --git a/include/linux/raid_class.h b/include/linux/raid_class.h
index 31e1ff6..603af94 100644
--- a/include/linux/raid_class.h
+++ b/include/linux/raid_class.h
@@ -16,7 +16,7 @@ struct raid_function_template {
 	int (*is_raid)(struct device *);
 	void (*get_resync)(struct device *);
 	void (*get_state)(struct device *);
-};
+} __designated_init;
 
 enum raid_state {
 	RAID_STATE_UNKNOWN = 0,
diff --git a/lib/raid6/altivec.uc b/lib/raid6/altivec.uc
index 7cc12b5..4ff138c 100644
--- a/lib/raid6/altivec.uc
+++ b/lib/raid6/altivec.uc
@@ -118,10 +118,9 @@ int raid6_have_altivec(void)
 #endif
 
 const struct raid6_calls raid6_altivec$# = {
-	raid6_altivec$#_gen_syndrome,
-	raid6_have_altivec,
-	"altivecx$#",
-	0
+	.gen_syndrome = raid6_altivec$#_gen_syndrome,
+	.valid = raid6_have_altivec,
+	.name = "altivecx$#",
 };
 
 #endif /* CONFIG_ALTIVEC */
diff --git a/lib/raid6/avx2.c b/lib/raid6/avx2.c
index bc3b1dd..e56fa06 100644
--- a/lib/raid6/avx2.c
+++ b/lib/raid6/avx2.c
@@ -88,10 +88,10 @@ static void raid6_avx21_gen_syndrome(int disks, size_t bytes, void **ptrs)
 }
 
 const struct raid6_calls raid6_avx2x1 = {
-	raid6_avx21_gen_syndrome,
-	raid6_have_avx2,
-	"avx2x1",
-	1			/* Has cache hints */
+	.gen_syndrome = raid6_avx21_gen_syndrome,
+	.valid = raid6_have_avx2,
+	.name = "avx2x1",
+	.prefer = 1,		/* Has cache hints */
 };
 
 /*
@@ -149,10 +149,10 @@ static void raid6_avx22_gen_syndrome(int disks, size_t bytes, void **ptrs)
 }
 
 const struct raid6_calls raid6_avx2x2 = {
-	raid6_avx22_gen_syndrome,
-	raid6_have_avx2,
-	"avx2x2",
-	1			/* Has cache hints */
+	.gen_syndrome = raid6_avx22_gen_syndrome,
+	.valid = raid6_have_avx2,
+	.name = "avx2x2",
+	.prefer = 1,		/* Has cache hints */
 };
 
 #ifdef CONFIG_X86_64
@@ -241,10 +241,10 @@ static void raid6_avx24_gen_syndrome(int disks, size_t bytes, void **ptrs)
 }
 
 const struct raid6_calls raid6_avx2x4 = {
-	raid6_avx24_gen_syndrome,
-	raid6_have_avx2,
-	"avx2x4",
-	1			/* Has cache hints */
+	.gen_syndrome = raid6_avx24_gen_syndrome,
+	.valid = raid6_have_avx2,
+	.name = "avx2x4",
+	.prefer = 1,		/* Has cache hints */
 };
 #endif
 
diff --git a/lib/raid6/int.uc b/lib/raid6/int.uc
index 5b50f8d..35ad01a 100644
--- a/lib/raid6/int.uc
+++ b/lib/raid6/int.uc
@@ -108,10 +108,8 @@ static void raid6_int$#_gen_syndrome(int disks, size_t bytes, void **ptrs)
 }
 
 const struct raid6_calls raid6_intx$# = {
-	raid6_int$#_gen_syndrome,
-	NULL,		/* always valid */
-	"int" NSTRING "x$#",
-	0
+	.gen_syndrome = raid6_int$#_gen_syndrome,
+	.name = "int" NSTRING "x$#",
 };
 
 #endif
diff --git a/lib/raid6/mmx.c b/lib/raid6/mmx.c
index 590c71c..cdd7d02 100644
--- a/lib/raid6/mmx.c
+++ b/lib/raid6/mmx.c
@@ -75,10 +75,9 @@ static void raid6_mmx1_gen_syndrome(int disks, size_t bytes, void **ptrs)
 }
 
 const struct raid6_calls raid6_mmxx1 = {
-	raid6_mmx1_gen_syndrome,
-	raid6_have_mmx,
-	"mmxx1",
-	0
+	.gen_syndrome = raid6_mmx1_gen_syndrome,
+	.valid = raid6_have_mmx,
+	.name = "mmxx1",
 };
 
 /*
@@ -133,10 +132,9 @@ static void raid6_mmx2_gen_syndrome(int disks, size_t bytes, void **ptrs)
 }
 
 const struct raid6_calls raid6_mmxx2 = {
-	raid6_mmx2_gen_syndrome,
-	raid6_have_mmx,
-	"mmxx2",
-	0
+	.gen_syndrome = raid6_mmx2_gen_syndrome,
+	.valid = raid6_have_mmx,
+	.name = "mmxx2",
 };
 
 #endif
diff --git a/lib/raid6/neon.c b/lib/raid6/neon.c
index 36ad470..99100dd 100644
--- a/lib/raid6/neon.c
+++ b/lib/raid6/neon.c
@@ -41,10 +41,9 @@
 		kernel_neon_end();					\
 	}								\
 	struct raid6_calls const raid6_neonx ## _n = {			\
-		raid6_neon ## _n ## _gen_syndrome,			\
-		raid6_have_neon,					\
-		"neonx" #_n,						\
-		0							\
+		.gen_syndrome = raid6_neon ## _n ## _gen_syndrome,	\
+		.valid = raid6_have_neon,				\
+		.name = "neonx" #_n,					\
 	}
 
 static int raid6_have_neon(void)
diff --git a/lib/raid6/sse1.c b/lib/raid6/sse1.c
index f762971..a9de46e 100644
--- a/lib/raid6/sse1.c
+++ b/lib/raid6/sse1.c
@@ -91,10 +91,10 @@ static void raid6_sse11_gen_syndrome(int disks, size_t bytes, void **ptrs)
 }
 
 const struct raid6_calls raid6_sse1x1 = {
-	raid6_sse11_gen_syndrome,
-	raid6_have_sse1_or_mmxext,
-	"sse1x1",
-	1			/* Has cache hints */
+	.gen_syndrome = raid6_sse11_gen_syndrome,
+	.valid = raid6_have_sse1_or_mmxext,
+	.name = "sse1x1",
+	.prefer = 1,		/* Has cache hints */
 };
 
 /*
@@ -153,10 +153,10 @@ static void raid6_sse12_gen_syndrome(int disks, size_t bytes, void **ptrs)
 }
 
 const struct raid6_calls raid6_sse1x2 = {
-	raid6_sse12_gen_syndrome,
-	raid6_have_sse1_or_mmxext,
-	"sse1x2",
-	1			/* Has cache hints */
+	.gen_syndrome = raid6_sse12_gen_syndrome,
+	.valid = raid6_have_sse1_or_mmxext,
+	.name = "sse1x2",
+	.prefer = 1,		/* Has cache hints */
 };
 
 #endif
diff --git a/lib/raid6/sse2.c b/lib/raid6/sse2.c
index 85b82c8..cd262518aa 100644
--- a/lib/raid6/sse2.c
+++ b/lib/raid6/sse2.c
@@ -89,10 +89,10 @@ static void raid6_sse21_gen_syndrome(int disks, size_t bytes, void **ptrs)
 }
 
 const struct raid6_calls raid6_sse2x1 = {
-	raid6_sse21_gen_syndrome,
-	raid6_have_sse2,
-	"sse2x1",
-	1			/* Has cache hints */
+	.gen_syndrome = raid6_sse21_gen_syndrome,
+	.valid = raid6_have_sse2,
+	.name = "sse2x1",
+	.prefer = 1,		/* Has cache hints */
 };
 
 /*
@@ -151,10 +151,10 @@ static void raid6_sse22_gen_syndrome(int disks, size_t bytes, void **ptrs)
 }
 
 const struct raid6_calls raid6_sse2x2 = {
-	raid6_sse22_gen_syndrome,
-	raid6_have_sse2,
-	"sse2x2",
-	1			/* Has cache hints */
+	.gen_syndrome = raid6_sse22_gen_syndrome,
+	.valid = raid6_have_sse2,
+	.name = "sse2x2",
+	.prefer = 1,		/* Has cache hints */
 };
 
 #ifdef CONFIG_X86_64
@@ -249,10 +249,10 @@ static void raid6_sse24_gen_syndrome(int disks, size_t bytes, void **ptrs)
 }
 
 const struct raid6_calls raid6_sse2x4 = {
-	raid6_sse24_gen_syndrome,
-	raid6_have_sse2,
-	"sse2x4",
-	1			/* Has cache hints */
+	.gen_syndrome = raid6_sse24_gen_syndrome,
+	.valid = raid6_have_sse2,
+	.name = "sse2x4",
+	.prefer = 1,		/* Has cache hints */
 };
 
 #endif /* CONFIG_X86_64 */
diff --git a/lib/raid6/tilegx.uc b/lib/raid6/tilegx.uc
index e7c2945..3077722 100644
--- a/lib/raid6/tilegx.uc
+++ b/lib/raid6/tilegx.uc
@@ -79,8 +79,6 @@ void raid6_tilegx$#_gen_syndrome(int disks, size_t bytes, void **ptrs)
 }
 
 const struct raid6_calls raid6_tilegx$# = {
-	raid6_tilegx$#_gen_syndrome,
-	NULL,
-	"tilegx$#",
-	0
+	.gen_syndrome = raid6_tilegx$#_gen_syndrome,
+	.name = "tilegx$#",
 };
-- 
2.0.1


^ permalink raw reply related

* [PATCH 3/5] fs: Require designated initialization of structures
From: Josh Triplett @ 2014-07-31 23:47 UTC (permalink / raw)
  To: akpm, J. Bruce Fields, Alexander Viro, Christopher Li,
	Ingo Molnar, Jeff Layton, Michal Marek, Neil Brown,
	Steven Rostedt, linux-api, linux-fsdevel, linux-kbuild,
	linux-kernel, linux-raid, linux-sparse
In-Reply-To: <3130b0553b15518e3bef6d14c80280beed0f5ff9.1406850006.git.josh@joshtriplett.org>

Mark various filesystem structures with __designated_init.  Fix the one
and only instance of positional initialization of those structures.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
---
 fs/ioctl.c         |  2 +-
 include/linux/fs.h | 45 +++++++++++++++++++++++----------------------
 2 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/fs/ioctl.c b/fs/ioctl.c
index 8ac3fad..2151968 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -174,7 +174,7 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg)
 {
 	struct fiemap fiemap;
 	struct fiemap __user *ufiemap = (struct fiemap __user *) arg;
-	struct fiemap_extent_info fieinfo = { 0, };
+	struct fiemap_extent_info fieinfo = { };
 	struct inode *inode = file_inode(filp);
 	struct super_block *sb = inode->i_sb;
 	u64 len;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e11d60c..cec614b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -366,7 +366,7 @@ struct address_space_operations {
 	int (*swap_activate)(struct swap_info_struct *sis, struct file *file,
 				sector_t *span);
 	void (*swap_deactivate)(struct file *file);
-};
+} __designated_init;
 
 extern const struct address_space_operations empty_aops;
 
@@ -401,7 +401,7 @@ struct address_space {
 	spinlock_t		private_lock;	/* for use by the address_space */
 	struct list_head	private_list;	/* ditto */
 	void			*private_data;	/* ditto */
-} __attribute__((aligned(sizeof(long))));
+} __designated_init __attribute__((aligned(sizeof(long))));
 	/*
 	 * On most architectures that alignment is already the case; but
 	 * must be enforced here for CRIS, to let the least significant bit
@@ -444,7 +444,7 @@ struct block_device {
 	int			bd_fsfreeze_count;
 	/* Mutex for freeze */
 	struct mutex		bd_fsfreeze_mutex;
-};
+} __designated_init;
 
 /*
  * Radix-tree tags, for tagging dirty and writeback pages within the pagecache
@@ -588,7 +588,7 @@ struct inode {
 #endif
 
 	void			*i_private; /* fs or device private pointer */
-};
+} __designated_init;
 
 static inline int inode_unhashed(struct inode *inode)
 {
@@ -719,7 +719,7 @@ struct fown_struct {
 	enum pid_type pid_type;	/* Kind of process group SIGIO should be sent to */
 	kuid_t uid, euid;	/* uid/euid of process setting the owner */
 	int signum;		/* posix.1b rt signal to be delivered on IO */
-};
+} __designated_init;
 
 /*
  * Track a single file's readahead state
@@ -733,7 +733,7 @@ struct file_ra_state {
 	unsigned int ra_pages;		/* Maximum readahead window */
 	unsigned int mmap_miss;		/* Cache miss stat for mmap accesses */
 	loff_t prev_pos;		/* Cache last read() position */
-};
+} __designated_init;
 
 /*
  * Check if @index falls in the readahead windows.
@@ -781,14 +781,15 @@ struct file {
 	struct list_head	f_tfile_llink;
 #endif /* #ifdef CONFIG_EPOLL */
 	struct address_space	*f_mapping;
-} __attribute__((aligned(4)));	/* lest something weird decides that 2 is OK */
+} __designated_init __attribute__((aligned(4)));
+/* lest something weird decides that 2 is OK */
 
 struct file_handle {
 	__u32 handle_bytes;
 	int handle_type;
 	/* file identifier */
 	unsigned char f_handle[0];
-};
+} __designated_init;
 
 static inline struct file *get_file(struct file *f)
 {
@@ -838,7 +839,7 @@ typedef struct files_struct *fl_owner_t;
 struct file_lock_operations {
 	void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
 	void (*fl_release_private)(struct file_lock *);
-};
+} __designated_init;
 
 struct lock_manager_operations {
 	int (*lm_compare_owner)(struct file_lock *, struct file_lock *);
@@ -847,7 +848,7 @@ struct lock_manager_operations {
 	int (*lm_grant)(struct file_lock *, struct file_lock *, int);
 	void (*lm_break)(struct file_lock *);
 	int (*lm_change)(struct file_lock **, int);
-};
+} __designated_init;
 
 struct lock_manager {
 	struct list_head list;
@@ -909,7 +910,7 @@ struct file_lock {
 			int state;		/* state of grant or error if -ve */
 		} afs;
 	} fl_u;
-};
+} __designated_init;
 
 /* The following constant reflects the upper bound of the file/locking space */
 #ifndef OFFSET_MAX
@@ -1112,7 +1113,7 @@ struct fasync_struct {
 	struct fasync_struct	*fa_next; /* singly linked list */
 	struct file		*fa_file;
 	struct rcu_head		fa_rcu;
-};
+} __designated_init;
 
 #define FASYNC_MAGIC 0x4601
 
@@ -1170,7 +1171,7 @@ struct sb_writers {
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 	struct lockdep_map	lock_map[SB_FREEZE_LEVELS];
 #endif
-};
+} __designated_init;
 
 struct super_block {
 	struct list_head	s_list;		/* Keep this first */
@@ -1258,7 +1259,7 @@ struct super_block {
 	struct list_lru		s_dentry_lru ____cacheline_aligned_in_smp;
 	struct list_lru		s_inode_lru ____cacheline_aligned_in_smp;
 	struct rcu_head		rcu;
-};
+} __designated_init;
 
 extern struct timespec current_fs_time(struct super_block *sb);
 
@@ -1410,7 +1411,7 @@ struct fiemap_extent_info {
 	unsigned int fi_extents_max;	/* Size of fiemap_extent array */
 	struct fiemap_extent __user *fi_extents_start; /* Start of
 							fiemap_extent array */
-};
+} __designated_init;
 int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical,
 			    u64 phys, u64 len, u32 flags);
 int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
@@ -1441,7 +1442,7 @@ typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
 struct dir_context {
 	const filldir_t actor;
 	loff_t pos;
-};
+} __designated_init;
 
 struct block_device_operations;
 
@@ -1484,7 +1485,7 @@ struct file_operations {
 	long (*fallocate)(struct file *file, int mode, loff_t offset,
 			  loff_t len);
 	int (*show_fdinfo)(struct seq_file *m, struct file *f);
-};
+} __designated_init;
 
 struct inode_operations {
 	struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
@@ -1520,7 +1521,7 @@ struct inode_operations {
 			   umode_t create_mode, int *opened);
 	int (*tmpfile) (struct inode *, struct dentry *, umode_t);
 	int (*set_acl)(struct inode *, struct posix_acl *, int);
-} ____cacheline_aligned;
+} __designated_init ____cacheline_aligned;
 
 ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
 			      unsigned long nr_segs, unsigned long fast_segs,
@@ -1561,7 +1562,7 @@ struct super_operations {
 	int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
 	long (*nr_cached_objects)(struct super_block *, int);
 	long (*free_cached_objects)(struct super_block *, long, int);
-};
+} __designated_init;
 
 /*
  * Inode flags - they have no relation to superblock flags now
@@ -1771,7 +1772,7 @@ struct file_system_type {
 	struct lock_class_key i_lock_key;
 	struct lock_class_key i_mutex_key;
 	struct lock_class_key i_mutex_dir_key;
-};
+} __designated_init;
 
 #define MODULE_ALIAS_FS(NAME) MODULE_ALIAS("fs-" NAME)
 
@@ -2018,7 +2019,7 @@ struct filename {
 	const __user char	*uptr;	/* original userland pointer */
 	struct audit_names	*aname;
 	bool			separate; /* should "name" be freed? */
-};
+} __designated_init;
 
 extern long vfs_truncate(struct path *, loff_t);
 extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
@@ -2647,7 +2648,7 @@ static inline ino_t parent_ino(struct dentry *dentry)
 struct simple_transaction_argresp {
 	ssize_t size;
 	char data[0];
-};
+} __designated_init;
 
 #define SIMPLE_TRANSACTION_LIMIT (PAGE_SIZE - sizeof(struct simple_transaction_argresp))
 
-- 
2.0.1

^ permalink raw reply related

* [PATCH 4/5] ftrace: Require designated initialization of structures
From: Josh Triplett @ 2014-07-31 23:47 UTC (permalink / raw)
  To: akpm, J. Bruce Fields, Alexander Viro, Christopher Li,
	Ingo Molnar, Jeff Layton, Michal Marek, Neil Brown,
	Steven Rostedt, linux-api, linux-fsdevel, linux-kbuild,
	linux-kernel, linux-raid, linux-sparse
In-Reply-To: <3130b0553b15518e3bef6d14c80280beed0f5ff9.1406850006.git.josh@joshtriplett.org>

Mark various ftrace structures with __designated_init.  Fix some ftrace
macros to use designated initializers for those structures.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
---
 include/linux/ftrace.h       | 4 ++--
 include/linux/ftrace_event.h | 4 ++--
 include/linux/syscalls.h     | 8 ++------
 include/trace/ftrace.h       | 8 ++------
 kernel/trace/trace_export.c  | 4 +---
 5 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 404a686..cb2d023 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -260,7 +260,7 @@ struct ftrace_func_command {
 	int			(*func)(struct ftrace_hash *hash,
 					char *func, char *cmd,
 					char *params, int enable);
-};
+} __designated_init;
 
 #ifdef CONFIG_DYNAMIC_FTRACE
 
@@ -283,7 +283,7 @@ struct ftrace_probe_ops {
 					 unsigned long ip,
 					 struct ftrace_probe_ops *ops,
 					 void *data);
-};
+} __designated_init;
 
 extern int
 register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index cff3106..25af313 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -198,7 +198,7 @@ struct ftrace_event_class {
 	struct list_head	*(*get_fields)(struct ftrace_event_call *);
 	struct list_head	fields;
 	int			(*raw_init)(struct ftrace_event_call *);
-};
+} __designated_init;
 
 extern int ftrace_event_reg(struct ftrace_event_call *event,
 			    enum trace_reg type, void *data);
@@ -293,7 +293,7 @@ struct ftrace_event_call {
 	int	(*perf_perm)(struct ftrace_event_call *,
 			     struct perf_event *);
 #endif
-};
+} __designated_init;
 
 static inline const char *
 ftrace_event_name(struct ftrace_event_call *call)
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index b0881a0..3002648 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -120,9 +120,7 @@ extern struct trace_event_functions exit_syscall_print_funcs;
 	static struct ftrace_event_call __used				\
 	  event_enter_##sname = {					\
 		.class			= &event_class_syscall_enter,	\
-		{							\
-			.name                   = "sys_enter"#sname,	\
-		},							\
+		.name                   = "sys_enter"#sname,		\
 		.event.funcs            = &enter_syscall_print_funcs,	\
 		.data			= (void *)&__syscall_meta_##sname,\
 		.flags                  = TRACE_EVENT_FL_CAP_ANY,	\
@@ -136,9 +134,7 @@ extern struct trace_event_functions exit_syscall_print_funcs;
 	static struct ftrace_event_call __used				\
 	  event_exit_##sname = {					\
 		.class			= &event_class_syscall_exit,	\
-		{							\
-			.name                   = "sys_exit"#sname,	\
-		},							\
+		.name                   = "sys_exit"#sname,		\
 		.event.funcs		= &exit_syscall_print_funcs,	\
 		.data			= (void *)&__syscall_meta_##sname,\
 		.flags                  = TRACE_EVENT_FL_CAP_ANY,	\
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 26b4f2e..095aaca 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -699,9 +699,7 @@ static struct ftrace_event_class __used __refdata event_class_##call = { \
 									\
 static struct ftrace_event_call __used event_##call = {			\
 	.class			= &event_class_##template,		\
-	{								\
-		.tp			= &__tracepoint_##call,		\
-	},								\
+	.tp			= &__tracepoint_##call,			\
 	.event.funcs		= &ftrace_event_type_funcs_##template,	\
 	.print_fmt		= print_fmt_##template,			\
 	.flags			= TRACE_EVENT_FL_TRACEPOINT,		\
@@ -716,9 +714,7 @@ static const char print_fmt_##call[] = print;				\
 									\
 static struct ftrace_event_call __used event_##call = {			\
 	.class			= &event_class_##template,		\
-	{								\
-		.tp			= &__tracepoint_##call,		\
-	},								\
+	.tp			= &__tracepoint_##call,			\
 	.event.funcs		= &ftrace_event_type_funcs_##call,	\
 	.print_fmt		= print_fmt_##call,			\
 	.flags			= TRACE_EVENT_FL_TRACEPOINT,		\
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
index d4ddde2..40f472f 100644
--- a/kernel/trace/trace_export.c
+++ b/kernel/trace/trace_export.c
@@ -174,9 +174,7 @@ struct ftrace_event_class __refdata event_class_ftrace_##call = {	\
 									\
 struct ftrace_event_call __used event_##call = {			\
 	.class			= &event_class_ftrace_##call,		\
-	{								\
-		.name			= #call,			\
-	},								\
+	.name			= #call,				\
 	.event.type		= etype,				\
 	.print_fmt		= print,				\
 	.flags			= TRACE_EVENT_FL_IGNORE_ENABLE | TRACE_EVENT_FL_USE_CALL_FILTER, \
-- 
2.0.1

^ permalink raw reply related

* [PATCH 5/5] include/linux/interrupt.h: Require designated initialization of structures
From: Josh Triplett @ 2014-07-31 23:48 UTC (permalink / raw)
  To: akpm, J. Bruce Fields, Alexander Viro, Christopher Li,
	Ingo Molnar, Jeff Layton, Michal Marek, Neil Brown,
	Steven Rostedt, linux-api, linux-fsdevel, linux-kbuild,
	linux-kernel, linux-raid, linux-sparse
In-Reply-To: <3130b0553b15518e3bef6d14c80280beed0f5ff9.1406850006.git.josh@joshtriplett.org>

Fix the corresponding tasklet initialization macros to use designated
initializers, which simplifies those initializers using the default
initialization of fields to 0.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
---
 include/linux/interrupt.h | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 698ad05..559ef98 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -217,7 +217,7 @@ struct irq_affinity_notify {
 	struct work_struct work;
 	void (*notify)(struct irq_affinity_notify *, const cpumask_t *mask);
 	void (*release)(struct kref *ref);
-};
+} __designated_init;
 
 #if defined(CONFIG_SMP)
 
@@ -419,7 +419,7 @@ extern const char * const softirq_to_name[NR_SOFTIRQS];
 struct softirq_action
 {
 	void	(*action)(struct softirq_action *);
-};
+} __designated_init;
 
 asmlinkage void do_softirq(void);
 asmlinkage void __do_softirq(void);
@@ -474,14 +474,21 @@ struct tasklet_struct
 	atomic_t count;
 	void (*func)(unsigned long);
 	unsigned long data;
-};
-
-#define DECLARE_TASKLET(name, func, data) \
-struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data }
+} __designated_init;
 
-#define DECLARE_TASKLET_DISABLED(name, func, data) \
-struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(1), func, data }
+#define DECLARE_TASKLET(name, tsfunc, tsdata) \
+struct tasklet_struct name = {		\
+	.count = ATOMIC_INIT(0),	\
+	.func = tsfunc,			\
+	.data = tsdata,			\
+}
 
+#define DECLARE_TASKLET_DISABLED(name, tsfunc, tsdata) \
+struct tasklet_struct name = {		\
+	.count = ATOMIC_INIT(1),	\
+	.func = tsfunc,			\
+	.data = tsdata,			\
+}
 
 enum
 {
@@ -576,7 +583,7 @@ struct tasklet_hrtimer {
 	struct hrtimer		timer;
 	struct tasklet_struct	tasklet;
 	enum hrtimer_restart	(*function)(struct hrtimer *);
-};
+} __designated_init;
 
 extern void
 tasklet_hrtimer_init(struct tasklet_hrtimer *ttimer,
-- 
2.0.1

^ permalink raw reply related

* [REVIEW][PATCH 0/4] /proc/thread-self
From: Eric W. Biederman @ 2014-08-01  0:30 UTC (permalink / raw)
  To: Linux Containers
  Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, Michael Kerrisk (man-pages),
	linux-kernel-u79uwXL29TY76Z2rM5mHXA


This patchset implements /proc/thread-self a magic symlink that
solves a couple of problems.

- It makes it easy to get to a specific threads directory in /proc
  with gettid() not being exported in glibc this is currently a pain.

- It allows fixing the problem present in /proc/mounts and /proc/net
  that when the thread group leader exits but the entire thread group
  remains /proc/self/net and /proc/self/mounts and thus /proc/mounts and
  /proc/net become empty.

- As mount and network namespaces are per thread it allows /proc/net and
  /proc/mounts to reflect this.

This is small chance changing /proc/net and /proc/mounts will cause
userspace regressions (although nothing has shown up in my testing) if
that happens we can just point the change that moves them from
/proc/self/... to /proc/thread-self/...

Eric W. Biederman (4):
      proc: Have net show up under /proc/<tgid>/task/<tid>
      proc: Implement /proc/thread-self to point at the directory of the current thread
      proc: Point /proc/net at /proc/thread-self/net instead of /proc/self/net
      proc: Point /proc/mounts at /proc/thread-self/mounts instead of /proc/self/mounts

 fs/proc/Makefile              |  1 +
 fs/proc/base.c                | 18 ++++++---
 fs/proc/inode.c               |  7 +++-
 fs/proc/internal.h            |  6 +++
 fs/proc/proc_net.c            |  2 +-
 fs/proc/root.c                |  5 ++-
 fs/proc/thread_self.c         | 85 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/pid_namespace.h |  1 +
 8 files changed, 117 insertions(+), 8 deletions(-)

Eric

^ permalink raw reply

* [REVIEW][PATCH 1/4] proc: Have net show up under /proc/<tgid>/task/<tid>
From: Eric W. Biederman @ 2014-08-01  0:33 UTC (permalink / raw)
  To: Linux Containers
  Cc: linux-api, Michael Kerrisk (man-pages), linux-fsdevel,
	linux-kernel
In-Reply-To: <87oaw5caq1.fsf@x220.int.ebiederm.org>


Network namespaces are per task so it make sense for them to show up
in the task directory.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/proc/base.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 2d696b0c93bf..ed34e405c6b9 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2895,6 +2895,9 @@ static const struct pid_entry tid_base_stuff[] = {
 	DIR("fd",        S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
 	DIR("fdinfo",    S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations),
 	DIR("ns",	 S_IRUSR|S_IXUGO, proc_ns_dir_inode_operations, proc_ns_dir_operations),
+#ifdef CONFIG_NET
+	DIR("net",        S_IRUGO|S_IXUGO, proc_net_inode_operations, proc_net_operations),
+#endif
 	REG("environ",   S_IRUSR, proc_environ_operations),
 	INF("auxv",      S_IRUSR, proc_pid_auxv),
 	ONE("status",    S_IRUGO, proc_pid_status),
-- 
1.9.1


^ permalink raw reply related

* [REVIEW][PATCH 2/4] proc: Implement /proc/thread-self to point at the directory of the current thread
From: Eric W. Biederman @ 2014-08-01  0:34 UTC (permalink / raw)
  To: Linux Containers
  Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, Michael Kerrisk (man-pages),
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <87oaw5caq1.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>


/proc/thread-self is derived from /proc/self.  /proc/thread-self
points to the directory in proc containing information about the
current thread.

This funtionality has been missing for a long time, and is tricky to
implement in userspace as gettid() is not exported by glibc.  More
importantly this allows fixing defects in /proc/mounts and /proc/net
where in a threaded application today they wind up being empty files
when only the initial pthread has exited, causing problems for other
threads.

Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
 fs/proc/Makefile              |  1 +
 fs/proc/base.c                | 15 +++++---
 fs/proc/inode.c               |  7 +++-
 fs/proc/internal.h            |  6 +++
 fs/proc/root.c                |  3 ++
 fs/proc/thread_self.c         | 85 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/pid_namespace.h |  1 +
 7 files changed, 112 insertions(+), 6 deletions(-)
 create mode 100644 fs/proc/thread_self.c

diff --git a/fs/proc/Makefile b/fs/proc/Makefile
index 239493ec718e..7151ea428041 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -23,6 +23,7 @@ proc-y	+= version.o
 proc-y	+= softirqs.o
 proc-y	+= namespaces.o
 proc-y	+= self.o
+proc-y	+= thread_self.o
 proc-$(CONFIG_PROC_SYSCTL)	+= proc_sysctl.o
 proc-$(CONFIG_NET)		+= proc_net.o
 proc-$(CONFIG_PROC_KCORE)	+= kcore.o
diff --git a/fs/proc/base.c b/fs/proc/base.c
index ed34e405c6b9..0131156ce7c9 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2847,7 +2847,7 @@ retry:
 	return iter;
 }
 
-#define TGID_OFFSET (FIRST_PROCESS_ENTRY + 1)
+#define TGID_OFFSET (FIRST_PROCESS_ENTRY + 2)
 
 /* for the /proc/ directory itself, after non-process stuff has been done */
 int proc_pid_readdir(struct file *file, struct dir_context *ctx)
@@ -2859,14 +2859,19 @@ int proc_pid_readdir(struct file *file, struct dir_context *ctx)
 	if (pos >= PID_MAX_LIMIT + TGID_OFFSET)
 		return 0;
 
-	if (pos == TGID_OFFSET - 1) {
+	if (pos == TGID_OFFSET - 2) {
 		struct inode *inode = ns->proc_self->d_inode;
 		if (!dir_emit(ctx, "self", 4, inode->i_ino, DT_LNK))
 			return 0;
-		iter.tgid = 0;
-	} else {
-		iter.tgid = pos - TGID_OFFSET;
+		ctx->pos = pos = pos + 1;
+	}
+	if (pos == TGID_OFFSET - 1) {
+		struct inode *inode = ns->proc_thread_self->d_inode;
+		if (!dir_emit(ctx, "thread-self", 11, inode->i_ino, DT_LNK))
+			return 0;
+		ctx->pos = pos = pos + 1;
 	}
+	iter.tgid = pos - TGID_OFFSET;
 	iter.task = NULL;
 	for (iter = next_tgid(ns, iter);
 	     iter.task;
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 0adbc02d60e3..333080d7a671 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -442,6 +442,7 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
 int proc_fill_super(struct super_block *s)
 {
 	struct inode *root_inode;
+	int ret;
 
 	s->s_flags |= MS_NODIRATIME | MS_NOSUID | MS_NOEXEC;
 	s->s_blocksize = 1024;
@@ -463,5 +464,9 @@ int proc_fill_super(struct super_block *s)
 		return -ENOMEM;
 	}
 
-	return proc_setup_self(s);
+	ret = proc_setup_self(s);
+	if (ret) {
+		return ret;
+	}
+	return proc_setup_thread_self(s);
 }
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 3ab6d14e71c5..ee04619173b2 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -234,6 +234,12 @@ static inline int proc_net_init(void) { return 0; }
 extern int proc_setup_self(struct super_block *);
 
 /*
+ * proc_thread_self.c
+ */
+extern int proc_setup_thread_self(struct super_block *);
+extern void proc_thread_self_init(void);
+
+/*
  * proc_sysctl.c
  */
 #ifdef CONFIG_PROC_SYSCTL
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 5dbadecb234d..48f1c03bc7ed 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -149,6 +149,8 @@ static void proc_kill_sb(struct super_block *sb)
 	ns = (struct pid_namespace *)sb->s_fs_info;
 	if (ns->proc_self)
 		dput(ns->proc_self);
+	if (ns->proc_thread_self)
+		dput(ns->proc_thread_self);
 	kill_anon_super(sb);
 	put_pid_ns(ns);
 }
@@ -170,6 +172,7 @@ void __init proc_root_init(void)
 		return;
 
 	proc_self_init();
+	proc_thread_self_init();
 	proc_symlink("mounts", NULL, "self/mounts");
 
 	proc_net_init();
diff --git a/fs/proc/thread_self.c b/fs/proc/thread_self.c
new file mode 100644
index 000000000000..59075b509df3
--- /dev/null
+++ b/fs/proc/thread_self.c
@@ -0,0 +1,85 @@
+#include <linux/sched.h>
+#include <linux/namei.h>
+#include <linux/slab.h>
+#include <linux/pid_namespace.h>
+#include "internal.h"
+
+/*
+ * /proc/thread_self:
+ */
+static int proc_thread_self_readlink(struct dentry *dentry, char __user *buffer,
+			      int buflen)
+{
+	struct pid_namespace *ns = dentry->d_sb->s_fs_info;
+	pid_t tgid = task_tgid_nr_ns(current, ns);
+	pid_t pid = task_pid_nr_ns(current, ns);
+	char tmp[PROC_NUMBUF + 6 + PROC_NUMBUF];
+	if (!pid)
+		return -ENOENT;
+	sprintf(tmp, "%d/task/%d", tgid, pid);
+	return readlink_copy(buffer, buflen, tmp);
+}
+
+static void *proc_thread_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+	struct pid_namespace *ns = dentry->d_sb->s_fs_info;
+	pid_t tgid = task_tgid_nr_ns(current, ns);
+	pid_t pid = task_pid_nr_ns(current, ns);
+	char *name = ERR_PTR(-ENOENT);
+	if (pid) {
+		name = kmalloc(PROC_NUMBUF + 6 + PROC_NUMBUF, GFP_KERNEL);
+		if (!name)
+			name = ERR_PTR(-ENOMEM);
+		else
+			sprintf(name, "%d/task/%d", tgid, pid);
+	}
+	nd_set_link(nd, name);
+	return NULL;
+}
+
+static const struct inode_operations proc_thread_self_inode_operations = {
+	.readlink	= proc_thread_self_readlink,
+	.follow_link	= proc_thread_self_follow_link,
+	.put_link	= kfree_put_link,
+};
+
+static unsigned thread_self_inum;
+
+int proc_setup_thread_self(struct super_block *s)
+{
+	struct inode *root_inode = s->s_root->d_inode;
+	struct pid_namespace *ns = s->s_fs_info;
+	struct dentry *thread_self;
+
+	mutex_lock(&root_inode->i_mutex);
+	thread_self = d_alloc_name(s->s_root, "thread-self");
+	if (thread_self) {
+		struct inode *inode = new_inode_pseudo(s);
+		if (inode) {
+			inode->i_ino = thread_self_inum;
+			inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+			inode->i_mode = S_IFLNK | S_IRWXUGO;
+			inode->i_uid = GLOBAL_ROOT_UID;
+			inode->i_gid = GLOBAL_ROOT_GID;
+			inode->i_op = &proc_thread_self_inode_operations;
+			d_add(thread_self, inode);
+		} else {
+			dput(thread_self);
+			thread_self = ERR_PTR(-ENOMEM);
+		}
+	} else {
+		thread_self = ERR_PTR(-ENOMEM);
+	}
+	mutex_unlock(&root_inode->i_mutex);
+	if (IS_ERR(thread_self)) {
+		pr_err("proc_fill_super: can't allocate /proc/thread_self\n");
+		return PTR_ERR(thread_self);
+	}
+	ns->proc_thread_self = thread_self;
+	return 0;
+}
+
+void __init proc_thread_self_init(void)
+{
+	proc_alloc_inum(&thread_self_inum);
+}
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index 7246ef3d4455..1997ffc295a7 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -33,6 +33,7 @@ struct pid_namespace {
 #ifdef CONFIG_PROC_FS
 	struct vfsmount *proc_mnt;
 	struct dentry *proc_self;
+	struct dentry *proc_thread_self;
 #endif
 #ifdef CONFIG_BSD_PROCESS_ACCT
 	struct bsd_acct_struct *bacct;
-- 
1.9.1

^ permalink raw reply related

* [REVIEW][PATCH 3/4] proc: Point /proc/net at /proc/thread-self/net instead of /proc/self/net
From: Eric W. Biederman @ 2014-08-01  0:34 UTC (permalink / raw)
  To: Linux Containers
  Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, Michael Kerrisk (man-pages),
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <87oaw5caq1.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>


In oddball cases where the thread has a different network namespace
than the primary thread group leader or more likely in cases where
the thread remains and the thread group leader has exited this
ensures that /proc/net continues to work.

This should not cause any problems but if it does this patch can just
be reverted.

Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
 fs/proc/proc_net.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index a63af3e0a612..39481028ec08 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -226,7 +226,7 @@ static struct pernet_operations __net_initdata proc_net_ns_ops = {
 
 int __init proc_net_init(void)
 {
-	proc_symlink("net", NULL, "self/net");
+	proc_symlink("net", NULL, "thread-self/net");
 
 	return register_pernet_subsys(&proc_net_ns_ops);
 }
-- 
1.9.1

^ permalink raw reply related

* [REVIEW][PATCH 4/4] proc: Point /proc/mounts at /proc/thread-self/mounts instead of /proc/self/mounts
From: Eric W. Biederman @ 2014-08-01  0:35 UTC (permalink / raw)
  To: Linux Containers
  Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, Michael Kerrisk (man-pages),
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <87oaw5caq1.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>


In oddball cases where the thread has a different mount namespace than
the thread group leader or more likely in cases where the thread
remains and the thread group leader has exited this ensures that
/proc/mounts continues to work.

This should not cause any problems but if it does this patch can just
be reverted.

Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
 fs/proc/root.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/proc/root.c b/fs/proc/root.c
index 48f1c03bc7ed..92c12c243ce3 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -173,7 +173,7 @@ void __init proc_root_init(void)
 
 	proc_self_init();
 	proc_thread_self_init();
-	proc_symlink("mounts", NULL, "self/mounts");
+	proc_symlink("mounts", NULL, "thread-self/mounts");
 
 	proc_net_init();
 
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH 2/5] raid: Require designated initialization of structures
From: NeilBrown @ 2014-08-01  1:10 UTC (permalink / raw)
  To: Josh Triplett
  Cc: akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b, J. Bruce Fields,
	Alexander Viro, Christopher Li, Ingo Molnar, Jeff Layton,
	Michal Marek, Steven Rostedt, linux-api-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kbuild-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-raid-u79uwXL29TY76Z2rM5mHXA,
	linux-sparse-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1d468224409ef2bf46874f817d19389ac5d1b26d.1406850006.git.josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>

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

On Thu, 31 Jul 2014 16:47:35 -0700 Josh Triplett <josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>
wrote:

> Mark raid6_calls and other structures containing function pointers with
> __designated_init.  Fix implementations in lib/raid6/ to use designated
> initializers; this also simplifies those initializers using the default
> initialization of fields to 0.
> 
> Signed-off-by: Josh Triplett <josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>

Looks like an excellent idea!
Feel free to forward this upstream on my behalf, or remind me once the first
patch is in -next, and I'll take this one myself - whichever you prefer.

 Acked-by: NeilBrown <neilb-l3A5Bk7waGM@public.gmane.org>

Thanks,
NeilBrown

> ---
>  include/linux/raid/pq.h    |  4 ++--
>  include/linux/raid/xor.h   |  2 +-
>  include/linux/raid_class.h |  2 +-
>  lib/raid6/altivec.uc       |  7 +++----
>  lib/raid6/avx2.c           | 24 ++++++++++++------------
>  lib/raid6/int.uc           |  6 ++----
>  lib/raid6/mmx.c            | 14 ++++++--------
>  lib/raid6/neon.c           |  7 +++----
>  lib/raid6/sse1.c           | 16 ++++++++--------
>  lib/raid6/sse2.c           | 24 ++++++++++++------------
>  lib/raid6/tilegx.uc        |  6 ++----
>  11 files changed, 52 insertions(+), 60 deletions(-)
> 
> diff --git a/include/linux/raid/pq.h b/include/linux/raid/pq.h
> index 73069cb..2147bff 100644
> --- a/include/linux/raid/pq.h
> +++ b/include/linux/raid/pq.h
> @@ -75,7 +75,7 @@ struct raid6_calls {
>  	int  (*valid)(void);	/* Returns 1 if this routine set is usable */
>  	const char *name;	/* Name of this routine set */
>  	int prefer;		/* Has special performance attribute */
> -};
> +} __designated_init;
>  
>  /* Selected algorithm */
>  extern struct raid6_calls raid6_call;
> @@ -109,7 +109,7 @@ struct raid6_recov_calls {
>  	int  (*valid)(void);
>  	const char *name;
>  	int priority;
> -};
> +} __designated_init;
>  
>  extern const struct raid6_recov_calls raid6_recov_intx1;
>  extern const struct raid6_recov_calls raid6_recov_ssse3;
> diff --git a/include/linux/raid/xor.h b/include/linux/raid/xor.h
> index 5a21095..c7df59f 100644
> --- a/include/linux/raid/xor.h
> +++ b/include/linux/raid/xor.h
> @@ -17,6 +17,6 @@ struct xor_block_template {
>  		     unsigned long *, unsigned long *);
>  	void (*do_5)(unsigned long, unsigned long *, unsigned long *,
>  		     unsigned long *, unsigned long *, unsigned long *);
> -};
> +} __designated_init;
>  
>  #endif
> diff --git a/include/linux/raid_class.h b/include/linux/raid_class.h
> index 31e1ff6..603af94 100644
> --- a/include/linux/raid_class.h
> +++ b/include/linux/raid_class.h
> @@ -16,7 +16,7 @@ struct raid_function_template {
>  	int (*is_raid)(struct device *);
>  	void (*get_resync)(struct device *);
>  	void (*get_state)(struct device *);
> -};
> +} __designated_init;
>  
>  enum raid_state {
>  	RAID_STATE_UNKNOWN = 0,
> diff --git a/lib/raid6/altivec.uc b/lib/raid6/altivec.uc
> index 7cc12b5..4ff138c 100644
> --- a/lib/raid6/altivec.uc
> +++ b/lib/raid6/altivec.uc
> @@ -118,10 +118,9 @@ int raid6_have_altivec(void)
>  #endif
>  
>  const struct raid6_calls raid6_altivec$# = {
> -	raid6_altivec$#_gen_syndrome,
> -	raid6_have_altivec,
> -	"altivecx$#",
> -	0
> +	.gen_syndrome = raid6_altivec$#_gen_syndrome,
> +	.valid = raid6_have_altivec,
> +	.name = "altivecx$#",
>  };
>  
>  #endif /* CONFIG_ALTIVEC */
> diff --git a/lib/raid6/avx2.c b/lib/raid6/avx2.c
> index bc3b1dd..e56fa06 100644
> --- a/lib/raid6/avx2.c
> +++ b/lib/raid6/avx2.c
> @@ -88,10 +88,10 @@ static void raid6_avx21_gen_syndrome(int disks, size_t bytes, void **ptrs)
>  }
>  
>  const struct raid6_calls raid6_avx2x1 = {
> -	raid6_avx21_gen_syndrome,
> -	raid6_have_avx2,
> -	"avx2x1",
> -	1			/* Has cache hints */
> +	.gen_syndrome = raid6_avx21_gen_syndrome,
> +	.valid = raid6_have_avx2,
> +	.name = "avx2x1",
> +	.prefer = 1,		/* Has cache hints */
>  };
>  
>  /*
> @@ -149,10 +149,10 @@ static void raid6_avx22_gen_syndrome(int disks, size_t bytes, void **ptrs)
>  }
>  
>  const struct raid6_calls raid6_avx2x2 = {
> -	raid6_avx22_gen_syndrome,
> -	raid6_have_avx2,
> -	"avx2x2",
> -	1			/* Has cache hints */
> +	.gen_syndrome = raid6_avx22_gen_syndrome,
> +	.valid = raid6_have_avx2,
> +	.name = "avx2x2",
> +	.prefer = 1,		/* Has cache hints */
>  };
>  
>  #ifdef CONFIG_X86_64
> @@ -241,10 +241,10 @@ static void raid6_avx24_gen_syndrome(int disks, size_t bytes, void **ptrs)
>  }
>  
>  const struct raid6_calls raid6_avx2x4 = {
> -	raid6_avx24_gen_syndrome,
> -	raid6_have_avx2,
> -	"avx2x4",
> -	1			/* Has cache hints */
> +	.gen_syndrome = raid6_avx24_gen_syndrome,
> +	.valid = raid6_have_avx2,
> +	.name = "avx2x4",
> +	.prefer = 1,		/* Has cache hints */
>  };
>  #endif
>  
> diff --git a/lib/raid6/int.uc b/lib/raid6/int.uc
> index 5b50f8d..35ad01a 100644
> --- a/lib/raid6/int.uc
> +++ b/lib/raid6/int.uc
> @@ -108,10 +108,8 @@ static void raid6_int$#_gen_syndrome(int disks, size_t bytes, void **ptrs)
>  }
>  
>  const struct raid6_calls raid6_intx$# = {
> -	raid6_int$#_gen_syndrome,
> -	NULL,		/* always valid */
> -	"int" NSTRING "x$#",
> -	0
> +	.gen_syndrome = raid6_int$#_gen_syndrome,
> +	.name = "int" NSTRING "x$#",
>  };
>  
>  #endif
> diff --git a/lib/raid6/mmx.c b/lib/raid6/mmx.c
> index 590c71c..cdd7d02 100644
> --- a/lib/raid6/mmx.c
> +++ b/lib/raid6/mmx.c
> @@ -75,10 +75,9 @@ static void raid6_mmx1_gen_syndrome(int disks, size_t bytes, void **ptrs)
>  }
>  
>  const struct raid6_calls raid6_mmxx1 = {
> -	raid6_mmx1_gen_syndrome,
> -	raid6_have_mmx,
> -	"mmxx1",
> -	0
> +	.gen_syndrome = raid6_mmx1_gen_syndrome,
> +	.valid = raid6_have_mmx,
> +	.name = "mmxx1",
>  };
>  
>  /*
> @@ -133,10 +132,9 @@ static void raid6_mmx2_gen_syndrome(int disks, size_t bytes, void **ptrs)
>  }
>  
>  const struct raid6_calls raid6_mmxx2 = {
> -	raid6_mmx2_gen_syndrome,
> -	raid6_have_mmx,
> -	"mmxx2",
> -	0
> +	.gen_syndrome = raid6_mmx2_gen_syndrome,
> +	.valid = raid6_have_mmx,
> +	.name = "mmxx2",
>  };
>  
>  #endif
> diff --git a/lib/raid6/neon.c b/lib/raid6/neon.c
> index 36ad470..99100dd 100644
> --- a/lib/raid6/neon.c
> +++ b/lib/raid6/neon.c
> @@ -41,10 +41,9 @@
>  		kernel_neon_end();					\
>  	}								\
>  	struct raid6_calls const raid6_neonx ## _n = {			\
> -		raid6_neon ## _n ## _gen_syndrome,			\
> -		raid6_have_neon,					\
> -		"neonx" #_n,						\
> -		0							\
> +		.gen_syndrome = raid6_neon ## _n ## _gen_syndrome,	\
> +		.valid = raid6_have_neon,				\
> +		.name = "neonx" #_n,					\
>  	}
>  
>  static int raid6_have_neon(void)
> diff --git a/lib/raid6/sse1.c b/lib/raid6/sse1.c
> index f762971..a9de46e 100644
> --- a/lib/raid6/sse1.c
> +++ b/lib/raid6/sse1.c
> @@ -91,10 +91,10 @@ static void raid6_sse11_gen_syndrome(int disks, size_t bytes, void **ptrs)
>  }
>  
>  const struct raid6_calls raid6_sse1x1 = {
> -	raid6_sse11_gen_syndrome,
> -	raid6_have_sse1_or_mmxext,
> -	"sse1x1",
> -	1			/* Has cache hints */
> +	.gen_syndrome = raid6_sse11_gen_syndrome,
> +	.valid = raid6_have_sse1_or_mmxext,
> +	.name = "sse1x1",
> +	.prefer = 1,		/* Has cache hints */
>  };
>  
>  /*
> @@ -153,10 +153,10 @@ static void raid6_sse12_gen_syndrome(int disks, size_t bytes, void **ptrs)
>  }
>  
>  const struct raid6_calls raid6_sse1x2 = {
> -	raid6_sse12_gen_syndrome,
> -	raid6_have_sse1_or_mmxext,
> -	"sse1x2",
> -	1			/* Has cache hints */
> +	.gen_syndrome = raid6_sse12_gen_syndrome,
> +	.valid = raid6_have_sse1_or_mmxext,
> +	.name = "sse1x2",
> +	.prefer = 1,		/* Has cache hints */
>  };
>  
>  #endif
> diff --git a/lib/raid6/sse2.c b/lib/raid6/sse2.c
> index 85b82c8..cd262518aa 100644
> --- a/lib/raid6/sse2.c
> +++ b/lib/raid6/sse2.c
> @@ -89,10 +89,10 @@ static void raid6_sse21_gen_syndrome(int disks, size_t bytes, void **ptrs)
>  }
>  
>  const struct raid6_calls raid6_sse2x1 = {
> -	raid6_sse21_gen_syndrome,
> -	raid6_have_sse2,
> -	"sse2x1",
> -	1			/* Has cache hints */
> +	.gen_syndrome = raid6_sse21_gen_syndrome,
> +	.valid = raid6_have_sse2,
> +	.name = "sse2x1",
> +	.prefer = 1,		/* Has cache hints */
>  };
>  
>  /*
> @@ -151,10 +151,10 @@ static void raid6_sse22_gen_syndrome(int disks, size_t bytes, void **ptrs)
>  }
>  
>  const struct raid6_calls raid6_sse2x2 = {
> -	raid6_sse22_gen_syndrome,
> -	raid6_have_sse2,
> -	"sse2x2",
> -	1			/* Has cache hints */
> +	.gen_syndrome = raid6_sse22_gen_syndrome,
> +	.valid = raid6_have_sse2,
> +	.name = "sse2x2",
> +	.prefer = 1,		/* Has cache hints */
>  };
>  
>  #ifdef CONFIG_X86_64
> @@ -249,10 +249,10 @@ static void raid6_sse24_gen_syndrome(int disks, size_t bytes, void **ptrs)
>  }
>  
>  const struct raid6_calls raid6_sse2x4 = {
> -	raid6_sse24_gen_syndrome,
> -	raid6_have_sse2,
> -	"sse2x4",
> -	1			/* Has cache hints */
> +	.gen_syndrome = raid6_sse24_gen_syndrome,
> +	.valid = raid6_have_sse2,
> +	.name = "sse2x4",
> +	.prefer = 1,		/* Has cache hints */
>  };
>  
>  #endif /* CONFIG_X86_64 */
> diff --git a/lib/raid6/tilegx.uc b/lib/raid6/tilegx.uc
> index e7c2945..3077722 100644
> --- a/lib/raid6/tilegx.uc
> +++ b/lib/raid6/tilegx.uc
> @@ -79,8 +79,6 @@ void raid6_tilegx$#_gen_syndrome(int disks, size_t bytes, void **ptrs)
>  }
>  
>  const struct raid6_calls raid6_tilegx$# = {
> -	raid6_tilegx$#_gen_syndrome,
> -	NULL,
> -	"tilegx$#",
> -	0
> +	.gen_syndrome = raid6_tilegx$#_gen_syndrome,
> +	.name = "tilegx$#",
>  };


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: [PATCH 2/5] raid: Require designated initialization of structures
From: Josh Triplett @ 2014-08-01  1:30 UTC (permalink / raw)
  To: NeilBrown
  Cc: akpm, J. Bruce Fields, Alexander Viro, Christopher Li,
	Ingo Molnar, Jeff Layton, Michal Marek, Steven Rostedt, linux-api,
	linux-fsdevel, linux-kbuild, linux-kernel, linux-raid,
	linux-sparse
In-Reply-To: <20140801111055.59419950@notabene.brown>

On Fri, Aug 01, 2014 at 11:10:55AM +1000, NeilBrown wrote:
> On Thu, 31 Jul 2014 16:47:35 -0700 Josh Triplett <josh@joshtriplett.org>
> wrote:
> 
> > Mark raid6_calls and other structures containing function pointers with
> > __designated_init.  Fix implementations in lib/raid6/ to use designated
> > initializers; this also simplifies those initializers using the default
> > initialization of fields to 0.
> > 
> > Signed-off-by: Josh Triplett <josh@joshtriplett.org>
> 
> Looks like an excellent idea!
> Feel free to forward this upstream on my behalf, or remind me once the first
> patch is in -next, and I'll take this one myself - whichever you prefer.
> 
>  Acked-by: NeilBrown <neilb@suse.de>

Thanks!  Ideally, I'd like to see the whole series go in through one
tree, which is why I CCed Andrew.  I can easily produce several dozen
more patches like these, but I just included enough examples to motivate
patch 1, and I can send more in any order once that one goes in.

- Josh Triplett

^ permalink raw reply

* Re: [REVIEW][PATCH 0/4] /proc/thread-self
From: Davidlohr Bueso @ 2014-08-01  2:39 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Linux Containers, linux-api-u79uwXL29TY76Z2rM5mHXA,
	Michael Kerrisk (man-pages), linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <87oaw5caq1.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>

On Thu, 2014-07-31 at 17:30 -0700, Eric W. Biederman wrote:
> This is small chance changing /proc/net and /proc/mounts will cause
> userspace regressions (although nothing has shown up in my testing) if
> that happens we can just point the change that moves them from
> /proc/self/... to /proc/thread-self/...

Isn't breaking userspace a no no, no matter what? At least some
util-linux programs makes use of both /proc/mounts and /proc/net.

^ permalink raw reply

* Re: [REVIEW][PATCH 0/4] /proc/thread-self
From: Eric W. Biederman @ 2014-08-01  6:16 UTC (permalink / raw)
  To: Davidlohr Bueso
  Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, Linux Containers,
	Michael Kerrisk (man-pages), linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1406860795.3036.3.camel-5JQ4ckphU/8SZAcGdq5asR6epYMZPwEe5NbjCUgZEJk@public.gmane.org>

Davidlohr Bueso <davidlohr-VXdhtT5mjnY@public.gmane.org> writes:

> On Thu, 2014-07-31 at 17:30 -0700, Eric W. Biederman wrote:
>> This is small chance changing /proc/net and /proc/mounts will cause
>> userspace regressions (although nothing has shown up in my testing) if
>> that happens we can just point the change that moves them from
>> /proc/self/... to /proc/thread-self/...
>
> Isn't breaking userspace a no no, no matter what? At least some
> util-linux programs makes use of both /proc/mounts and /proc/net.

The only programs that will notice that /proc/mounts and /proc/net have
changed where they point are multi-threaded programs.

The vast majority of multi-thread programs have the same mount namespace
and network namespace across all threads.  Those programs will simply
see the case where /proc/mounts and /proc/net work now after the initial
thread has terminated.  (A Bug fix).

For the weird multi-threaded applications that access /proc/mounts or
/proc/net and have different namespaces in different threads this most
likely is a bug fix.  But this could potentially introduce a regression.

Which is a long way of saying that we don't have to remain bug
compatible with past versions of linux if no one cares about our bugs.

So while I am seriously concerned about the possibility of introducing a
regression the only way to find out if anyone cares is to release the
code and to release these patches, and see if anything breaks.  The
changes that might have to be reverted are trivial one liners, so it
will be easy to fix if something shows up.

So if you or anyone else knows of applications that are multi-threaded
have different namespaces on different threads and depend on
/proc/mounts or /proc/net always reflecting the namespace of the initial
thread in the program let me know.  Until then this series fixes at
least one long-standing annoying bug.

Eric

^ permalink raw reply

* Re: [REVIEW][PATCH 0/4] /proc/thread-self
From: Randy Dunlap @ 2014-08-01  6:45 UTC (permalink / raw)
  To: Eric W. Biederman, Linux Containers
  Cc: linux-api, Michael Kerrisk (man-pages), linux-fsdevel,
	linux-kernel
In-Reply-To: <87oaw5caq1.fsf@x220.int.ebiederm.org>

On 07/31/14 17:30, Eric W. Biederman wrote:
> 
> This patchset implements /proc/thread-self a magic symlink that
> solves a couple of problems.
> 
> - It makes it easy to get to a specific threads directory in /proc
>   with gettid() not being exported in glibc this is currently a pain.
> 
> - It allows fixing the problem present in /proc/mounts and /proc/net
>   that when the thread group leader exits but the entire thread group
>   remains /proc/self/net and /proc/self/mounts and thus /proc/mounts and
>   /proc/net become empty.
> 
> - As mount and network namespaces are per thread it allows /proc/net and
>   /proc/mounts to reflect this.

Hi Eric,

Any changes/additions to Documentation/ ?

Thanks.

> This is small chance changing /proc/net and /proc/mounts will cause
> userspace regressions (although nothing has shown up in my testing) if
> that happens we can just point the change that moves them from
> /proc/self/... to /proc/thread-self/...
> 
> Eric W. Biederman (4):
>       proc: Have net show up under /proc/<tgid>/task/<tid>
>       proc: Implement /proc/thread-self to point at the directory of the current thread
>       proc: Point /proc/net at /proc/thread-self/net instead of /proc/self/net
>       proc: Point /proc/mounts at /proc/thread-self/mounts instead of /proc/self/mounts
> 
>  fs/proc/Makefile              |  1 +
>  fs/proc/base.c                | 18 ++++++---
>  fs/proc/inode.c               |  7 +++-
>  fs/proc/internal.h            |  6 +++
>  fs/proc/proc_net.c            |  2 +-
>  fs/proc/root.c                |  5 ++-
>  fs/proc/thread_self.c         | 85 +++++++++++++++++++++++++++++++++++++++++++
>  include/linux/pid_namespace.h |  1 +
>  8 files changed, 117 insertions(+), 8 deletions(-)


-- 
~Randy

^ permalink raw reply

* Re: [REVIEW][PATCH 0/4] /proc/thread-self
From: Eric W. Biederman @ 2014-08-01  7:01 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, Linux Containers,
	Michael Kerrisk (man-pages), linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <53DB3790.7020600-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>

Randy Dunlap <rdunlap-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org> writes:

> On 07/31/14 17:30, Eric W. Biederman wrote:
>> 
>> This patchset implements /proc/thread-self a magic symlink that
>> solves a couple of problems.
>> 
>> - It makes it easy to get to a specific threads directory in /proc
>>   with gettid() not being exported in glibc this is currently a pain.
>> 
>> - It allows fixing the problem present in /proc/mounts and /proc/net
>>   that when the thread group leader exits but the entire thread group
>>   remains /proc/self/net and /proc/self/mounts and thus /proc/mounts and
>>   /proc/net become empty.
>> 
>> - As mount and network namespaces are per thread it allows /proc/net and
>>   /proc/mounts to reflect this.
>
> Hi Eric,
>
> Any changes/additions to Documentation/ ?

Not at this time.  I can imagine that there is proc manpage that might
need a line or two of Documentation.

I am not familiar with anything in Documentation that descripes any of
this and would benefit from an update.  From an overview perspective I
can see documenting this so people know thread-self exists.  From an
actual usage perspective:

  $ ls -l /proc/thread-self
  lrwxrwxrwx 1 root root 0 Aug  1 00:00 /proc/thread-self -> 484/task/484

seems like pretty comprehensive documentation to me.

Eric

^ permalink raw reply

* Re: [REVIEW][PATCH 0/4] /proc/thread-self
From: Bert Wesarg @ 2014-08-01  7:14 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Linux Containers, linux-api-u79uwXL29TY76Z2rM5mHXA,
	Michael Kerrisk (man-pages), linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <87oaw5caq1.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>

On Fri, Aug 1, 2014 at 2:30 AM, Eric W. Biederman <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> wrote:
>
> This patchset implements /proc/thread-self a magic symlink that
> solves a couple of problems.

shouldn't we keep the 'task' in the name, as it points into the 'task'
directory? And why not mimic the current 'self -> <id>' ideom under
/proc/<tgid>/task too and put a new 'self' link there:

$ ls -l /proc/self/task/self
  lrwxrwxrwx 1 root root 0 Aug  1 00:00 /proc/self/task/self -> 484

Bert

^ permalink raw reply

* Re: [REVIEW][PATCH 0/4] /proc/thread-self
From: Eric W. Biederman @ 2014-08-01  7:45 UTC (permalink / raw)
  To: Bert Wesarg
  Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, Linux Containers,
	Michael Kerrisk (man-pages),
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <CAKPyHN1k80fc0hkg7agMkCMDsb623=Zf-TrpyMiMLvtYEjz3_Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

Bert Wesarg <bert.wesarg-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> writes:

> On Fri, Aug 1, 2014 at 2:30 AM, Eric W. Biederman <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> wrote:
>>
>> This patchset implements /proc/thread-self a magic symlink that
>> solves a couple of problems.
>
> shouldn't we keep the 'task' in the name, as it points into the 'task'
> directory? And why not mimic the current 'self -> <id>' ideom under
> /proc/<tgid>/task too and put a new 'self' link there:
>
> $ ls -l /proc/self/task/self
>   lrwxrwxrwx 1 root root 0 Aug  1 00:00 /proc/self/task/self -> 484

No particularly good reason.  

Mostly I picked thread-self as I could pick that out as a concept in the
code distinct from self and distinct from thread and it the
implementation was stratighforward.

Your approach requires a bit more symlink recursion than mine so it is
not my first choice.

I almost pointed it at just the sometimes invisible thread directory
directly under /proc so it would be a single number.  But that has the
issue that it you still get the process rollups in the numbers reported
by some of the proc files, which is undesirable.

Frankly I think it was a mistake by the nptl kernel code to have changed
the implementation of self.  But changing /proc/self to return the tid
at this point is more likely than not to beak applications so that I
have avoided.

Eric

^ permalink raw reply

* Re: [Xen-devel] [PATCH 1/2] xen: Implement ioctl to restrict privcmd to a specific domain
From: Jan Beulich @ 2014-08-01  8:27 UTC (permalink / raw)
  To: Frediano Ziglio
  Cc: David Vrabel, xen-devel, Boris Ostrovsky, Konrad Rzeszutek Wilk,
	linux-api-u79uwXL29TY76Z2rM5mHXA, linux-kernel
In-Reply-To: <E1XCqEY-0005zn-V2-GuqFBffKawuEi8DpZVb4nw@public.gmane.org>

>>> On 31.07.14 at 15:16, <frediano.ziglio-Sxgqhf6Nn4DQT0dZR+AlfA@public.gmane.org> wrote:
> Add a RESTRICT ioctl to /dev/xen/privcmd, which allows privileged commands
> file descriptor to be restricted to only working with a particular domain.

The "with" here has been quite confusing, and I realized that you
mean the subject domain rather than the actor one only after
having gone through quite some parts of the patch. For a patch
this size, a little more of a description (and the original motivation)
would have helped.

Wrt motivation: Why does this need enforcing in the kernel at all?
Doesn't XSM_DM_PRIV mode deal specifically with what you're
trying to do here? Or else I guess I really need some better
explanation of what this is about.

Jan

^ permalink raw reply

* Re: [Xen-devel] [PATCH 1/2] xen: Implement ioctl to restrict privcmd to a specific domain
From: Frediano Ziglio @ 2014-08-01 13:44 UTC (permalink / raw)
  To: Jan Beulich
  Cc: David Vrabel, xen-devel, Boris Ostrovsky, Konrad Rzeszutek Wilk,
	linux-api-u79uwXL29TY76Z2rM5mHXA, linux-kernel
In-Reply-To: <53DB6B8D02000078000284D3-tRfBTM6QL9aeHWOVceGJHFaTQe2KTcn/@public.gmane.org>

On Fri, 2014-08-01 at 09:27 +0100, Jan Beulich wrote:
> >>> On 31.07.14 at 15:16, <frediano.ziglio-Sxgqhf6Nn4DQT0dZR+AlfA@public.gmane.org> wrote:
> > Add a RESTRICT ioctl to /dev/xen/privcmd, which allows privileged commands
> > file descriptor to be restricted to only working with a particular domain.
> 
> The "with" here has been quite confusing, and I realized that you
> mean the subject domain rather than the actor one only after
> having gone through quite some parts of the patch. For a patch
> this size, a little more of a description (and the original motivation)
> would have helped.
> 

Yes, you are right.

> Wrt motivation: Why does this need enforcing in the kernel at all?
> Doesn't XSM_DM_PRIV mode deal specifically with what you're
> trying to do here? Or else I guess I really need some better
> explanation of what this is about.
> 
> Jan
> 

This is quite old for me but you are right, perhaps is not that clear
for other people. In XenServer we have some patches that allow Qemu
running in dom0 but work only for a specific domain. The patches
required changes to libxc, kernel and Qemu. We are reimplementing these
patches as the old implementation has some problems (one is that the
patch for libxc was quite big). This feature was removed as kernel
patches did not work with newer (3.x) kernels.

Now, XSM_DM_PRIV works checking if the domain target is the domain we
are going to handle. However if your dom0 (as in XenServer) has all Qemu
to handle all VMs it cannot be bound to a single target so XSM is not
usable. Xen has no knowledge of process or file descriptor (which are
kernel specific) so there is actually no way it can distinguish which
domain should be restricted to. It would solve if the restriction would
be done for system call (so we can say execute this hypercall(s) with
these policies). However this require to change the target to be at
least CPU specific and handle preemption correctly in order to not mix
policies. This could be quite heavy so we hack the kernel in order to do
the restriction instead (it also was easier to port the patches).

Actually changes in Qemu to handle the privcmd/evtchn restrictions are
quite small, mainly restrict these two handles with an ioctl. Other
parts of the patch (chroot, setuid, groups, resource limits, and mostly
xenstore accesses) are more heavy.

Frediano

^ 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