diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h index cfb2a08b28f5..c3b1da9e5feb 100644 --- a/include/linux/ipc_namespace.h +++ b/include/linux/ipc_namespace.h @@ -4,14 +4,14 @@ #include #include #include -#ifdef CONFIG_MEMORY_HOTPLUG #include -#endif /* CONFIG_MEMORY_HOTPLUG */ /* * ipc namespace events */ #define IPCNS_MEMCHANGED 0x00000001 /* Notify lowmem size changed */ +#define IPCNS_CREATED 0x00000002 /* Notify new ipc namespace created */ +#define IPCNS_REMOVED 0x00000003 /* Notify ipc namespace removed */ #define IPCNS_CALLBACK_PRI 0 @@ -42,9 +42,7 @@ struct ipc_namespace { int shm_ctlmni; int shm_tot; -#ifdef CONFIG_MEMORY_HOTPLUG struct notifier_block ipcns_nb; -#endif }; extern struct ipc_namespace init_ipc_ns; @@ -53,29 +51,10 @@ extern atomic_t nr_ipc_ns; #ifdef CONFIG_SYSVIPC #define INIT_IPC_NS(ns) .ns = &init_ipc_ns, -#ifdef CONFIG_MEMORY_HOTPLUG - extern int register_ipcns_notifier(struct ipc_namespace *); extern int unregister_ipcns_notifier(struct ipc_namespace *); extern int ipcns_notify(unsigned long); -#else /* CONFIG_MEMORY_HOTPLUG */ - -static inline int register_ipcns_notifier(struct ipc_namespace *ipcns) -{ - return 0; -} -static inline int unregister_ipcns_notifier(struct ipc_namespace *ipcns) -{ - return 0; -} -static inline int ipcns_notify(unsigned long ev) -{ - return 0; -} - -#endif /* CONFIG_MEMORY_HOTPLUG */ - #else /* CONFIG_SYSVIPC */ #define INIT_IPC_NS(ns) #endif /* CONFIG_SYSVIPC */ diff --git a/ipc/Makefile b/ipc/Makefile index 388e4d259f02..65c384395801 100644 --- a/ipc/Makefile +++ b/ipc/Makefile @@ -3,8 +3,7 @@ # obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o -obj_mem-$(CONFIG_MEMORY_HOTPLUG) += ipcns_notifier.o -obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o $(obj_mem-y) +obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o ipcns_notifier.o obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o obj_mq-$(CONFIG_COMPAT) += compat_mq.o obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y) diff --git a/ipc/ipcns_notifier.c b/ipc/ipcns_notifier.c index 0786af6ce3ec..c7974609defc 100644 --- a/ipc/ipcns_notifier.c +++ b/ipc/ipcns_notifier.c @@ -29,6 +29,8 @@ static int ipcns_callback(struct notifier_block *self, switch (action) { case IPCNS_MEMCHANGED: /* amount of lowmem has changed */ + case IPCNS_CREATED: + case IPCNS_REMOVED: /* * It's time to recompute msgmni */ diff --git a/ipc/namespace.c b/ipc/namespace.c index f7a35be2e771..9171d948751e 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -26,6 +26,12 @@ static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns) msg_init_ns(ns); shm_init_ns(ns); + /* + * msgmni has already been computed for the new ipc ns. + * Thus, do the ipcns creation notification before registering that + * new ipcns in the chain. + */ + ipcns_notify(IPCNS_CREATED); register_ipcns_notifier(ns); kref_init(&ns->kref); @@ -97,4 +103,10 @@ void free_ipc_ns(struct kref *kref) shm_exit_ns(ns); kfree(ns); atomic_dec(&nr_ipc_ns); + + /* + * Do the ipcns removal notification after decrementing nr_ipc_ns in + * order to have a correct value when recomputing msgmni. + */ + ipcns_notify(IPCNS_REMOVED); }