Make the syscall error detector a kernel header (XCC)
[akaros.git] / kern / include / refd_pages.h
1 /* Copyright (c) 2016 Google Inc.
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Helpers for reference counted pages, for use with Linux code.
6  *
7  * Some code wants to use reference counted pages.  I'd like to keep these
8  * uses separate from the main memory allocator.  Code that wants reference
9  * counted pages can use these helpers.
10  *
11  * Pass in memory allocated with get_cont_pages(). */
12
13 #pragma once
14
15 #include <kref.h>
16 #include <page_alloc.h>
17 #include <pmap.h>
18 #include <kmalloc.h>
19 #include <assert.h>
20
21 struct refd_pages {
22         void                    *rp_kva;
23         size_t                  rp_order;
24         struct kref             rp_kref;
25 };
26
27 static struct page *rp2page(struct refd_pages *rp)
28 {
29         return kva2page(rp->rp_kva);
30 }
31
32 static void refd_pages_release(struct kref *kref)
33 {
34         struct refd_pages *rp = container_of(kref, struct refd_pages, rp_kref);
35
36         free_cont_pages(rp->rp_kva, rp->rp_order);
37         kfree(rp);
38 }
39
40 static struct refd_pages *get_refd_pages(void *kva, size_t order)
41 {
42         struct refd_pages *rp;
43
44         if (!kva)
45                 return 0;
46         rp = kmalloc(sizeof(struct refd_pages), MEM_WAIT);
47         assert(rp);
48         rp->rp_kva = kva;
49         rp->rp_order = order;
50         kref_init(&rp->rp_kref, refd_pages_release, 1);
51         return rp;
52 }
53
54 static void refd_pages_decref(struct refd_pages *rp)
55 {
56         kref_put(&rp->rp_kref);
57 }