Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * CMA SysFS Interface
  4 *
  5 * Copyright (c) 2021 Minchan Kim <minchan@kernel.org>
  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
 17void cma_sysfs_account_success_pages(struct cma *cma, unsigned long nr_pages)
 18{
 19	atomic64_add(nr_pages, &cma->nr_pages_succeeded);
 20}
 21
 22void cma_sysfs_account_fail_pages(struct cma *cma, unsigned long nr_pages)
 23{
 24	atomic64_add(nr_pages, &cma->nr_pages_failed);
 25}
 26
 27static inline struct cma *cma_from_kobj(struct kobject *kobj)
 28{
 29	return container_of(kobj, struct cma_kobject, kobj)->cma;
 30}
 31
 32static ssize_t alloc_pages_success_show(struct kobject *kobj,
 33					struct kobj_attribute *attr, char *buf)
 34{
 35	struct cma *cma = cma_from_kobj(kobj);
 36
 37	return sysfs_emit(buf, "%llu\n",
 38			  atomic64_read(&cma->nr_pages_succeeded));
 39}
 40CMA_ATTR_RO(alloc_pages_success);
 41
 42static ssize_t alloc_pages_fail_show(struct kobject *kobj,
 43				     struct kobj_attribute *attr, char *buf)
 44{
 45	struct cma *cma = cma_from_kobj(kobj);
 46
 47	return sysfs_emit(buf, "%llu\n", atomic64_read(&cma->nr_pages_failed));
 48}
 49CMA_ATTR_RO(alloc_pages_fail);
 50
 51static void cma_kobj_release(struct kobject *kobj)
 52{
 53	struct cma *cma = cma_from_kobj(kobj);
 54	struct cma_kobject *cma_kobj = cma->cma_kobj;
 55
 56	kfree(cma_kobj);
 57	cma->cma_kobj = NULL;
 58}
 59
 60static struct attribute *cma_attrs[] = {
 61	&alloc_pages_success_attr.attr,
 62	&alloc_pages_fail_attr.attr,
 63	NULL,
 64};
 65ATTRIBUTE_GROUPS(cma);
 66
 67static struct kobj_type cma_ktype = {
 68	.release = cma_kobj_release,
 69	.sysfs_ops = &kobj_sysfs_ops,
 70	.default_groups = cma_groups,
 71};
 72
 73static int __init cma_sysfs_init(void)
 74{
 75	struct kobject *cma_kobj_root;
 76	struct cma_kobject *cma_kobj;
 77	struct cma *cma;
 78	int i, err;
 79
 80	cma_kobj_root = kobject_create_and_add("cma", mm_kobj);
 81	if (!cma_kobj_root)
 82		return -ENOMEM;
 83
 84	for (i = 0; i < cma_area_count; i++) {
 85		cma_kobj = kzalloc(sizeof(*cma_kobj), GFP_KERNEL);
 86		if (!cma_kobj) {
 87			err = -ENOMEM;
 88			goto out;
 89		}
 90
 91		cma = &cma_areas[i];
 92		cma->cma_kobj = cma_kobj;
 93		cma_kobj->cma = cma;
 94		err = kobject_init_and_add(&cma_kobj->kobj, &cma_ktype,
 95					   cma_kobj_root, "%s", cma->name);
 96		if (err) {
 97			kobject_put(&cma_kobj->kobj);
 98			goto out;
 99		}
100	}
101
102	return 0;
103out:
104	while (--i >= 0) {
105		cma = &cma_areas[i];
106		kobject_put(&cma->cma_kobj->kobj);
107	}
108	kobject_put(cma_kobj_root);
109
110	return err;
111}
112subsys_initcall(cma_sysfs_init);