xref: /openbmc/linux/mm/cma_sysfs.c (revision a4a4659d)
143ca106fSMinchan Kim // SPDX-License-Identifier: GPL-2.0
243ca106fSMinchan Kim /*
343ca106fSMinchan Kim  * CMA SysFS Interface
443ca106fSMinchan Kim  *
543ca106fSMinchan Kim  * Copyright (c) 2021 Minchan Kim <minchan@kernel.org>
643ca106fSMinchan Kim  */
743ca106fSMinchan Kim 
843ca106fSMinchan Kim #include <linux/cma.h>
943ca106fSMinchan Kim #include <linux/kernel.h>
1043ca106fSMinchan Kim #include <linux/slab.h>
1143ca106fSMinchan Kim 
1243ca106fSMinchan Kim #include "cma.h"
1343ca106fSMinchan Kim 
1443ca106fSMinchan Kim #define CMA_ATTR_RO(_name) \
1543ca106fSMinchan Kim 	static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
1643ca106fSMinchan Kim 
cma_sysfs_account_success_pages(struct cma * cma,unsigned long nr_pages)1743ca106fSMinchan Kim void cma_sysfs_account_success_pages(struct cma *cma, unsigned long nr_pages)
1843ca106fSMinchan Kim {
1943ca106fSMinchan Kim 	atomic64_add(nr_pages, &cma->nr_pages_succeeded);
2043ca106fSMinchan Kim }
2143ca106fSMinchan Kim 
cma_sysfs_account_fail_pages(struct cma * cma,unsigned long nr_pages)2243ca106fSMinchan Kim void cma_sysfs_account_fail_pages(struct cma *cma, unsigned long nr_pages)
2343ca106fSMinchan Kim {
2443ca106fSMinchan Kim 	atomic64_add(nr_pages, &cma->nr_pages_failed);
2543ca106fSMinchan Kim }
2643ca106fSMinchan Kim 
cma_from_kobj(struct kobject * kobj)2743ca106fSMinchan Kim static inline struct cma *cma_from_kobj(struct kobject *kobj)
2843ca106fSMinchan Kim {
2943ca106fSMinchan Kim 	return container_of(kobj, struct cma_kobject, kobj)->cma;
3043ca106fSMinchan Kim }
3143ca106fSMinchan Kim 
alloc_pages_success_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)3243ca106fSMinchan Kim static ssize_t alloc_pages_success_show(struct kobject *kobj,
3343ca106fSMinchan Kim 					struct kobj_attribute *attr, char *buf)
3443ca106fSMinchan Kim {
3543ca106fSMinchan Kim 	struct cma *cma = cma_from_kobj(kobj);
3643ca106fSMinchan Kim 
3743ca106fSMinchan Kim 	return sysfs_emit(buf, "%llu\n",
3843ca106fSMinchan Kim 			  atomic64_read(&cma->nr_pages_succeeded));
3943ca106fSMinchan Kim }
4043ca106fSMinchan Kim CMA_ATTR_RO(alloc_pages_success);
4143ca106fSMinchan Kim 
alloc_pages_fail_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)4243ca106fSMinchan Kim static ssize_t alloc_pages_fail_show(struct kobject *kobj,
4343ca106fSMinchan Kim 				     struct kobj_attribute *attr, char *buf)
4443ca106fSMinchan Kim {
4543ca106fSMinchan Kim 	struct cma *cma = cma_from_kobj(kobj);
4643ca106fSMinchan Kim 
4743ca106fSMinchan Kim 	return sysfs_emit(buf, "%llu\n", atomic64_read(&cma->nr_pages_failed));
4843ca106fSMinchan Kim }
4943ca106fSMinchan Kim CMA_ATTR_RO(alloc_pages_fail);
5043ca106fSMinchan Kim 
cma_kobj_release(struct kobject * kobj)5143ca106fSMinchan Kim static void cma_kobj_release(struct kobject *kobj)
5243ca106fSMinchan Kim {
5343ca106fSMinchan Kim 	struct cma *cma = cma_from_kobj(kobj);
5443ca106fSMinchan Kim 	struct cma_kobject *cma_kobj = cma->cma_kobj;
5543ca106fSMinchan Kim 
5643ca106fSMinchan Kim 	kfree(cma_kobj);
5743ca106fSMinchan Kim 	cma->cma_kobj = NULL;
5843ca106fSMinchan Kim }
5943ca106fSMinchan Kim 
6043ca106fSMinchan Kim static struct attribute *cma_attrs[] = {
6143ca106fSMinchan Kim 	&alloc_pages_success_attr.attr,
6243ca106fSMinchan Kim 	&alloc_pages_fail_attr.attr,
6343ca106fSMinchan Kim 	NULL,
6443ca106fSMinchan Kim };
6543ca106fSMinchan Kim ATTRIBUTE_GROUPS(cma);
6643ca106fSMinchan Kim 
67*a4a4659dSThomas Weißschuh static const struct kobj_type cma_ktype = {
6843ca106fSMinchan Kim 	.release = cma_kobj_release,
6943ca106fSMinchan Kim 	.sysfs_ops = &kobj_sysfs_ops,
7043ca106fSMinchan Kim 	.default_groups = cma_groups,
7143ca106fSMinchan Kim };
7243ca106fSMinchan Kim 
cma_sysfs_init(void)7343ca106fSMinchan Kim static int __init cma_sysfs_init(void)
7443ca106fSMinchan Kim {
7543ca106fSMinchan Kim 	struct kobject *cma_kobj_root;
7643ca106fSMinchan Kim 	struct cma_kobject *cma_kobj;
7743ca106fSMinchan Kim 	struct cma *cma;
7843ca106fSMinchan Kim 	int i, err;
7943ca106fSMinchan Kim 
8043ca106fSMinchan Kim 	cma_kobj_root = kobject_create_and_add("cma", mm_kobj);
8143ca106fSMinchan Kim 	if (!cma_kobj_root)
8243ca106fSMinchan Kim 		return -ENOMEM;
8343ca106fSMinchan Kim 
8443ca106fSMinchan Kim 	for (i = 0; i < cma_area_count; i++) {
8543ca106fSMinchan Kim 		cma_kobj = kzalloc(sizeof(*cma_kobj), GFP_KERNEL);
8643ca106fSMinchan Kim 		if (!cma_kobj) {
8743ca106fSMinchan Kim 			err = -ENOMEM;
8843ca106fSMinchan Kim 			goto out;
8943ca106fSMinchan Kim 		}
9043ca106fSMinchan Kim 
9143ca106fSMinchan Kim 		cma = &cma_areas[i];
9243ca106fSMinchan Kim 		cma->cma_kobj = cma_kobj;
9343ca106fSMinchan Kim 		cma_kobj->cma = cma;
9443ca106fSMinchan Kim 		err = kobject_init_and_add(&cma_kobj->kobj, &cma_ktype,
9543ca106fSMinchan Kim 					   cma_kobj_root, "%s", cma->name);
9643ca106fSMinchan Kim 		if (err) {
9743ca106fSMinchan Kim 			kobject_put(&cma_kobj->kobj);
9843ca106fSMinchan Kim 			goto out;
9943ca106fSMinchan Kim 		}
10043ca106fSMinchan Kim 	}
10143ca106fSMinchan Kim 
10243ca106fSMinchan Kim 	return 0;
10343ca106fSMinchan Kim out:
10443ca106fSMinchan Kim 	while (--i >= 0) {
10543ca106fSMinchan Kim 		cma = &cma_areas[i];
10643ca106fSMinchan Kim 		kobject_put(&cma->cma_kobj->kobj);
10743ca106fSMinchan Kim 	}
10843ca106fSMinchan Kim 	kobject_put(cma_kobj_root);
10943ca106fSMinchan Kim 
11043ca106fSMinchan Kim 	return err;
11143ca106fSMinchan Kim }
11243ca106fSMinchan Kim subsys_initcall(cma_sysfs_init);
113