Commit | Line | Data |
---|---|---|
133ff0ea JG |
1 | /* |
2 | * Copyright 2013 Red Hat Inc. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
14 | * Authors: Jérôme Glisse <jglisse@redhat.com> | |
15 | */ | |
16 | /* | |
17 | * Refer to include/linux/hmm.h for information about heterogeneous memory | |
18 | * management or HMM for short. | |
19 | */ | |
20 | #include <linux/mm.h> | |
21 | #include <linux/hmm.h> | |
22 | #include <linux/slab.h> | |
23 | #include <linux/sched.h> | |
24 | ||
25 | ||
26 | #ifdef CONFIG_HMM | |
27 | /* | |
28 | * struct hmm - HMM per mm struct | |
29 | * | |
30 | * @mm: mm struct this HMM struct is bound to | |
31 | */ | |
32 | struct hmm { | |
33 | struct mm_struct *mm; | |
34 | }; | |
35 | ||
36 | /* | |
37 | * hmm_register - register HMM against an mm (HMM internal) | |
38 | * | |
39 | * @mm: mm struct to attach to | |
40 | * | |
41 | * This is not intended to be used directly by device drivers. It allocates an | |
42 | * HMM struct if mm does not have one, and initializes it. | |
43 | */ | |
44 | static struct hmm *hmm_register(struct mm_struct *mm) | |
45 | { | |
46 | if (!mm->hmm) { | |
47 | struct hmm *hmm = NULL; | |
48 | ||
49 | hmm = kmalloc(sizeof(*hmm), GFP_KERNEL); | |
50 | if (!hmm) | |
51 | return NULL; | |
52 | hmm->mm = mm; | |
53 | ||
54 | spin_lock(&mm->page_table_lock); | |
55 | if (!mm->hmm) | |
56 | mm->hmm = hmm; | |
57 | else | |
58 | kfree(hmm); | |
59 | spin_unlock(&mm->page_table_lock); | |
60 | } | |
61 | ||
62 | /* | |
63 | * The hmm struct can only be freed once the mm_struct goes away, | |
64 | * hence we should always have pre-allocated an new hmm struct | |
65 | * above. | |
66 | */ | |
67 | return mm->hmm; | |
68 | } | |
69 | ||
70 | void hmm_mm_destroy(struct mm_struct *mm) | |
71 | { | |
72 | kfree(mm->hmm); | |
73 | } | |
74 | #endif /* CONFIG_HMM */ |