diff options
author | Nadia Derbey <Nadia.Derbey@bull.net> | 2008-07-25 04:48:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-25 13:53:42 -0400 |
commit | 9eefe520c814f6f62c5d36a2ddcd3fb99dfdb30e (patch) | |
tree | 064ce99674f144b681f8d365d1e20d99c8078d0c /ipc/ipcns_notifier.c | |
parent | f1a43f93f0f3bab418800eaccb9e2e3b5427e173 (diff) |
ipc: do not use a negative value to re-enable msgmni automatic recomputing
This patch proposes an alternative to the "magical
positive-versus-negative number trick" Andrew complained about last week
in http://lkml.org/lkml/2008/6/24/418.
This had been introduced with the patches that scale msgmni to the amount
of lowmem. With these patches, msgmni has a registered notification
routine that recomputes msgmni value upon memory add/remove or ipc
namespace creation/ removal.
When msgmni is changed from user space (i.e. value written to the proc
file), that notification routine is unregistered, and the way to make it
registered back is to write a negative value into the proc file. This is
the "magical positive-versus-negative number trick".
To fix this, a new proc file is introduced: /proc/sys/kernel/auto_msgmni.
This file acts as ON/OFF for msgmni automatic recomputing.
With this patch, the process is the following:
1) kernel boots in "automatic recomputing mode"
/proc/sys/kernel/msgmni contains the value that has been computed (depends
on lowmem)
/proc/sys/kernel/automatic_msgmni contains "1"
2) echo <val> > /proc/sys/kernel/msgmni
. sets msg_ctlmni to <val>
. de-activates automatic recomputing (i.e. if, say, some memory is added
msgmni won't be recomputed anymore)
. /proc/sys/kernel/automatic_msgmni now contains "0"
3) echo "0" > /proc/sys/kernel/automatic_msgmni
. de-activates msgmni automatic recomputing
this has the same effect as 2) except that msg_ctlmni's value stays
blocked at its current value)
3) echo "1" > /proc/sys/kernel/automatic_msgmni
. recomputes msgmni's value based on the current available memory size
and number of ipc namespaces
. re-activates automatic recomputing for msgmni.
Signed-off-by: Nadia Derbey <Nadia.Derbey@bull.net>
Cc: Solofo Ramangalahy <Solofo.Ramangalahy@bull.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc/ipcns_notifier.c')
-rw-r--r-- | ipc/ipcns_notifier.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/ipc/ipcns_notifier.c b/ipc/ipcns_notifier.c index 70ff09183f7b..b9b31a4f77e1 100644 --- a/ipc/ipcns_notifier.c +++ b/ipc/ipcns_notifier.c | |||
@@ -55,25 +55,35 @@ static int ipcns_callback(struct notifier_block *self, | |||
55 | 55 | ||
56 | int register_ipcns_notifier(struct ipc_namespace *ns) | 56 | int register_ipcns_notifier(struct ipc_namespace *ns) |
57 | { | 57 | { |
58 | int rc; | ||
59 | |||
58 | memset(&ns->ipcns_nb, 0, sizeof(ns->ipcns_nb)); | 60 | memset(&ns->ipcns_nb, 0, sizeof(ns->ipcns_nb)); |
59 | ns->ipcns_nb.notifier_call = ipcns_callback; | 61 | ns->ipcns_nb.notifier_call = ipcns_callback; |
60 | ns->ipcns_nb.priority = IPCNS_CALLBACK_PRI; | 62 | ns->ipcns_nb.priority = IPCNS_CALLBACK_PRI; |
61 | return blocking_notifier_chain_register(&ipcns_chain, &ns->ipcns_nb); | 63 | rc = blocking_notifier_chain_register(&ipcns_chain, &ns->ipcns_nb); |
64 | if (!rc) | ||
65 | ns->auto_msgmni = 1; | ||
66 | return rc; | ||
62 | } | 67 | } |
63 | 68 | ||
64 | int cond_register_ipcns_notifier(struct ipc_namespace *ns) | 69 | int cond_register_ipcns_notifier(struct ipc_namespace *ns) |
65 | { | 70 | { |
71 | int rc; | ||
72 | |||
66 | memset(&ns->ipcns_nb, 0, sizeof(ns->ipcns_nb)); | 73 | memset(&ns->ipcns_nb, 0, sizeof(ns->ipcns_nb)); |
67 | ns->ipcns_nb.notifier_call = ipcns_callback; | 74 | ns->ipcns_nb.notifier_call = ipcns_callback; |
68 | ns->ipcns_nb.priority = IPCNS_CALLBACK_PRI; | 75 | ns->ipcns_nb.priority = IPCNS_CALLBACK_PRI; |
69 | return blocking_notifier_chain_cond_register(&ipcns_chain, | 76 | rc = blocking_notifier_chain_cond_register(&ipcns_chain, |
70 | &ns->ipcns_nb); | 77 | &ns->ipcns_nb); |
78 | if (!rc) | ||
79 | ns->auto_msgmni = 1; | ||
80 | return rc; | ||
71 | } | 81 | } |
72 | 82 | ||
73 | int unregister_ipcns_notifier(struct ipc_namespace *ns) | 83 | void unregister_ipcns_notifier(struct ipc_namespace *ns) |
74 | { | 84 | { |
75 | return blocking_notifier_chain_unregister(&ipcns_chain, | 85 | blocking_notifier_chain_unregister(&ipcns_chain, &ns->ipcns_nb); |
76 | &ns->ipcns_nb); | 86 | ns->auto_msgmni = 0; |
77 | } | 87 | } |
78 | 88 | ||
79 | int ipcns_notify(unsigned long val) | 89 | int ipcns_notify(unsigned long val) |