Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/ipc/ipcns_notifier.c
10814 views
1
/*
2
* linux/ipc/ipcns_notifier.c
3
* Copyright (C) 2007 BULL SA. Nadia Derbey
4
*
5
* Notification mechanism for ipc namespaces:
6
* The callback routine registered in the memory chain invokes the ipcns
7
* notifier chain with the IPCNS_MEMCHANGED event.
8
* Each callback routine registered in the ipcns namespace recomputes msgmni
9
* for the owning namespace.
10
*/
11
12
#include <linux/msg.h>
13
#include <linux/rcupdate.h>
14
#include <linux/notifier.h>
15
#include <linux/nsproxy.h>
16
#include <linux/ipc_namespace.h>
17
18
#include "util.h"
19
20
21
22
static BLOCKING_NOTIFIER_HEAD(ipcns_chain);
23
24
25
static int ipcns_callback(struct notifier_block *self,
26
unsigned long action, void *arg)
27
{
28
struct ipc_namespace *ns;
29
30
switch (action) {
31
case IPCNS_MEMCHANGED: /* amount of lowmem has changed */
32
case IPCNS_CREATED:
33
case IPCNS_REMOVED:
34
/*
35
* It's time to recompute msgmni
36
*/
37
ns = container_of(self, struct ipc_namespace, ipcns_nb);
38
/*
39
* No need to get a reference on the ns: the 1st job of
40
* free_ipc_ns() is to unregister the callback routine.
41
* blocking_notifier_chain_unregister takes the wr lock to do
42
* it.
43
* When this callback routine is called the rd lock is held by
44
* blocking_notifier_call_chain.
45
* So the ipc ns cannot be freed while we are here.
46
*/
47
recompute_msgmni(ns);
48
break;
49
default:
50
break;
51
}
52
53
return NOTIFY_OK;
54
}
55
56
int register_ipcns_notifier(struct ipc_namespace *ns)
57
{
58
int rc;
59
60
memset(&ns->ipcns_nb, 0, sizeof(ns->ipcns_nb));
61
ns->ipcns_nb.notifier_call = ipcns_callback;
62
ns->ipcns_nb.priority = IPCNS_CALLBACK_PRI;
63
rc = blocking_notifier_chain_register(&ipcns_chain, &ns->ipcns_nb);
64
if (!rc)
65
ns->auto_msgmni = 1;
66
return rc;
67
}
68
69
int cond_register_ipcns_notifier(struct ipc_namespace *ns)
70
{
71
int rc;
72
73
memset(&ns->ipcns_nb, 0, sizeof(ns->ipcns_nb));
74
ns->ipcns_nb.notifier_call = ipcns_callback;
75
ns->ipcns_nb.priority = IPCNS_CALLBACK_PRI;
76
rc = blocking_notifier_chain_cond_register(&ipcns_chain,
77
&ns->ipcns_nb);
78
if (!rc)
79
ns->auto_msgmni = 1;
80
return rc;
81
}
82
83
void unregister_ipcns_notifier(struct ipc_namespace *ns)
84
{
85
blocking_notifier_chain_unregister(&ipcns_chain, &ns->ipcns_nb);
86
ns->auto_msgmni = 0;
87
}
88
89
int ipcns_notify(unsigned long val)
90
{
91
return blocking_notifier_call_chain(&ipcns_chain, val, NULL);
92
}
93
94