Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed2ddbf8 authored by Pierre Peiffer's avatar Pierre Peiffer Committed by Linus Torvalds
Browse files

IPC: make struct ipc_ids static in ipc_namespace



Each ipc_namespace contains a table of 3 pointers to struct ipc_ids (3 for
msg, sem and shm, structure used to store all ipcs) These 'struct ipc_ids'
are dynamically allocated for each icp_namespace as the ipc_namespace
itself (for the init namespace, they are initialized with pointers to
static variables instead)

It is so for historical reason: in fact, before the use of idr to store the
ipcs, the ipcs were stored in tables of variable length, depending of the
maximum number of ipc allowed.  Now, these 'struct ipc_ids' have a fixed
size.  As they are allocated in any cases for each new ipc_namespace, there
is no gain of memory in having them allocated separately of the struct
ipc_namespace.

This patch proposes to make this table static in the struct ipc_namespace.
Thus, we can allocate all in once and get rid of all the code needed to
allocate and free these ipc_ids separately.

Signed-off-by: default avatarPierre Peiffer <pierre.peiffer@bull.net>
Acked-by: default avatarCedric Le Goater <clg@fr.ibm.com>
Cc: Pavel Emelyanov <xemul@openvz.org>
Cc: Nadia Derbey <Nadia.Derbey@bull.net>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 4b9fcb0e
Loading
Loading
Loading
Loading
+11 −2
Original line number Original line Diff line number Diff line
@@ -2,11 +2,20 @@
#define __IPC_NAMESPACE_H__
#define __IPC_NAMESPACE_H__


#include <linux/err.h>
#include <linux/err.h>
#include <linux/idr.h>
#include <linux/rwsem.h>

struct ipc_ids {
	int in_use;
	unsigned short seq;
	unsigned short seq_max;
	struct rw_semaphore rw_mutex;
	struct idr ipcs_idr;
};


struct ipc_ids;
struct ipc_namespace {
struct ipc_namespace {
	struct kref	kref;
	struct kref	kref;
	struct ipc_ids	*ids[3];
	struct ipc_ids	ids[3];


	int		sem_ctls[4];
	int		sem_ctls[4];
	int		used_sems;
	int		used_sems;
+4 −22
Original line number Original line Diff line number Diff line
@@ -67,9 +67,7 @@ struct msg_sender {
#define SEARCH_NOTEQUAL		3
#define SEARCH_NOTEQUAL		3
#define SEARCH_LESSEQUAL	4
#define SEARCH_LESSEQUAL	4


static struct ipc_ids init_msg_ids;
#define msg_ids(ns)	((ns)->ids[IPC_MSG_IDS])

#define msg_ids(ns)	(*((ns)->ids[IPC_MSG_IDS]))


#define msg_unlock(msq)		ipc_unlock(&(msq)->q_perm)
#define msg_unlock(msq)		ipc_unlock(&(msq)->q_perm)
#define msg_buildid(id, seq)	ipc_buildid(id, seq)
#define msg_buildid(id, seq)	ipc_buildid(id, seq)
@@ -80,30 +78,17 @@ static int newque(struct ipc_namespace *, struct ipc_params *);
static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
#endif
#endif


static void __msg_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
void msg_init_ns(struct ipc_namespace *ns)
{
{
	ns->ids[IPC_MSG_IDS] = ids;
	ns->msg_ctlmax = MSGMAX;
	ns->msg_ctlmax = MSGMAX;
	ns->msg_ctlmnb = MSGMNB;
	ns->msg_ctlmnb = MSGMNB;
	ns->msg_ctlmni = MSGMNI;
	ns->msg_ctlmni = MSGMNI;
	atomic_set(&ns->msg_bytes, 0);
	atomic_set(&ns->msg_bytes, 0);
	atomic_set(&ns->msg_hdrs, 0);
	atomic_set(&ns->msg_hdrs, 0);
	ipc_init_ids(ids);
	ipc_init_ids(&ns->ids[IPC_MSG_IDS]);
}
}


#ifdef CONFIG_IPC_NS
#ifdef CONFIG_IPC_NS
int msg_init_ns(struct ipc_namespace *ns)
{
	struct ipc_ids *ids;

	ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
	if (ids == NULL)
		return -ENOMEM;

	__msg_init_ns(ns, ids);
	return 0;
}

void msg_exit_ns(struct ipc_namespace *ns)
void msg_exit_ns(struct ipc_namespace *ns)
{
{
	struct msg_queue *msq;
	struct msg_queue *msq;
@@ -126,15 +111,12 @@ void msg_exit_ns(struct ipc_namespace *ns)
	}
	}


	up_write(&msg_ids(ns).rw_mutex);
	up_write(&msg_ids(ns).rw_mutex);

	kfree(ns->ids[IPC_MSG_IDS]);
	ns->ids[IPC_MSG_IDS] = NULL;
}
}
#endif
#endif


void __init msg_init(void)
void __init msg_init(void)
{
{
	__msg_init_ns(&init_ipc_ns, &init_msg_ids);
	msg_init_ns(&init_ipc_ns);
	ipc_init_proc_interface("sysvipc/msg",
	ipc_init_proc_interface("sysvipc/msg",
				"       key      msqid perms      cbytes       qnum lspid lrpid   uid   gid  cuid  cgid      stime      rtime      ctime\n",
				"       key      msqid perms      cbytes       qnum lspid lrpid   uid   gid  cuid  cgid      stime      rtime      ctime\n",
				IPC_MSG_IDS, sysvipc_msg_proc_show);
				IPC_MSG_IDS, sysvipc_msg_proc_show);
+4 −21
Original line number Original line Diff line number Diff line
@@ -14,35 +14,18 @@


static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
{
{
	int err;
	struct ipc_namespace *ns;
	struct ipc_namespace *ns;


	err = -ENOMEM;
	ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL);
	ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL);
	if (ns == NULL)
	if (ns == NULL)
		goto err_mem;
		return ERR_PTR(-ENOMEM);


	err = sem_init_ns(ns);
	sem_init_ns(ns);
	if (err)
	msg_init_ns(ns);
		goto err_sem;
	shm_init_ns(ns);
	err = msg_init_ns(ns);
	if (err)
		goto err_msg;
	err = shm_init_ns(ns);
	if (err)
		goto err_shm;


	kref_init(&ns->kref);
	kref_init(&ns->kref);
	return ns;
	return ns;

err_shm:
	msg_exit_ns(ns);
err_msg:
	sem_exit_ns(ns);
err_sem:
	kfree(ns);
err_mem:
	return ERR_PTR(err);
}
}


struct ipc_namespace *copy_ipcs(unsigned long flags, struct ipc_namespace *ns)
struct ipc_namespace *copy_ipcs(unsigned long flags, struct ipc_namespace *ns)
+4 −22
Original line number Original line Diff line number Diff line
@@ -87,14 +87,12 @@
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include "util.h"
#include "util.h"


#define sem_ids(ns)	(*((ns)->ids[IPC_SEM_IDS]))
#define sem_ids(ns)	((ns)->ids[IPC_SEM_IDS])


#define sem_unlock(sma)		ipc_unlock(&(sma)->sem_perm)
#define sem_unlock(sma)		ipc_unlock(&(sma)->sem_perm)
#define sem_checkid(sma, semid)	ipc_checkid(&sma->sem_perm, semid)
#define sem_checkid(sma, semid)	ipc_checkid(&sma->sem_perm, semid)
#define sem_buildid(id, seq)	ipc_buildid(id, seq)
#define sem_buildid(id, seq)	ipc_buildid(id, seq)


static struct ipc_ids init_sem_ids;

static int newary(struct ipc_namespace *, struct ipc_params *);
static int newary(struct ipc_namespace *, struct ipc_params *);
static void freeary(struct ipc_namespace *, struct sem_array *);
static void freeary(struct ipc_namespace *, struct sem_array *);
#ifdef CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
@@ -118,30 +116,17 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
#define sc_semopm	sem_ctls[2]
#define sc_semopm	sem_ctls[2]
#define sc_semmni	sem_ctls[3]
#define sc_semmni	sem_ctls[3]


static void __sem_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
void sem_init_ns(struct ipc_namespace *ns)
{
{
	ns->ids[IPC_SEM_IDS] = ids;
	ns->sc_semmsl = SEMMSL;
	ns->sc_semmsl = SEMMSL;
	ns->sc_semmns = SEMMNS;
	ns->sc_semmns = SEMMNS;
	ns->sc_semopm = SEMOPM;
	ns->sc_semopm = SEMOPM;
	ns->sc_semmni = SEMMNI;
	ns->sc_semmni = SEMMNI;
	ns->used_sems = 0;
	ns->used_sems = 0;
	ipc_init_ids(ids);
	ipc_init_ids(&ns->ids[IPC_SEM_IDS]);
}
}


#ifdef CONFIG_IPC_NS
#ifdef CONFIG_IPC_NS
int sem_init_ns(struct ipc_namespace *ns)
{
	struct ipc_ids *ids;

	ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
	if (ids == NULL)
		return -ENOMEM;

	__sem_init_ns(ns, ids);
	return 0;
}

void sem_exit_ns(struct ipc_namespace *ns)
void sem_exit_ns(struct ipc_namespace *ns)
{
{
	struct sem_array *sma;
	struct sem_array *sma;
@@ -163,15 +148,12 @@ void sem_exit_ns(struct ipc_namespace *ns)
		total++;
		total++;
	}
	}
	up_write(&sem_ids(ns).rw_mutex);
	up_write(&sem_ids(ns).rw_mutex);

	kfree(ns->ids[IPC_SEM_IDS]);
	ns->ids[IPC_SEM_IDS] = NULL;
}
}
#endif
#endif


void __init sem_init (void)
void __init sem_init (void)
{
{
	__sem_init_ns(&init_ipc_ns, &init_sem_ids);
	sem_init_ns(&init_ipc_ns);
	ipc_init_proc_interface("sysvipc/sem",
	ipc_init_proc_interface("sysvipc/sem",
				"       key      semid perms      nsems   uid   gid  cuid  cgid      otime      ctime\n",
				"       key      semid perms      nsems   uid   gid  cuid  cgid      otime      ctime\n",
				IPC_SEM_IDS, sysvipc_sem_proc_show);
				IPC_SEM_IDS, sysvipc_sem_proc_show);
+4 −22
Original line number Original line Diff line number Diff line
@@ -56,9 +56,7 @@ struct shm_file_data {
static const struct file_operations shm_file_operations;
static const struct file_operations shm_file_operations;
static struct vm_operations_struct shm_vm_ops;
static struct vm_operations_struct shm_vm_ops;


static struct ipc_ids init_shm_ids;
#define shm_ids(ns)	((ns)->ids[IPC_SHM_IDS])

#define shm_ids(ns)	(*((ns)->ids[IPC_SHM_IDS]))


#define shm_unlock(shp)			\
#define shm_unlock(shp)			\
	ipc_unlock(&(shp)->shm_perm)
	ipc_unlock(&(shp)->shm_perm)
@@ -72,14 +70,13 @@ static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp);
static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
#endif
#endif


static void __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
void shm_init_ns(struct ipc_namespace *ns)
{
{
	ns->ids[IPC_SHM_IDS] = ids;
	ns->shm_ctlmax = SHMMAX;
	ns->shm_ctlmax = SHMMAX;
	ns->shm_ctlall = SHMALL;
	ns->shm_ctlall = SHMALL;
	ns->shm_ctlmni = SHMMNI;
	ns->shm_ctlmni = SHMMNI;
	ns->shm_tot = 0;
	ns->shm_tot = 0;
	ipc_init_ids(ids);
	ipc_init_ids(&ns->ids[IPC_SHM_IDS]);
}
}


/*
/*
@@ -98,18 +95,6 @@ static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
}
}


#ifdef CONFIG_IPC_NS
#ifdef CONFIG_IPC_NS
int shm_init_ns(struct ipc_namespace *ns)
{
	struct ipc_ids *ids;

	ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
	if (ids == NULL)
		return -ENOMEM;

	__shm_init_ns(ns, ids);
	return 0;
}

void shm_exit_ns(struct ipc_namespace *ns)
void shm_exit_ns(struct ipc_namespace *ns)
{
{
	struct shmid_kernel *shp;
	struct shmid_kernel *shp;
@@ -131,15 +116,12 @@ void shm_exit_ns(struct ipc_namespace *ns)
		total++;
		total++;
	}
	}
	up_write(&shm_ids(ns).rw_mutex);
	up_write(&shm_ids(ns).rw_mutex);

	kfree(ns->ids[IPC_SHM_IDS]);
	ns->ids[IPC_SHM_IDS] = NULL;
}
}
#endif
#endif


void __init shm_init (void)
void __init shm_init (void)
{
{
	__shm_init_ns(&init_ipc_ns, &init_shm_ids);
	shm_init_ns(&init_ipc_ns);
	ipc_init_proc_interface("sysvipc/shm",
	ipc_init_proc_interface("sysvipc/shm",
				"       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime\n",
				"       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime\n",
				IPC_SHM_IDS, sysvipc_shm_proc_show);
				IPC_SHM_IDS, sysvipc_shm_proc_show);
Loading