Each process that uses RPAL features is called an RPAL service. This patch adds the RPAL header file rpal.h and defines the rpal_service structure. The struct rpal_service uses a dedicated kmem_cache for allocation and deallocation, and atomic variables to maintain references to the struct rpal_service. Additionally, the patch introduces the rpal_get_service() and rpal_put_service() interfaces to manage reference counts. Signed-off-by: Bo Li <libo.gcs85@xxxxxxxxxxxxx> --- arch/x86/rpal/Makefile | 5 ++++ arch/x86/rpal/core.c | 32 +++++++++++++++++++++++ arch/x86/rpal/internal.h | 13 ++++++++++ arch/x86/rpal/service.c | 56 ++++++++++++++++++++++++++++++++++++++++ include/linux/rpal.h | 43 ++++++++++++++++++++++++++++++ 5 files changed, 149 insertions(+) create mode 100644 arch/x86/rpal/core.c create mode 100644 arch/x86/rpal/internal.h create mode 100644 arch/x86/rpal/service.c create mode 100644 include/linux/rpal.h diff --git a/arch/x86/rpal/Makefile b/arch/x86/rpal/Makefile index e69de29bb2d1..ee3698b5a9b3 100644 --- a/arch/x86/rpal/Makefile +++ b/arch/x86/rpal/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_RPAL) += rpal.o + +rpal-y := service.o core.o diff --git a/arch/x86/rpal/core.c b/arch/x86/rpal/core.c new file mode 100644 index 000000000000..495dbc1b1536 --- /dev/null +++ b/arch/x86/rpal/core.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * RPAL service level operations + * Copyright (c) 2025, ByteDance. All rights reserved. + * + * Author: Jiadong Sun <sunjiadong.lff@xxxxxxxxxxxxx> + */ + +#include <linux/rpal.h> + +#include "internal.h" + +int __init rpal_init(void); + +bool rpal_inited; + +int __init rpal_init(void) +{ + int ret = 0; + + ret = rpal_service_init(); + if (ret) + goto fail; + + rpal_inited = true; + return 0; + +fail: + rpal_err("rpal init fail\n"); + return -1; +} +subsys_initcall(rpal_init); diff --git a/arch/x86/rpal/internal.h b/arch/x86/rpal/internal.h new file mode 100644 index 000000000000..e44e6fc79677 --- /dev/null +++ b/arch/x86/rpal/internal.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * RPAL service level operations + * Copyright (c) 2025, ByteDance. All rights reserved. + * + * Author: Jiadong Sun <sunjiadong.lff@xxxxxxxxxxxxx> + */ + +extern bool rpal_inited; + +/* service.c */ +int __init rpal_service_init(void); +void __init rpal_service_exit(void); diff --git a/arch/x86/rpal/service.c b/arch/x86/rpal/service.c new file mode 100644 index 000000000000..c8e609798d4f --- /dev/null +++ b/arch/x86/rpal/service.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * RPAL service level operations + * Copyright (c) 2025, ByteDance. All rights reserved. + * + * Author: Jiadong Sun <sunjiadong.lff@xxxxxxxxxxxxx> + */ + +#include <linux/rpal.h> +#include <linux/sched/signal.h> +#include <linux/sched/task.h> +#include <linux/slab.h> + +#include "internal.h" + +static struct kmem_cache *service_cache; + +static void __rpal_put_service(struct rpal_service *rs) +{ + kmem_cache_free(service_cache, rs); +} + +struct rpal_service *rpal_get_service(struct rpal_service *rs) +{ + if (!rs) + return NULL; + atomic_inc(&rs->refcnt); + return rs; +} + +void rpal_put_service(struct rpal_service *rs) +{ + if (!rs) + return; + + if (atomic_dec_and_test(&rs->refcnt)) + __rpal_put_service(rs); +} + +int __init rpal_service_init(void) +{ + service_cache = kmem_cache_create("rpal_service_cache", + sizeof(struct rpal_service), 0, + SLAB_PANIC, NULL); + if (!service_cache) { + rpal_err("service init fail\n"); + return -1; + } + + return 0; +} + +void __init rpal_service_exit(void) +{ + kmem_cache_destroy(service_cache); +} diff --git a/include/linux/rpal.h b/include/linux/rpal.h new file mode 100644 index 000000000000..73468884cc5d --- /dev/null +++ b/include/linux/rpal.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * RPAL service level operations + * Copyright (c) 2025, ByteDance. All rights reserved. + * + * Author: Jiadong Sun <sunjiadong.lff@xxxxxxxxxxxxx> + */ + +#ifndef _LINUX_RPAL_H +#define _LINUX_RPAL_H + +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/atomic.h> + +#define RPAL_ERROR_MSG "rpal error: " +#define rpal_err(x...) pr_err(RPAL_ERROR_MSG x) +#define rpal_err_ratelimited(x...) pr_err_ratelimited(RPAL_ERROR_MSG x) + +struct rpal_service { + /* reference count of this struct */ + atomic_t refcnt; +}; + +/** + * @brief get new reference to a rpal service, a corresponding + * rpal_put_service() should be called later by the caller. + * + * @param rs The struct rpal_service to get. + * + * @return new reference of struct rpal_service. + */ +struct rpal_service *rpal_get_service(struct rpal_service *rs); + +/** + * @brief put a reference to a rpal service. If the reference count of + * the service turns to be 0, then release its struct rpal_service. + * rpal_put_service() may be used in an atomic context. + * + * @param rs The struct rpal_service to put. + */ +void rpal_put_service(struct rpal_service *rs); +#endif -- 2.20.1