-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[NETNS]: The generic per-net pointers.
Add the elastic array of void * pointer to the struct net.
The access rules are simple:
1. register the ops with register_pernet_gen_device to get
the id of your private pointer
2. call net_assign_generic() to put the private data on the
struct net (most preferably this should be done in the
->init callback of the ops registered)
3. do not store any private reference on the net_generic array;
4. do not change this pointer while the net is alive;
5. use the net_generic() to get the pointer.
When adding a new pointer, I copy the old array, replace it
with a new one and schedule the old for kfree after an RCU
grace period.
Since the net_generic explores the net->gen array inside rcu
read section and once set the net->gen->ptr[x] pointer never
changes, this grants us a safe access to generic pointers.
Quoting Paul: "... RCU is protecting -only- the net_generic
structure that net_generic() is traversing, and the [pointer]
returned by net_generic() is protected by a reference counter
in the upper-level struct net."
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>- Loading branch information
Pavel Emelyanov
authored and
David S. Miller
committed
Apr 15, 2008
1 parent
c93cf61
commit dec827d
Showing
3 changed files
with
113 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| /* | ||
| * generic net pointers | ||
| */ | ||
|
|
||
| #ifndef __NET_GENERIC_H__ | ||
| #define __NET_GENERIC_H__ | ||
|
|
||
| #include <linux/rcupdate.h> | ||
|
|
||
| /* | ||
| * Generic net pointers are to be used by modules to put some private | ||
| * stuff on the struct net without explicit struct net modification | ||
| * | ||
| * The rules are simple: | ||
| * 1. register the ops with register_pernet_gen_device to get the id | ||
| * of your private pointer; | ||
| * 2. call net_assign_generic() to put the private data on the struct | ||
| * net (most preferably this should be done in the ->init callback | ||
| * of the ops registered); | ||
| * 3. do not change this pointer while the net is alive; | ||
| * 4. do not try to have any private reference on the net_generic object. | ||
| * | ||
| * After accomplishing all of the above, the private pointer can be | ||
| * accessed with the net_generic() call. | ||
| */ | ||
|
|
||
| struct net_generic { | ||
| unsigned int len; | ||
| struct rcu_head rcu; | ||
|
|
||
| void *ptr[0]; | ||
| }; | ||
|
|
||
| static inline void *net_generic(struct net *net, int id) | ||
| { | ||
| struct net_generic *ng; | ||
| void *ptr; | ||
|
|
||
| rcu_read_lock(); | ||
| ng = rcu_dereference(net->gen); | ||
| BUG_ON(id == 0 || id > ng->len); | ||
| ptr = ng->ptr[id - 1]; | ||
| rcu_read_unlock(); | ||
|
|
||
| return ptr; | ||
| } | ||
|
|
||
| extern int net_assign_generic(struct net *net, int id, void *data); | ||
| #endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters