2 * Inter process networking (virtual distributed ethernet) module
3 * management of ipn_msgbuf (one slab for each MTU)
4 * (part of the View-OS project: wiki.virtualsquare.org)
6 * N.B. all these functions need global locking! (ipn_glob_lock)
8 * Copyright (C) 2007 Renzo Davoli (renzo@cs.unibo.it)
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * Due to this file being licensed under the GPL there is controversy over
16 * whether this permits you to write a module that #includes this file
17 * without placing your module under the GPL. Please consult a lawyer for
18 * advice before doing this.
20 * WARNING: THIS CODE IS ALREADY EXPERIMENTAL
24 #include <linux/init.h>
25 #include <linux/module.h>
28 #include "ipn_netdev.h"
31 struct list_head list
;
35 struct kmem_cache
*cache
;
38 static LIST_HEAD(ipn_msgbufh
);
39 static struct kmem_cache
*ipn_msgbuf_cache
;
41 /* get a kmem_cache pointer for a given mtu.
42 * it is a cache for struct msgpool_item elements (the latter field of
43 * the struct, i.e. the payload, has variable length depending on the mtu)
44 * if it exists already a cache with the given mtu, ipn_msgbuf_get creates
45 * one more reference for that cache, otherwise a new one is created.
47 struct kmem_cache
*ipn_msgbuf_get(int mtu
)
49 struct ipn_msgbuf
*ipn_msgbuf
;
50 list_for_each_entry(ipn_msgbuf
, &ipn_msgbufh
, list
) {
51 if (mtu
== ipn_msgbuf
->mtu
) {
53 return ipn_msgbuf
->cache
;
56 ipn_msgbuf
=kmem_cache_alloc(ipn_msgbuf_cache
,GFP_KERNEL
);
57 if (ipn_msgbuf
== NULL
)
62 snprintf(ipn_msgbuf
->cachename
,12,"ipn%d",mtu
);
63 ipn_msgbuf
->cache
=kmem_cache_create(ipn_msgbuf
->cachename
,sizeof(struct msgpool_item
)+mtu
,0,0,NULL
);
64 list_add_tail(&ipn_msgbuf
->list
,&ipn_msgbufh
);
65 return ipn_msgbuf
->cache
;
69 /* release a reference of a msgbuf cache (a network with a given mtu
71 * the last reference for a given mtu releases the slub*/
72 void ipn_msgbuf_put(struct kmem_cache
*cache
)
74 struct ipn_msgbuf
*ipn_msgbuf
;
75 list_for_each_entry(ipn_msgbuf
, &ipn_msgbufh
, list
) {
76 if (ipn_msgbuf
->cache
== cache
) {
78 if (ipn_msgbuf
->refcnt
== 0) {
79 kmem_cache_destroy(ipn_msgbuf
->cache
);
80 list_del(&ipn_msgbuf
->list
);
81 kmem_cache_free(ipn_msgbuf_cache
,ipn_msgbuf
);
88 int ipn_msgbuf_init(void)
90 ipn_msgbuf_cache
=kmem_cache_create("ipn_msgbuf",sizeof(struct ipn_msgbuf
),0,0,NULL
);
91 if (!ipn_msgbuf_cache
)
97 void ipn_msgbuf_fini(void)
99 if (ipn_msgbuf_cache
) {
100 while (!list_empty(&ipn_msgbufh
)) {
101 struct ipn_msgbuf
*ipn_msgbuf
=list_first_entry(&ipn_msgbufh
, struct ipn_msgbuf
, list
);
102 list_del(&ipn_msgbuf
->list
);
103 kmem_cache_destroy(ipn_msgbuf
->cache
);
104 kmem_cache_free(ipn_msgbuf_cache
,ipn_msgbuf
);
106 kmem_cache_destroy(ipn_msgbuf_cache
);