// SPDX-License-Identifier: GPL-2.0
/*
 * CMA SysFS Interface
 *
 * Copyright (c) 2021 Minchan Kim <minchan@kernel.org>
 */

#include <linux/cma.h>
#include <linux/kernel.h>
#include <linux/slab.h>

#include "cma.h"

#define CMA_ATTR_RO(_name) \
	static struct kobj_attribute _name##_attr = __ATTR_RO(_name)

void cma_sysfs_account_success_pages(struct cma *cma, unsigned long nr_pages)
{
	atomic64_add(nr_pages, &cma->nr_pages_succeeded);
}

void cma_sysfs_account_fail_pages(struct cma *cma, unsigned long nr_pages)
{
	atomic64_add(nr_pages, &cma->nr_pages_failed);
}

void cma_sysfs_account_release_pages(struct cma *cma, unsigned long nr_pages)
{
	atomic64_add(nr_pages, &cma->nr_pages_released);
}

static inline struct cma *cma_from_kobj(struct kobject *kobj)
{
	return container_of(kobj, struct cma_kobject, kobj)->cma;
}

static ssize_t alloc_pages_success_show(struct kobject *kobj,
					struct kobj_attribute *attr, char *buf)
{
	struct cma *cma = cma_from_kobj(kobj);

	return sysfs_emit(buf, "%llu\n",
			  atomic64_read(&cma->nr_pages_succeeded));
}
CMA_ATTR_RO(alloc_pages_success);

static ssize_t alloc_pages_fail_show(struct kobject *kobj,
				     struct kobj_attribute *attr, char *buf)
{
	struct cma *cma = cma_from_kobj(kobj);

	return sysfs_emit(buf, "%llu\n", atomic64_read(&cma->nr_pages_failed));
}
CMA_ATTR_RO(alloc_pages_fail);

static ssize_t release_pages_success_show(struct kobject *kobj,
					  struct kobj_attribute *attr, char *buf)
{
	struct cma *cma = cma_from_kobj(kobj);

	return sysfs_emit(buf, "%llu\n", atomic64_read(&cma->nr_pages_released));
}
CMA_ATTR_RO(release_pages_success);

static ssize_t total_pages_show(struct kobject *kobj,
					  struct kobj_attribute *attr, char *buf)
{
	struct cma *cma = cma_from_kobj(kobj);

	return sysfs_emit(buf, "%lu\n", cma->count);
}
CMA_ATTR_RO(total_pages);

static ssize_t available_pages_show(struct kobject *kobj,
					  struct kobj_attribute *attr, char *buf)
{
	struct cma *cma = cma_from_kobj(kobj);

	return sysfs_emit(buf, "%lu\n", cma->available_count);
}
CMA_ATTR_RO(available_pages);

static void cma_kobj_release(struct kobject *kobj)
{
	struct cma *cma = cma_from_kobj(kobj);
	struct cma_kobject *cma_kobj = cma->cma_kobj;

	kfree(cma_kobj);
	cma->cma_kobj = NULL;
}

static struct attribute *cma_attrs[] = {
	&alloc_pages_success_attr.attr,
	&alloc_pages_fail_attr.attr,
	&release_pages_success_attr.attr,
	&total_pages_attr.attr,
	&available_pages_attr.attr,
	NULL,
};
ATTRIBUTE_GROUPS(cma);

static const struct kobj_type cma_ktype = {
	.release = cma_kobj_release,
	.sysfs_ops = &kobj_sysfs_ops,
	.default_groups = cma_groups,
};

static int __init cma_sysfs_init(void)
{
	struct kobject *cma_kobj_root;
	struct cma_kobject *cma_kobj;
	struct cma *cma;
	int i, err;

	cma_kobj_root = kobject_create_and_add("cma", mm_kobj);
	if (!cma_kobj_root)
		return -ENOMEM;

	for (i = 0; i < cma_area_count; i++) {
		cma = &cma_areas[i];
		if (!test_bit(CMA_ACTIVATED, &cma->flags))
			continue;

		cma_kobj = kzalloc_obj(*cma_kobj);
		if (!cma_kobj) {
			err = -ENOMEM;
			goto out;
		}

		cma->cma_kobj = cma_kobj;
		cma_kobj->cma = cma;
		err = kobject_init_and_add(&cma_kobj->kobj, &cma_ktype,
					   cma_kobj_root, "%s", cma->name);
		if (err) {
			kobject_put(&cma_kobj->kobj);
			goto out;
		}
	}

	return 0;
out:
	while (--i >= 0) {
		cma = &cma_areas[i];
		if (cma->cma_kobj)
			kobject_put(&cma->cma_kobj->kobj);
	}
	kobject_put(cma_kobj_root);

	return err;
}
subsys_initcall(cma_sysfs_init);
