public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Dave Hansen <haveblue@us.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: serue@us.ibm.com, frankeh@watson.ibm.com, clg@fr.ibm.com,
	Herbert Poetzl <herbert@13thfloor.at>,
	Sam Vilain <sam@vilain.net>, Dave Hansen <haveblue@us.ibm.com>
Subject: [RFC][PATCH 5/6] sysvshm: containerize
Date: Mon, 06 Mar 2006 15:52:52 -0800	[thread overview]
Message-ID: <20060306235252.1514C348@localhost.localdomain> (raw)
In-Reply-To: <20060306235248.20842700@localhost.localdomain>


Same thing as sems and msgs.

Take all of the global sysv shm context and put it inside of
a special structure.  This allows future work to give different
containers completely different views into the sysv space.

Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
---

 work-dave/ipc/shm.c  |  197 +++++++++++++++++++++++++++------------------------
 work-dave/ipc/util.c |    3 
 work-dave/ipc/util.h |    9 ++
 3 files changed, 118 insertions(+), 91 deletions(-)

diff -puN include/linux/sched.h~sysvshm-container include/linux/sched.h
diff -puN ipc/shm.c~sysvshm-container ipc/shm.c
--- work/ipc/shm.c~sysvshm-container	2006-03-06 15:41:59.000000000 -0800
+++ work-dave/ipc/shm.c	2006-03-06 15:41:59.000000000 -0800
@@ -38,15 +38,17 @@
 static struct file_operations shm_file_operations;
 static struct vm_operations_struct shm_vm_ops;
 
-static struct ipc_ids shm_ids;
+#define shm_lock(context, id)		\
+	((struct shmid_kernel*)ipc_lock(&context->ids,id))
+#define shm_unlock(context, shp)	\
+	ipc_unlock(&(shp)->shm_perm)
+#define shm_get(context, id)\
+	((struct shmid_kernel*)ipc_get(&context->ids,id))
+#define shm_buildid(context, id, seq) \
+	ipc_buildid(&context->ids, id, seq)
 
-#define shm_lock(id)	((struct shmid_kernel*)ipc_lock(&shm_ids,id))
-#define shm_unlock(shp)	ipc_unlock(&(shp)->shm_perm)
-#define shm_get(id)	((struct shmid_kernel*)ipc_get(&shm_ids,id))
-#define shm_buildid(id, seq) \
-	ipc_buildid(&shm_ids, id, seq)
-
-static int newseg (key_t key, int shmflg, size_t size);
+static int newseg (struct ipc_shm_context *context,
+		   key_t key, int shmflg, size_t size);
 static void shm_open (struct vm_area_struct *shmd);
 static void shm_close (struct vm_area_struct *shmd);
 #ifdef CONFIG_PROC_FS
@@ -57,51 +59,53 @@ size_t	shm_ctlmax = SHMMAX;
 size_t 	shm_ctlall = SHMALL;
 int 	shm_ctlmni = SHMMNI;
 
-static int shm_tot; /* total number of shared memory pages */
-
-void __init shm_init (void)
+void __init shm_init (struct ipc_shm_context *context)
 {
-	ipc_init_ids(&shm_ids, 1);
+	ipc_init_ids(&context->ids, 1);
 	ipc_init_proc_interface("sysvipc/shm",
 				"       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime\n",
-				&shm_ids,
+				&context->ids,
 				sysvipc_shm_proc_show);
 }
 
-static inline int shm_checkid(struct shmid_kernel *s, int id)
+static inline int shm_checkid(struct ipc_shm_context *context,
+			      struct shmid_kernel *s, int id)
 {
-	if (ipc_checkid(&shm_ids,&s->shm_perm,id))
+	if (ipc_checkid(&context->ids,&s->shm_perm,id))
 		return -EIDRM;
 	return 0;
 }
 
-static inline struct shmid_kernel *shm_rmid(int id)
+static inline
+struct shmid_kernel *shm_rmid(struct ipc_shm_context *context, int id)
 {
-	return (struct shmid_kernel *)ipc_rmid(&shm_ids,id);
+	return (struct shmid_kernel *)ipc_rmid(&context->ids,id);
 }
 
-static inline int shm_addid(struct shmid_kernel *shp)
+static inline
+int shm_addid(struct ipc_shm_context *context, struct shmid_kernel *shp)
 {
-	return ipc_addid(&shm_ids, &shp->shm_perm, shm_ctlmni);
+	return ipc_addid(&context->ids, &shp->shm_perm, shm_ctlmni);
 }
 
 
 
-static inline void shm_inc (int id) {
+static inline void shm_inc (struct ipc_shm_context *context, int id) {
 	struct shmid_kernel *shp;
 
-	if(!(shp = shm_lock(id)))
+	if(!(shp = shm_lock(context, id)))
 		BUG();
 	shp->shm_atim = get_seconds();
 	shp->shm_lprid = current->tgid;
 	shp->shm_nattch++;
-	shm_unlock(shp);
+	shm_unlock(context, shp);
 }
 
 /* This is called by fork, once for every shm attach. */
 static void shm_open (struct vm_area_struct *shmd)
 {
-	shm_inc (shmd->vm_file->f_dentry->d_inode->i_ino);
+	struct ipc_shm_context *context = shmd->vm_private_data;
+	shm_inc (context, shmd->vm_file->f_dentry->d_inode->i_ino);
 }
 
 /*
@@ -109,14 +113,15 @@ static void shm_open (struct vm_area_str
  *
  * @shp: struct to free
  *
- * It has to be called with shp and shm_ids.sem locked,
+ * It has to be called with shp and context->ids.sem locked,
  * but returns with shp unlocked and freed.
  */
-static void shm_destroy (struct shmid_kernel *shp)
+static void shm_destroy (struct ipc_shm_context *context,
+			 struct shmid_kernel *shp)
 {
-	shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	shm_rmid (shp->id);
-	shm_unlock(shp);
+	context->tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	shm_rmid (context, shp->id);
+	shm_unlock(context, shp);
 	if (!is_file_hugepages(shp->shm_file))
 		shmem_lock(shp->shm_file, 0, shp->mlock_user);
 	else
@@ -138,30 +143,39 @@ static void shm_close (struct vm_area_st
 	struct file * file = shmd->vm_file;
 	int id = file->f_dentry->d_inode->i_ino;
 	struct shmid_kernel *shp;
+	struct ipc_shm_context *context = shmd->vm_private_data;
 
-	down (&shm_ids.sem);
+	down (&context->ids.sem);
 	/* remove from the list of attaches of the shm segment */
-	if(!(shp = shm_lock(id)))
+	if(!(shp = shm_lock(context, id)))
 		BUG();
 	shp->shm_lprid = current->tgid;
 	shp->shm_dtim = get_seconds();
 	shp->shm_nattch--;
 	if(shp->shm_nattch == 0 &&
 	   shp->shm_perm.mode & SHM_DEST)
-		shm_destroy (shp);
+		shm_destroy (context, shp);
 	else
-		shm_unlock(shp);
-	up (&shm_ids.sem);
+		shm_unlock(context, shp);
+	up (&context->ids.sem);
 }
 
 static int shm_mmap(struct file * file, struct vm_area_struct * vma)
 {
 	int ret;
+	struct ipc_shm_context *context = current->ipc_shm_context;
 
 	ret = shmem_mmap(file, vma);
 	if (ret == 0) {
 		vma->vm_ops = &shm_vm_ops;
-		shm_inc(file->f_dentry->d_inode->i_ino);
+		/*
+		 * This implies that the shm context can not change
+		 * while a task is running because this mmap's
+		 * context would change underneath it.
+		 * -- You many only change shm context at exec()
+		 */
+		vma->vm_private_data = context;
+		shm_inc(context, file->f_dentry->d_inode->i_ino);
 	}
 
 	return ret;
@@ -184,7 +198,8 @@ static struct vm_operations_struct shm_v
 #endif
 };
 
-static int newseg (key_t key, int shmflg, size_t size)
+static int newseg (struct ipc_shm_context *context,
+		   key_t key, int shmflg, size_t size)
 {
 	int error;
 	struct shmid_kernel *shp;
@@ -196,7 +211,7 @@ static int newseg (key_t key, int shmflg
 	if (size < SHMMIN || size > shm_ctlmax)
 		return -EINVAL;
 
-	if (shm_tot + numpages >= shm_ctlall)
+	if (context->tot + numpages >= shm_ctlall)
 		return -ENOSPC;
 
 	shp = ipc_rcu_alloc(sizeof(*shp));
@@ -235,7 +250,7 @@ static int newseg (key_t key, int shmflg
 		goto no_file;
 
 	error = -ENOSPC;
-	id = shm_addid(shp);
+	id = shm_addid(context, shp);
 	if(id == -1) 
 		goto no_id;
 
@@ -245,7 +260,7 @@ static int newseg (key_t key, int shmflg
 	shp->shm_ctim = get_seconds();
 	shp->shm_segsz = size;
 	shp->shm_nattch = 0;
-	shp->id = shm_buildid(id,shp->shm_perm.seq);
+	shp->id = shm_buildid(context, id,shp->shm_perm.seq);
 	shp->shm_file = file;
 	file->f_dentry->d_inode->i_ino = shp->id;
 
@@ -253,8 +268,8 @@ static int newseg (key_t key, int shmflg
 	if (!(shmflg & SHM_HUGETLB))
 		file->f_op = &shm_file_operations;
 
-	shm_tot += numpages;
-	shm_unlock(shp);
+	context->tot += numpages;
+	shm_unlock(context, shp);
 	return shp->id;
 
 no_id:
@@ -269,19 +284,20 @@ asmlinkage long sys_shmget (key_t key, s
 {
 	struct shmid_kernel *shp;
 	int err, id = 0;
+	struct ipc_shm_context *context = current->ipc_shm_context;
 
-	down(&shm_ids.sem);
+	down(&context->ids.sem);
 	if (key == IPC_PRIVATE) {
-		err = newseg(key, shmflg, size);
-	} else if ((id = ipc_findkey(&shm_ids, key)) == -1) {
+		err = newseg(context, key, shmflg, size);
+	} else if ((id = ipc_findkey(&context->ids, key)) == -1) {
 		if (!(shmflg & IPC_CREAT))
 			err = -ENOENT;
 		else
-			err = newseg(key, shmflg, size);
+			err = newseg(context, key, shmflg, size);
 	} else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
 		err = -EEXIST;
 	} else {
-		shp = shm_lock(id);
+		shp = shm_lock(context, id);
 		if(shp==NULL)
 			BUG();
 		if (shp->shm_segsz < size)
@@ -289,14 +305,14 @@ asmlinkage long sys_shmget (key_t key, s
 		else if (ipcperms(&shp->shm_perm, shmflg))
 			err = -EACCES;
 		else {
-			int shmid = shm_buildid(id, shp->shm_perm.seq);
+			int shmid = shm_buildid(context, id, shp->shm_perm.seq);
 			err = security_shm_associate(shp, shmflg);
 			if (!err)
 				err = shmid;
 		}
-		shm_unlock(shp);
+		shm_unlock(context, shp);
 	}
-	up(&shm_ids.sem);
+	up(&context->ids.sem);
 
 	return err;
 }
@@ -392,18 +408,19 @@ static inline unsigned long copy_shminfo
 	}
 }
 
-static void shm_get_stat(unsigned long *rss, unsigned long *swp) 
+static void shm_get_stat(struct ipc_shm_context *context,
+			 unsigned long *rss, unsigned long *swp)
 {
 	int i;
 
 	*rss = 0;
 	*swp = 0;
 
-	for (i = 0; i <= shm_ids.max_id; i++) {
+	for (i = 0; i <= context->ids.max_id; i++) {
 		struct shmid_kernel *shp;
 		struct inode *inode;
 
-		shp = shm_get(i);
+		shp = shm_get(context, i);
 		if(!shp)
 			continue;
 
@@ -427,6 +444,7 @@ asmlinkage long sys_shmctl (int shmid, i
 	struct shm_setbuf setbuf;
 	struct shmid_kernel *shp;
 	int err, version;
+	struct ipc_shm_context *context = current->ipc_shm_context;
 
 	if (cmd < 0 || shmid < 0) {
 		err = -EINVAL;
@@ -453,7 +471,7 @@ asmlinkage long sys_shmctl (int shmid, i
 		if(copy_shminfo_to_user (buf, &shminfo, version))
 			return -EFAULT;
 		/* reading a integer is always atomic */
-		err= shm_ids.max_id;
+		err= context->ids.max_id;
 		if(err<0)
 			err = 0;
 		goto out;
@@ -467,14 +485,14 @@ asmlinkage long sys_shmctl (int shmid, i
 			return err;
 
 		memset(&shm_info,0,sizeof(shm_info));
-		down(&shm_ids.sem);
-		shm_info.used_ids = shm_ids.in_use;
-		shm_get_stat (&shm_info.shm_rss, &shm_info.shm_swp);
-		shm_info.shm_tot = shm_tot;
+		down(&context->ids.sem);
+		shm_info.used_ids = context->ids.in_use;
+		shm_get_stat (context, &shm_info.shm_rss, &shm_info.shm_swp);
+		shm_info.shm_tot = context->tot;
 		shm_info.swap_attempts = 0;
 		shm_info.swap_successes = 0;
-		err = shm_ids.max_id;
-		up(&shm_ids.sem);
+		err = context->ids.max_id;
+		up(&context->ids.sem);
 		if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
 			err = -EFAULT;
 			goto out;
@@ -489,17 +507,17 @@ asmlinkage long sys_shmctl (int shmid, i
 		struct shmid64_ds tbuf;
 		int result;
 		memset(&tbuf, 0, sizeof(tbuf));
-		shp = shm_lock(shmid);
+		shp = shm_lock(context, shmid);
 		if(shp==NULL) {
 			err = -EINVAL;
 			goto out;
 		} else if(cmd==SHM_STAT) {
 			err = -EINVAL;
-			if (shmid > shm_ids.max_id)
+			if (shmid > context->ids.max_id)
 				goto out_unlock;
-			result = shm_buildid(shmid, shp->shm_perm.seq);
+			result = shm_buildid(context, shmid, shp->shm_perm.seq);
 		} else {
-			err = shm_checkid(shp,shmid);
+			err = shm_checkid(context,shp,shmid);
 			if(err)
 				goto out_unlock;
 			result = 0;
@@ -521,7 +539,7 @@ asmlinkage long sys_shmctl (int shmid, i
 			tbuf.shm_nattch	= shp->shm_nattch;
 		else
 			tbuf.shm_nattch = file_count(shp->shm_file) - 1;
-		shm_unlock(shp);
+		shm_unlock(context, shp);
 		if(copy_shmid_to_user (buf, &tbuf, version))
 			err = -EFAULT;
 		else
@@ -531,12 +549,12 @@ asmlinkage long sys_shmctl (int shmid, i
 	case SHM_LOCK:
 	case SHM_UNLOCK:
 	{
-		shp = shm_lock(shmid);
+		shp = shm_lock(context, shmid);
 		if(shp==NULL) {
 			err = -EINVAL;
 			goto out;
 		}
-		err = shm_checkid(shp,shmid);
+		err = shm_checkid(context,shp,shmid);
 		if(err)
 			goto out_unlock;
 
@@ -568,7 +586,7 @@ asmlinkage long sys_shmctl (int shmid, i
 			shp->shm_perm.mode &= ~SHM_LOCKED;
 			shp->mlock_user = NULL;
 		}
-		shm_unlock(shp);
+		shm_unlock(context, shp);
 		goto out;
 	}
 	case IPC_RMID:
@@ -583,12 +601,12 @@ asmlinkage long sys_shmctl (int shmid, i
 		 *	Instead we set a destroyed flag, and then blow
 		 *	the name away when the usage hits zero.
 		 */
-		down(&shm_ids.sem);
-		shp = shm_lock(shmid);
+		down(&context->ids.sem);
+		shp = shm_lock(context, shmid);
 		err = -EINVAL;
 		if (shp == NULL) 
 			goto out_up;
-		err = shm_checkid(shp, shmid);
+		err = shm_checkid(context, shp, shmid);
 		if(err)
 			goto out_unlock_up;
 
@@ -607,10 +625,10 @@ asmlinkage long sys_shmctl (int shmid, i
 			shp->shm_perm.mode |= SHM_DEST;
 			/* Do not find it any more */
 			shp->shm_perm.key = IPC_PRIVATE;
-			shm_unlock(shp);
+			shm_unlock(context, shp);
 		} else
-			shm_destroy (shp);
-		up(&shm_ids.sem);
+			shm_destroy (context, shp);
+		up(&context->ids.sem);
 		goto out;
 	}
 
@@ -622,12 +640,12 @@ asmlinkage long sys_shmctl (int shmid, i
 		}
 		if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode)))
 			return err;
-		down(&shm_ids.sem);
-		shp = shm_lock(shmid);
+		down(&context->ids.sem);
+		shp = shm_lock(context, shmid);
 		err=-EINVAL;
 		if(shp==NULL)
 			goto out_up;
-		err = shm_checkid(shp,shmid);
+		err = shm_checkid(context,shp,shmid);
 		if(err)
 			goto out_unlock_up;
 		err=-EPERM;
@@ -656,12 +674,12 @@ asmlinkage long sys_shmctl (int shmid, i
 
 	err = 0;
 out_unlock_up:
-	shm_unlock(shp);
+	shm_unlock(context, shp);
 out_up:
-	up(&shm_ids.sem);
+	up(&context->ids.sem);
 	goto out;
 out_unlock:
-	shm_unlock(shp);
+	shm_unlock(context, shp);
 out:
 	return err;
 }
@@ -675,6 +693,7 @@ out:
  */
 long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
 {
+	struct ipc_shm_context *context = current->ipc_shm_context;
 	struct shmid_kernel *shp;
 	unsigned long addr;
 	unsigned long size;
@@ -725,32 +744,32 @@ long do_shmat(int shmid, char __user *sh
 	 * We cannot rely on the fs check since SYSV IPC does have an
 	 * additional creator id...
 	 */
-	shp = shm_lock(shmid);
+	shp = shm_lock(context, shmid);
 	if(shp == NULL) {
 		err = -EINVAL;
 		goto out;
 	}
-	err = shm_checkid(shp,shmid);
+	err = shm_checkid(context,shp,shmid);
 	if (err) {
-		shm_unlock(shp);
+		shm_unlock(context, shp);
 		goto out;
 	}
 	if (ipcperms(&shp->shm_perm, acc_mode)) {
-		shm_unlock(shp);
+		shm_unlock(context, shp);
 		err = -EACCES;
 		goto out;
 	}
 
 	err = security_shm_shmat(shp, shmaddr, shmflg);
 	if (err) {
-		shm_unlock(shp);
+		shm_unlock(context, shp);
 		return err;
 	}
 		
 	file = shp->shm_file;
 	size = i_size_read(file->f_dentry->d_inode);
 	shp->shm_nattch++;
-	shm_unlock(shp);
+	shm_unlock(context, shp);
 
 	down_write(&current->mm->mmap_sem);
 	if (addr && !(shmflg & SHM_REMAP)) {
@@ -771,16 +790,16 @@ long do_shmat(int shmid, char __user *sh
 invalid:
 	up_write(&current->mm->mmap_sem);
 
-	down (&shm_ids.sem);
-	if(!(shp = shm_lock(shmid)))
+	down (&context->ids.sem);
+	if(!(shp = shm_lock(context, shmid)))
 		BUG();
 	shp->shm_nattch--;
 	if(shp->shm_nattch == 0 &&
 	   shp->shm_perm.mode & SHM_DEST)
-		shm_destroy (shp);
+		shm_destroy (context, shp);
 	else
-		shm_unlock(shp);
-	up (&shm_ids.sem);
+		shm_unlock(context, shp);
+	up (&context->ids.sem);
 
 	*raddr = (unsigned long) user_addr;
 	err = 0;
diff -puN ipc/util.c~sysvshm-container ipc/util.c
--- work/ipc/util.c~sysvshm-container	2006-03-06 15:41:59.000000000 -0800
+++ work-dave/ipc/util.c	2006-03-06 15:41:59.000000000 -0800
@@ -46,6 +46,7 @@ struct ipc_proc_iface {
  *	memory are initialised
  */
 
+struct ipc_shm_context *ipc_shm_context;
 static int __init ipc_init(void)
 {
 	init_task.ipc_context = kzalloc(sizeof(*ipc_context), GFP_KERNEL);
@@ -54,7 +55,7 @@ static int __init ipc_init(void)
 
 	sem_init(&init_task.ipc_context->sem);
 	msg_init(&init_task.ipc_context->msg);
-	shm_init();
+	shm_init(&init_task.ipc_context->shm);
 	return 0;
 }
 __initcall(ipc_init);
diff -puN ipc/util.h~sysvshm-container ipc/util.h
--- work/ipc/util.h~sysvshm-container	2006-03-06 15:41:59.000000000 -0800
+++ work-dave/ipc/util.h	2006-03-06 15:41:59.000000000 -0800
@@ -44,14 +44,21 @@ struct ipc_sem_context {
 	int nr_used;
 };
 
+struct ipc_shm_context {
+	struct ipc_ids ids;
+
+	int tot; /* total number of shared memory pages */
+};
+
 struct ipc_context {
 	struct ipc_msg_context msg;
 	struct ipc_sem_context sem;
+	struct ipc_shm_context shm;
 };
 
 void sem_init (struct ipc_sem_context *context);
 void msg_init (struct ipc_msg_context *context);
-void shm_init (void);
+void shm_init (struct ipc_shm_context *context);
 
 struct seq_file;
 void __init ipc_init_ids(struct ipc_ids* ids, int size);
_

  parent reply	other threads:[~2006-03-06 23:54 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-03-06 23:52 [RFC][PATCH 0/6] support separate namespaces for sysv Dave Hansen
2006-03-06 23:52 ` [RFC][PATCH 1/6] prepare sysctls for containers Dave Hansen
2006-03-07  0:50   ` Herbert Poetzl
2006-03-07  2:00     ` Dave Hansen
2006-03-07  2:45       ` Herbert Poetzl
2006-03-19 15:54         ` Eric W. Biederman
2006-03-07  1:01   ` Chris Wright
2006-03-07  2:04     ` Dave Hansen
2006-03-07  2:18       ` Chris Wright
2006-03-07  3:02       ` Sam Vilain
2006-03-07  1:24   ` Al Viro
2006-03-07  1:55     ` Dave Hansen
2006-03-07  1:57       ` Al Viro
2006-03-19 14:50         ` Eric W. Biederman
2006-03-19 15:29   ` Eric W. Biederman
2006-03-06 23:52 ` [RFC][PATCH 2/6] sysvmsg: containerize Dave Hansen
2006-03-07  1:57   ` Chris Wright
2006-03-07  2:08     ` Dave Hansen
2006-03-07  2:34       ` Chris Wright
2006-03-19 15:36         ` Eric W. Biederman
2006-03-20 19:34           ` Chris Wright
2006-03-20 21:29             ` Eric W. Biederman
2006-03-20 21:50               ` Chris Wright
2006-03-06 23:52 ` [RFC][PATCH 3/6] sysvmsg: containerize sysctls Dave Hansen
2006-03-06 23:52 ` [RFC][PATCH 4/6] sysvsem: containerize Dave Hansen
2006-03-07  2:44   ` Chris Wright
2006-03-07  5:08     ` Dave Hansen
2006-03-06 23:52 ` Dave Hansen [this message]
2006-03-06 23:52 ` [RFC][PATCH 6/6] sysvshm: containerize sysctls Dave Hansen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060306235252.1514C348@localhost.localdomain \
    --to=haveblue@us.ibm.com \
    --cc=clg@fr.ibm.com \
    --cc=frankeh@watson.ibm.com \
    --cc=herbert@13thfloor.at \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sam@vilain.net \
    --cc=serue@us.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox