Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/mm/cma_sysfs.c
26131 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* CMA SysFS Interface
4
*
5
* Copyright (c) 2021 Minchan Kim <[email protected]>
6
*/
7
8
#include <linux/cma.h>
9
#include <linux/kernel.h>
10
#include <linux/slab.h>
11
12
#include "cma.h"
13
14
#define CMA_ATTR_RO(_name) \
15
static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
16
17
void cma_sysfs_account_success_pages(struct cma *cma, unsigned long nr_pages)
18
{
19
atomic64_add(nr_pages, &cma->nr_pages_succeeded);
20
}
21
22
void cma_sysfs_account_fail_pages(struct cma *cma, unsigned long nr_pages)
23
{
24
atomic64_add(nr_pages, &cma->nr_pages_failed);
25
}
26
27
void cma_sysfs_account_release_pages(struct cma *cma, unsigned long nr_pages)
28
{
29
atomic64_add(nr_pages, &cma->nr_pages_released);
30
}
31
32
static inline struct cma *cma_from_kobj(struct kobject *kobj)
33
{
34
return container_of(kobj, struct cma_kobject, kobj)->cma;
35
}
36
37
static ssize_t alloc_pages_success_show(struct kobject *kobj,
38
struct kobj_attribute *attr, char *buf)
39
{
40
struct cma *cma = cma_from_kobj(kobj);
41
42
return sysfs_emit(buf, "%llu\n",
43
atomic64_read(&cma->nr_pages_succeeded));
44
}
45
CMA_ATTR_RO(alloc_pages_success);
46
47
static ssize_t alloc_pages_fail_show(struct kobject *kobj,
48
struct kobj_attribute *attr, char *buf)
49
{
50
struct cma *cma = cma_from_kobj(kobj);
51
52
return sysfs_emit(buf, "%llu\n", atomic64_read(&cma->nr_pages_failed));
53
}
54
CMA_ATTR_RO(alloc_pages_fail);
55
56
static ssize_t release_pages_success_show(struct kobject *kobj,
57
struct kobj_attribute *attr, char *buf)
58
{
59
struct cma *cma = cma_from_kobj(kobj);
60
61
return sysfs_emit(buf, "%llu\n", atomic64_read(&cma->nr_pages_released));
62
}
63
CMA_ATTR_RO(release_pages_success);
64
65
static ssize_t total_pages_show(struct kobject *kobj,
66
struct kobj_attribute *attr, char *buf)
67
{
68
struct cma *cma = cma_from_kobj(kobj);
69
70
return sysfs_emit(buf, "%lu\n", cma->count);
71
}
72
CMA_ATTR_RO(total_pages);
73
74
static ssize_t available_pages_show(struct kobject *kobj,
75
struct kobj_attribute *attr, char *buf)
76
{
77
struct cma *cma = cma_from_kobj(kobj);
78
79
return sysfs_emit(buf, "%lu\n", cma->available_count);
80
}
81
CMA_ATTR_RO(available_pages);
82
83
static void cma_kobj_release(struct kobject *kobj)
84
{
85
struct cma *cma = cma_from_kobj(kobj);
86
struct cma_kobject *cma_kobj = cma->cma_kobj;
87
88
kfree(cma_kobj);
89
cma->cma_kobj = NULL;
90
}
91
92
static struct attribute *cma_attrs[] = {
93
&alloc_pages_success_attr.attr,
94
&alloc_pages_fail_attr.attr,
95
&release_pages_success_attr.attr,
96
&total_pages_attr.attr,
97
&available_pages_attr.attr,
98
NULL,
99
};
100
ATTRIBUTE_GROUPS(cma);
101
102
static const struct kobj_type cma_ktype = {
103
.release = cma_kobj_release,
104
.sysfs_ops = &kobj_sysfs_ops,
105
.default_groups = cma_groups,
106
};
107
108
static int __init cma_sysfs_init(void)
109
{
110
struct kobject *cma_kobj_root;
111
struct cma_kobject *cma_kobj;
112
struct cma *cma;
113
int i, err;
114
115
cma_kobj_root = kobject_create_and_add("cma", mm_kobj);
116
if (!cma_kobj_root)
117
return -ENOMEM;
118
119
for (i = 0; i < cma_area_count; i++) {
120
cma_kobj = kzalloc(sizeof(*cma_kobj), GFP_KERNEL);
121
if (!cma_kobj) {
122
err = -ENOMEM;
123
goto out;
124
}
125
126
cma = &cma_areas[i];
127
cma->cma_kobj = cma_kobj;
128
cma_kobj->cma = cma;
129
err = kobject_init_and_add(&cma_kobj->kobj, &cma_ktype,
130
cma_kobj_root, "%s", cma->name);
131
if (err) {
132
kobject_put(&cma_kobj->kobj);
133
goto out;
134
}
135
}
136
137
return 0;
138
out:
139
while (--i >= 0) {
140
cma = &cma_areas[i];
141
kobject_put(&cma->cma_kobj->kobj);
142
}
143
kobject_put(cma_kobj_root);
144
145
return err;
146
}
147
subsys_initcall(cma_sysfs_init);
148
149