linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v1 0/4] Machine Learning (ML) library in Linux kernel
@ 2026-02-06 19:11 Viacheslav Dubeyko
  2026-02-06 19:11 ` [RFC PATCH v1 1/4] ml-lib: Introduce Machine Learning (ML) library declarations Viacheslav Dubeyko
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Viacheslav Dubeyko @ 2026-02-06 19:11 UTC (permalink / raw)
  To: linux-fsdevel, linux-mm, bpf; +Cc: Slava.Dubeyko, slava, linux-kernel

Hello,

This patchset introduces initial vision of Machine Learning (ML) library
in Linux kernel. It is an effort to define the ML library API and
to elaborate the way of running ML models in Linux kernel.

Linux kernel is a huge code base with enormous number of subsystems and
possible configuration options. Complexity and changing nature of modern
workloads result in complexity of elaborating an efficient configuration
and state of running Linux kernel.

Machine Learning (ML) is approach/area of learning from data,
finding patterns, and making predictions without implementing algorithms
by developers. The number of areas of ML applications is growing
with every day. Generally speaking, ML can introduce a self-evolving and
self-learning capability in Linux kernel.  There are already research works
and industry efforts to employ ML approaches for configuration and
optimization the Linux kernel. However, introduction of ML approaches
in Linux kernel is not so simple and straightforward way. There are multiple
problems and unanswered questions on this road. First of all, any ML model
requires the floating-point operations (FPU) for running. But there is
no direct use of FPUs in kernel space. Also, ML model requires training phase
that can be a reason of significant performance degradation of Linux kernel.
Even inference phase could be problematic from the performance point of view
on kernel side. The using of ML approaches in Linux kernel is inevitable step.
But, how can we use ML approaches in Linux kernel? Which infrastructure
do we need to adopt ML models in Linux kernel?

What is the goal of using ML models in Linux kernel? The main goal is
to employ ML models for elaboration of a logic of particular Linux kernel
subsystem based on processing data or/and an efficient subsystem
configuration based on internal state of subsystem. As a result, it needs:
(1) collect data for training, (2) execute ML model training phase,
(3) test trained ML model, (4) use ML model for executing the inference phase.
The ML model inference can be used for recommendation of Linux kernel
subsystem configuration or/and for injecting a synthesized subsystem logic
into kernel space (for example, eBPF logic).

How ML infrastructure can be designed in Linux kernel? It needs to introduce
in Linux kernel a special ML library that can implement a generalized
interface of interaction between ML model’s thread in user-space and kernel
subsystem. Likewise interface requires to have the means:
(1) create/initialize/destroy ML model proxy in kernel subsystem,
(2) start/stop ML model proxy, (3) get/preprocess/publish data sets
from kernel space, (4) receive/preprocess/apply ML model recommendation(s)
from user-space, (5) execute synthesized logic/recommendations in kernel-space,
(6) estimate efficiency of synthesized logic/recommendations,
(7) execute error back-propagation with the goal of correction ML model
on user-space side.

The create and initialize logic can be executed by kernel subsystem during
module load or Linux kernel start (oppositely, module unload or kernel
shutdown will execute destroy of ML model proxy logic). ML model thread
in user-space will be capable to re-initialize and to execute
the start/stop logic of  ML model proxy on kernel side. First of all,
ML model needs to be trained by data from kernel space. The data can be
requested by ML model from user-space or data can be published by ML model
proxy from kernel-space. The sysfs interface can be used to orchestrate
this interaction. As a result, ML model in user-space should be capable
to extract data set(s) from kernel space through sysfs, FUSE or character
device. Extracted data can be stored in persistent storage and, finally,
ML model can be trained in user-space by accessing these data.

The continuous learning model can be adopted during training phase.
It implies that kernel subsystem can receive ML model recommendations
even during training phase. ML model proxy on kernel side can estimate
the current kernel subsystem state, tries to apply the ML model
recommendations, and estimate the efficiency of applied recommendations.
Generally speaking, ML model proxy on kernel side can consider several
modes of interaction with ML model recommendations: (1) emergency mode,
(2) learning mode, (3) collaboration mode, (4) recommendation mode.
The emergency mode is the mode when kernel subsystem is in critical state
and it is required to work as efficient as possible without capability of
involving the ML model recommendations (for example, ML model
recommendations are completely inadequate or load is very high).
The learning mode implies that kernel subsystem can try to apply
the ML model recommendations for some operations with the goal of
estimation the maturity of ML model. Also, ML model proxy can degrade
the mode to learning state if ML model recommendations becomes inefficient.
The collaboration mode has the goal of using ML recommendations in
50% of operations with the goal of achieving mature state of ML model.
And, finally, ML model proxy can convert kernel subsystem in recommendation
mode if ML model is mature enough and efficiency of applying
the ML recommendations is higher than using human-made algorithms.
The back-propagation approach can be used to correct the ML model
by means of sharing feedback of efficiency estimation from kernel
to user-space side.

[REFERENCES]
[1] https://lore.kernel.org/linux-fsdevel/20240605110219.7356-1-slava@dubeyko.com/
[2] https://www.youtube.com/watch?v=E7q0SKeniXU
[3] https://github.com/kernel-ml-lib/ml-lib
[4] https://github.com/kernel-ml-lib/ml-lib-linux

Viacheslav Dubeyko (4):
  ml-lib: Introduce Machine Learning (ML) library declarations
  ml-lib: Implement PoC of Machine Learning (ML) library functionality
  ml-lib: Implement simple testing character device driver
  ml-lib: Implement simple user-space testing application

 include/linux/ml-lib/ml_lib.h                 | 425 ++++++++++
 lib/Kconfig                                   |   6 +
 lib/Makefile                                  |   2 +
 lib/ml-lib/Kconfig                            |  18 +
 lib/ml-lib/Makefile                           |   7 +
 lib/ml-lib/ml_lib_main.c                      | 758 ++++++++++++++++++
 lib/ml-lib/sysfs.c                            | 187 +++++
 lib/ml-lib/sysfs.h                            |  17 +
 lib/ml-lib/test_driver/Kconfig                |  22 +
 lib/ml-lib/test_driver/Makefile               |   5 +
 lib/ml-lib/test_driver/README.md              | 233 ++++++
 lib/ml-lib/test_driver/ml_lib_char_dev.c      | 530 ++++++++++++
 .../test_application/ml_lib_char_dev_ioctl.h  |  21 +
 .../test_application/test_ml_lib_char_dev.c   | 206 +++++
 14 files changed, 2437 insertions(+)
 create mode 100644 include/linux/ml-lib/ml_lib.h
 create mode 100644 lib/ml-lib/Kconfig
 create mode 100644 lib/ml-lib/Makefile
 create mode 100644 lib/ml-lib/ml_lib_main.c
 create mode 100644 lib/ml-lib/sysfs.c
 create mode 100644 lib/ml-lib/sysfs.h
 create mode 100644 lib/ml-lib/test_driver/Kconfig
 create mode 100644 lib/ml-lib/test_driver/Makefile
 create mode 100644 lib/ml-lib/test_driver/README.md
 create mode 100644 lib/ml-lib/test_driver/ml_lib_char_dev.c
 create mode 100644 lib/ml-lib/test_driver/test_application/ml_lib_char_dev_ioctl.h
 create mode 100644 lib/ml-lib/test_driver/test_application/test_ml_lib_char_dev.c

-- 
2.34.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFC PATCH v1 1/4] ml-lib: Introduce Machine Learning (ML) library declarations
  2026-02-06 19:11 [RFC PATCH v1 0/4] Machine Learning (ML) library in Linux kernel Viacheslav Dubeyko
@ 2026-02-06 19:11 ` Viacheslav Dubeyko
  2026-02-07 15:52   ` Greg KH
  2026-02-06 19:11 ` [RFC PATCH v1 2/4] ml-lib: Implement PoC of Machine Learning (ML) library functionality Viacheslav Dubeyko
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Viacheslav Dubeyko @ 2026-02-06 19:11 UTC (permalink / raw)
  To: linux-fsdevel, linux-mm, bpf; +Cc: Slava.Dubeyko, slava, linux-kernel

Any kernel subsystem can be extended by one or several ML model(s).
ML model is represented by struct ml_lib_model that contains:
(1) ML model mode, (2) ML model state, (3) pointer on parent kernel
subsystem, (4) parent kernel subsystem state, (5) ML model options,
(6) current dataset, (7) ML model specialized operations,
(8) dataset specialized operations.

Any kernel subsystem can be in several modes that define
how this subsystem interacts with ML model in user-space:
(1) EMERGENCY_MODE - ignore ML model and run default algorithm(s),
(2) LEARNING_MODE - ML model is learning and any recommendations
requires of checking and errors back-propagation,
(3) COLLABORATION_MODE - ML model has good prediction but still
requires correction by default algorithm(s),
(4) RECOMMENDATION_MODE - ML model is capable to substitute
the default algorithm(s).

ML model can be: (1) created, (2) initialized, (3) started,
(4) running, (5) stopped, (6) shutted down.

The API of ML model includes:
(1) ml_model_create() - create ML model and initialize generic field
(2) ml_model_init() - execute specialized logic of ML model initialization
(3) ml_model_re_init() - execute specialized logic of ML model re-init
(4) ml_model_start() - start ML model activity
(5) ml_model_stop() - stop ML model activity
(6) ml_model_destroy() - destroy ML model and free all allocated memory
(7) get_system_state() - get current state of parent kernel subsystem
(8) ml_model_get_dataset() - prepare dataset for extraction by user-space agent
(9) ml_model_discard_dataset() - discard/obsolete dataset by user-space agent
(10) ml_model_preprocess_data() - preprocess data of current dataset
(11) ml_model_publish_data() - notify user-space agent about new dataset
(12) ml_model_preprocess_recommendation() - preprocess ML model recommendations
(13) estimate_system_state() - estimate parent kernel subsystem mode
(14) apply_ml_model_recommendation() - apply ML model recommendations
(15) execute_ml_model_operation() - execute logic following ML model mode
(16) estimate_ml_model_efficiency() - estimate ML model efficiency
(17) ml_model_error_backpropagation() - execute error backpropagation
(18) correct_system_state() - correct parent kernel subsystem mode

Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
---
 include/linux/ml-lib/ml_lib.h | 425 ++++++++++++++++++++++++++++++++++
 1 file changed, 425 insertions(+)
 create mode 100644 include/linux/ml-lib/ml_lib.h

diff --git a/include/linux/ml-lib/ml_lib.h b/include/linux/ml-lib/ml_lib.h
new file mode 100644
index 000000000000..001e781e0bf1
--- /dev/null
+++ b/include/linux/ml-lib/ml_lib.h
@@ -0,0 +1,425 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Machine Learning (ML) library
+ *
+ * Copyright (C) 2025-2026 Viacheslav Dubeyko <slava@dubeyko.com>
+ */
+
+#ifndef _LINUX_ML_LIB_H
+#define _LINUX_ML_LIB_H
+
+/*
+ * Any kernel subsystem can be in several modes
+ * that define how this subsystem interacts with
+ * ML model in user-space:
+ * (1) EMERGENCY_MODE - ignore ML model and run default algorithm(s).
+ * (2) LEARNING_MODE - ML model is learning and any recommendations
+ *                     requires of checking and errors back-propagation.
+ * (3) COLLABORATION_MODE - ML model has good prediction but still
+ *                          requires correction by default algorithm(s).
+ * (4) RECOMMENDATION_MODE - ML model is capable to substitute
+ *                           the default algorithm(s).
+ */
+enum ml_lib_system_mode {
+	ML_LIB_UNKNOWN_MODE,
+	ML_LIB_EMERGENCY_MODE,
+	ML_LIB_LEARNING_MODE,
+	ML_LIB_COLLABORATION_MODE,
+	ML_LIB_RECOMMENDATION_MODE,
+	ML_LIB_MODE_MAX
+};
+
+enum {
+	ML_LIB_UNKNOWN_MODEL_STATE,
+	ML_LIB_MODEL_CREATED,
+	ML_LIB_MODEL_INITIALIZED,
+	ML_LIB_MODEL_STARTED,
+	ML_LIB_MODEL_RUNNING,
+	ML_LIB_MODEL_STOPPED,
+	ML_LIB_MODEL_SHUTTING_DOWN,
+	ML_LIB_MODEL_STATE_MAX
+};
+
+struct ml_lib_model;
+
+#define ML_LIB_SLEEP_TIMEOUT_DEFAULT	(10)
+
+/*
+ * struct ml_lib_model_options - ML model global options
+ * @sleep_timeout: main thread's sleep timeout
+ *
+ * These options define behavior of ML model.
+ * The options can be defined during init() or re-init() call.
+ */
+struct ml_lib_model_options {
+	u32 sleep_timeout;
+};
+
+/*
+ * struct ml_lib_model_run_config - ML model run config
+ * @sleep_timeout: main thread's sleep timeout
+ *
+ * The run config is used for correction of ML model options
+ * by means of start/stop methods pair.
+ */
+struct ml_lib_model_run_config {
+	u32 sleep_timeout;
+};
+
+/*
+ * struct ml_lib_subsystem - kernel subsystem object
+ * @type: object type
+ * @size: number of bytes in allocated object
+ * @private: private data of subsystem
+ */
+struct ml_lib_subsystem {
+	atomic_t type;
+	size_t size;
+
+	void *private;
+};
+
+enum {
+	ML_LIB_UNKNOWN_SUBSYSTEM_TYPE,
+	ML_LIB_GENERIC_SUBSYSTEM,
+	ML_LIB_SPECIALIZED_SUBSYSTEM,
+	ML_LIB_SUBSYSTEM_TYPE_MAX
+};
+
+/*
+ * struct ml_lib_subsystem_state - shared kernel subsystem state
+ * @state: object state
+ * @size: number of bytes in allocated object
+ */
+struct ml_lib_subsystem_state {
+	atomic_t state;
+	size_t size;
+};
+
+enum {
+	ML_LIB_UNKNOWN_SUBSYSTEM_STATE,
+	ML_LIB_SUBSYSTEM_CREATED,
+	ML_LIB_SUBSYSTEM_INITIALIZED,
+	ML_LIB_SUBSYSTEM_STARTED,
+	ML_LIB_SUBSYSTEM_RUNNING,
+	ML_LIB_SUBSYSTEM_SHUTTING_DOWN,
+	ML_LIB_SUBSYSTEM_STOPPED,
+	ML_LIB_SUBSYSTEM_STATE_MAX
+};
+
+struct ml_lib_subsystem_state_operations {
+	void *(*allocate)(size_t size, gfp_t gfp);
+	void (*free)(struct ml_lib_subsystem_state *state);
+	int (*init)(struct ml_lib_subsystem_state *state);
+	int (*destroy)(struct ml_lib_subsystem_state *state);
+	int (*check_state)(struct ml_lib_subsystem_state *state);
+	struct ml_lib_subsystem_state *
+	    (*snapshot_state)(struct ml_lib_subsystem *object);
+	int (*estimate_system_state)(struct ml_lib_model *ml_model);
+	int (*correct_system_state)(struct ml_lib_model *ml_model);
+};
+
+/*
+ * struct ml_lib_dataset - exported subsystem's dataset
+ * @type: object type
+ * @state: object state
+ * @allocated_size: number of bytes in allocated object
+ * @portion_offset: portion offset in the data stream
+ * @portion_size: extracted portion size
+ */
+struct ml_lib_dataset {
+	atomic_t type;
+	atomic_t state;
+	size_t allocated_size;
+
+	u64 portion_offset;
+	u32 portion_size;
+};
+
+enum {
+	ML_LIB_UNKNOWN_DATASET_TYPE,
+	ML_LIB_EMPTY_DATASET,
+	ML_LIB_VALUE_DATASET,
+	ML_LIB_STRUCTURE_DATASET,
+	ML_LIB_MEMORY_STREAM_DATASET,
+	ML_LIB_DATASET_TYPE_MAX
+};
+
+enum {
+	ML_LIB_UNKNOWN_DATASET_STATE,
+	ML_LIB_DATASET_ALLOCATED,
+	ML_LIB_DATASET_CLEAN,
+	ML_LIB_DATASET_EXTRACTED_PARTIALLY,
+	ML_LIB_DATASET_EXTRACTED_COMPLETELY,
+	ML_LIB_DATASET_OBSOLETE,
+	ML_LIB_DATASET_EXTRACTION_FAILURE,
+	ML_LIB_DATASET_CORRUPTED,
+	ML_LIB_DATASET_STATE_MAX
+};
+
+struct ml_lib_dataset_operations {
+	void *(*allocate)(size_t size, gfp_t gfp);
+	void (*free)(struct ml_lib_dataset *dataset);
+	int (*init)(struct ml_lib_dataset *dataset);
+	int (*destroy)(struct ml_lib_dataset *dataset);
+	int (*extract)(struct ml_lib_model *ml_model,
+			struct ml_lib_dataset *dataset);
+	int (*preprocess_data)(struct ml_lib_model *ml_model,
+				struct ml_lib_dataset *dataset);
+	int (*publish_data)(struct ml_lib_model *ml_model,
+			    struct ml_lib_dataset *dataset);
+};
+
+/*
+ * struct ml_lib_request_config - dataset operation configuration
+ * @type: object type
+ * @state: object state
+ * @size: number of bytes in allocated object
+ */
+struct ml_lib_request_config {
+	atomic_t type;
+	atomic_t state;
+	size_t size;
+};
+
+enum {
+	ML_LIB_UNKNOWN_REQUEST_CONFIG_TYPE,
+	ML_LIB_EMPTY_REQUEST_CONFIG,
+	ML_LIB_REQUEST_CONFIG_TYPE_MAX
+};
+
+enum {
+	ML_LIB_UNKNOWN_REQUEST_CONFIG_STATE,
+	ML_LIB_REQUEST_CONFIG_ALLOCATED,
+	ML_LIB_REQUEST_CONFIG_INITIALIZED,
+	ML_LIB_REQUEST_CONFIG_STATE_MAX
+};
+
+struct ml_lib_request_config_operations {
+	void *(*allocate)(size_t size, gfp_t gfp);
+	void (*free)(struct ml_lib_request_config *config);
+	int (*init)(struct ml_lib_request_config *config);
+	int (*destroy)(struct ml_lib_request_config *config);
+};
+
+struct ml_lib_user_space_request {
+};
+
+struct ml_lib_user_space_request_operations {
+	int (*operation)(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_request *request);
+};
+
+struct ml_lib_user_space_notification {
+};
+
+struct ml_lib_user_space_notification_operations {
+	int (*operation)(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_notification *notify);
+};
+
+struct ml_lib_user_space_recommendation {
+};
+
+struct ml_lib_user_space_recommendation_operations {
+	int (*operation)(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint);
+};
+
+struct ml_lib_backpropagation_feedback {
+};
+
+struct ml_lib_backpropagation_operations {
+	int (*operation)(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint);
+};
+
+/*
+ * struct ml_lib_model_operations - ML model operations
+ * @create: specialized method of ML model creation
+ * @init: specialized method of ML model initialization
+ * @re_init: specialized method of ML model re-initialization
+ * @start: specialized method of ML model start
+ * @stop: specialized method of ML model stop
+ * @destroy: specialized method of ML model destroy
+ * @get_system_state: specialized method of getting subsystem state
+ * @get_dataset: specialized method of getting a dataset
+ * @preprocess_data: specialized method of data preprocessing
+ * @publish_data: specialized method of sharing data with user-space
+ * @preprocess_recommendation: specialized method of preprocess recomendations
+ * @estimate_system_state: specialized method of system state estimation
+ * @apply_recommendation: specialized method of recommendations applying
+ * @execute_operation: specialized method of operation execution
+ * @estimate_efficiency: specialized method of operation efficiency estimation
+ * @error_backpropagation: specialized method of error backpropagation
+ * @correct_system_state: specialized method of subsystem state correction
+ */
+struct ml_lib_model_operations {
+	int (*create)(struct ml_lib_model *ml_model);
+	int (*init)(struct ml_lib_model *ml_model,
+		    struct ml_lib_model_options *options);
+	int (*re_init)(struct ml_lib_model *ml_model,
+			struct ml_lib_model_options *options);
+	int (*start)(struct ml_lib_model *ml_model,
+		     struct ml_lib_model_run_config *config);
+	int (*stop)(struct ml_lib_model *ml_model);
+	void (*destroy)(struct ml_lib_model *ml_model);
+	struct ml_lib_subsystem_state *
+		(*get_system_state)(struct ml_lib_model *ml_model);
+	int (*get_dataset)(struct ml_lib_model *ml_model,
+			   struct ml_lib_dataset *dataset);
+	int (*preprocess_data)(struct ml_lib_model *ml_model,
+				struct ml_lib_dataset *dataset);
+	int (*publish_data)(struct ml_lib_model *ml_model,
+			    struct ml_lib_dataset *dataset,
+			    struct ml_lib_user_space_notification *notify);
+	int (*preprocess_recommendation)(struct ml_lib_model *ml_model,
+			    struct ml_lib_user_space_recommendation *hint);
+	int (*estimate_system_state)(struct ml_lib_model *ml_model);
+	int (*apply_recommendation)(struct ml_lib_model *ml_model,
+			    struct ml_lib_user_space_recommendation *hint);
+	int (*execute_operation)(struct ml_lib_model *ml_model,
+			    struct ml_lib_user_space_recommendation *hint,
+			    struct ml_lib_user_space_request *request);
+	int (*estimate_efficiency)(struct ml_lib_model *ml_model,
+			    struct ml_lib_user_space_recommendation *hint,
+			    struct ml_lib_user_space_request *request);
+	int (*error_backpropagation)(struct ml_lib_model *ml_model,
+			    struct ml_lib_backpropagation_feedback *feedback,
+			    struct ml_lib_user_space_notification *notify);
+	int (*correct_system_state)(struct ml_lib_model *ml_model);
+};
+
+/*
+ * struct ml_lib_model - ML model declaration
+ * @mode: ML model mode (enum ml_lib_system_mode)
+ * @state: ML model state
+ * @subsystem_name: name of susbsystem
+ * @model_name: name of the ML model
+ * @parent: parent kernel subsystem
+ * @parent_state: parent kernel subsystem's state
+ * @options: ML model options
+ * @model_ops: ML model specialized operations
+ * @system_state_ops: subsystem state specialized operations
+ * @dataset_ops: dataset specialized operations
+ * @request_config_ops: specialized dataset configuration operations
+ * @kobj: /sys/<subsystem>/<ml_model>/ ML model object
+ * @kobj_unregister: completion state for <ml_model> kernel object
+ */
+struct ml_lib_model {
+	atomic_t mode;
+	atomic_t state;
+	const char *subsystem_name;
+	const char *model_name;
+
+	struct ml_lib_subsystem *parent;
+
+	spinlock_t parent_state_lock;
+	struct ml_lib_subsystem_state * __rcu parent_state;
+
+	spinlock_t options_lock;
+	struct ml_lib_model_options * __rcu options;
+
+	spinlock_t dataset_lock;
+	struct ml_lib_dataset * __rcu dataset;
+
+	struct ml_lib_model_operations *model_ops;
+	struct ml_lib_subsystem_state_operations *system_state_ops;
+	struct ml_lib_dataset_operations *dataset_ops;
+	struct ml_lib_request_config_operations *request_config_ops;
+
+	/* /sys/<subsystem>/<ml_model>/ */
+	struct kobject kobj;
+	struct completion kobj_unregister;
+};
+
+/* ML library API */
+
+void *allocate_ml_model(size_t size, gfp_t gfp);
+void free_ml_model(struct ml_lib_model *ml_model);
+void *allocate_subsystem_object(size_t size, gfp_t gfp);
+void free_subsystem_object(struct ml_lib_subsystem *object);
+void *allocate_ml_model_options(size_t size, gfp_t gfp);
+void free_ml_model_options(struct ml_lib_model_options *options);
+void *allocate_subsystem_state(size_t size, gfp_t gfp);
+void free_subsystem_state(struct ml_lib_subsystem_state *state);
+void *allocate_dataset(size_t size, gfp_t gfp);
+void free_dataset(struct ml_lib_dataset *dataset);
+void *allocate_request_config(size_t size, gfp_t gfp);
+void free_request_config(struct ml_lib_request_config *config);
+
+int ml_model_create(struct ml_lib_model *ml_model,
+		    const char *subsystem_name,
+		    const char *model_name,
+		    struct kobject *subsystem_kobj);
+int ml_model_init(struct ml_lib_model *ml_model,
+		  struct ml_lib_model_options *options);
+int ml_model_re_init(struct ml_lib_model *ml_model,
+		     struct ml_lib_model_options *options);
+int ml_model_start(struct ml_lib_model *ml_model,
+		   struct ml_lib_model_run_config *config);
+int ml_model_stop(struct ml_lib_model *ml_model);
+void ml_model_destroy(struct ml_lib_model *ml_model);
+struct ml_lib_subsystem_state *get_system_state(struct ml_lib_model *ml_model);
+int ml_model_get_dataset(struct ml_lib_model *ml_model,
+			 struct ml_lib_request_config *config,
+			 struct ml_lib_user_space_request *request);
+int ml_model_discard_dataset(struct ml_lib_model *ml_model);
+int ml_model_preprocess_data(struct ml_lib_model *ml_model,
+			     struct ml_lib_dataset *dataset);
+int ml_model_publish_data(struct ml_lib_model *ml_model,
+			  struct ml_lib_dataset *dataset,
+			  struct ml_lib_user_space_notification *notify);
+int ml_model_preprocess_recommendation(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint);
+int estimate_system_state(struct ml_lib_model *ml_model);
+int apply_ml_model_recommendation(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint);
+int execute_ml_model_operation(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint,
+			 struct ml_lib_user_space_request *request);
+int estimate_ml_model_efficiency(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint,
+			 struct ml_lib_user_space_request *request);
+int ml_model_error_backpropagation(struct ml_lib_model *ml_model,
+			    struct ml_lib_backpropagation_feedback *feedback,
+			    struct ml_lib_user_space_notification *notify);
+int correct_system_state(struct ml_lib_model *ml_model);
+
+/* Generic implementation of ML model's methods */
+
+int generic_create_ml_model(struct ml_lib_model *ml_model);
+int generic_init_ml_model(struct ml_lib_model *ml_model,
+			  struct ml_lib_model_options *options);
+int generic_re_init_ml_model(struct ml_lib_model *ml_model,
+			     struct ml_lib_model_options *options);
+int generic_start_ml_model(struct ml_lib_model *ml_model,
+			   struct ml_lib_model_run_config *config);
+int generic_stop_ml_model(struct ml_lib_model *ml_model);
+void generic_destroy_ml_model(struct ml_lib_model *ml_model);
+struct ml_lib_subsystem_state *
+generic_get_system_state(struct ml_lib_model *ml_model);
+int generic_get_dataset(struct ml_lib_model *ml_model,
+			struct ml_lib_dataset *dataset);
+int generic_preprocess_data(struct ml_lib_model *ml_model,
+			    struct ml_lib_dataset *dataset);
+int generic_publish_data(struct ml_lib_model *ml_model,
+			 struct ml_lib_dataset *dataset,
+			 struct ml_lib_user_space_notification *notify);
+int generic_preprocess_recommendation(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint);
+int generic_estimate_system_state(struct ml_lib_model *ml_model);
+int generic_apply_recommendation(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint);
+int generic_execute_operation(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint,
+			 struct ml_lib_user_space_request *request);
+int generic_estimate_efficiency(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint,
+			 struct ml_lib_user_space_request *request);
+int generic_error_backpropagation(struct ml_lib_model *ml_model,
+			    struct ml_lib_backpropagation_feedback *feedback,
+			    struct ml_lib_user_space_notification *notify);
+int generic_correct_system_state(struct ml_lib_model *ml_model);
+
+#endif /* _LINUX_ML_LIB_H */
-- 
2.34.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFC PATCH v1 2/4] ml-lib: Implement PoC of Machine Learning (ML) library functionality
  2026-02-06 19:11 [RFC PATCH v1 0/4] Machine Learning (ML) library in Linux kernel Viacheslav Dubeyko
  2026-02-06 19:11 ` [RFC PATCH v1 1/4] ml-lib: Introduce Machine Learning (ML) library declarations Viacheslav Dubeyko
@ 2026-02-06 19:11 ` Viacheslav Dubeyko
  2026-02-06 19:11 ` [RFC PATCH v1 3/4] ml-lib: Implement simple testing character device driver Viacheslav Dubeyko
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: Viacheslav Dubeyko @ 2026-02-06 19:11 UTC (permalink / raw)
  To: linux-fsdevel, linux-mm, bpf; +Cc: Slava.Dubeyko, slava, linux-kernel

ML model can be represented by process/thread running in user-space.
Particular kernel subsystem needs to implement ML model proxy
on kernel-space side. The process of loading kernel subsystem
creates and intializes the ML model proxy, create sysfs entries,
and character device, for example. The sysfs entries and character
device create the mechanism of interaction and collaboration of
kernel subsystem and ML model in user-space.

The simplest model of collaboration could include such steps:
(1) user-space process/thread (ML model) sends START command
    to kernel subsystem through sysfs control entry;
(2) user-space process/thread (ML model) requests to prepare
    a dataset by means of PREPARE_DATASET command through
    sysfs control entry;
(3) user-space process/thread (ML model) extracts the dataset
    by means of reading data from character device;
(4) dataset can be marked as obsolete after extraction
    by means of DISCARD_DATASET command through sysfs control entry
    and new dataset can be requested and extracted;
(5) extracted data can be used as training data by ML model
    on user-space side;
(6) ML model can execute the inference after some number of
    training cycles and to elaborate some recommendations or
    optimized logic for kernel subsystem;
(7) ML model's recommendations can be written into character
    device, for example, by user-space process/thread and
    kernel subsystem can use this recommendations for
    optimization or changing the logic;
(8) based on kernel subsystem's mode, recommendations can be
    completely ignored, partially applied, tested, or
    used instead of default configuration/logic;
(9) every time efficiency of applied recommendations or
    logic needs to be estimated;
(10) if ML model recommendations degrade efficiency of kernel
     subsystem, then error backpropagation needs to be used
     for ML model correction on user-space side.

Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
---
 lib/Kconfig              |   6 +
 lib/Makefile             |   2 +
 lib/ml-lib/Kconfig       |  18 +
 lib/ml-lib/Makefile      |   7 +
 lib/ml-lib/ml_lib_main.c | 758 +++++++++++++++++++++++++++++++++++++++
 lib/ml-lib/sysfs.c       | 187 ++++++++++
 lib/ml-lib/sysfs.h       |  17 +
 7 files changed, 995 insertions(+)
 create mode 100644 lib/ml-lib/Kconfig
 create mode 100644 lib/ml-lib/Makefile
 create mode 100644 lib/ml-lib/ml_lib_main.c
 create mode 100644 lib/ml-lib/sysfs.c
 create mode 100644 lib/ml-lib/sysfs.h

diff --git a/lib/Kconfig b/lib/Kconfig
index 2923924bea78..2d56977c0638 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -604,6 +604,12 @@ config LWQ_TEST
 	help
           Run boot-time test of light-weight queuing.
 
+#
+# Machine Learning (ML) library configuration
+#
+
+source "lib/ml-lib/Kconfig"
+
 endmenu
 
 config GENERIC_IOREMAP
diff --git a/lib/Makefile b/lib/Makefile
index aaf677cf4527..154e7fd220ab 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -332,3 +332,5 @@ obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
 obj-$(CONFIG_FIRMWARE_TABLE) += fw_table.o
 
 subdir-$(CONFIG_FORTIFY_SOURCE) += test_fortify
+
+obj-$(CONFIG_ML_LIB) += ml-lib/
diff --git a/lib/ml-lib/Kconfig b/lib/ml-lib/Kconfig
new file mode 100644
index 000000000000..d2f2ea40a833
--- /dev/null
+++ b/lib/ml-lib/Kconfig
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+#
+# Machine Learning (ML) library configuration
+#
+
+config ML_LIB
+	tristate "ML library support"
+	help
+	  Machine Learning (ML) library has goal to provide
+	  the interaction and communication of ML models in
+	  user-space with kernel subsystems. It implements
+	  the basic code primitives that builds the way of
+	  ML models integration into Linux kernel functionality.
+
+	  If unsure, say N.
+
+source "lib/ml-lib/test_driver/Kconfig"
diff --git a/lib/ml-lib/Makefile b/lib/ml-lib/Makefile
new file mode 100644
index 000000000000..b1103ab3e1c8
--- /dev/null
+++ b/lib/ml-lib/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_ML_LIB) += ml_lib.o
+
+ml_lib-y := sysfs.o ml_lib_main.o
+
+obj-$(CONFIG_ML_LIB_TEST_DRIVER) += test_driver/
diff --git a/lib/ml-lib/ml_lib_main.c b/lib/ml-lib/ml_lib_main.c
new file mode 100644
index 000000000000..ef336d6a83fb
--- /dev/null
+++ b/lib/ml-lib/ml_lib_main.c
@@ -0,0 +1,758 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Machine Learning (ML) library
+ *
+ * Copyright (C) 2025-2026 Viacheslav Dubeyko <slava@dubeyko.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <linux/ml-lib/ml_lib.h>
+
+#include "sysfs.h"
+
+#define UNKNOWN_SUBSYSTEM_NAME "unknown_subsystem"
+#define UNKNOWN_ML_MODEL_NAME "unknown_model"
+
+/*
+ * default_ml_model_ops - default ML model operations
+ */
+struct ml_lib_model_operations default_ml_model_ops = {
+	.create				= generic_create_ml_model,
+	.init				= generic_init_ml_model,
+	.re_init			= generic_re_init_ml_model,
+	.start				= generic_start_ml_model,
+	.stop				= generic_stop_ml_model,
+	.destroy			= generic_destroy_ml_model,
+	.get_system_state		= generic_get_system_state,
+	.get_dataset			= generic_get_dataset,
+	.preprocess_data		= generic_preprocess_data,
+	.publish_data			= generic_publish_data,
+	.preprocess_recommendation	= generic_preprocess_recommendation,
+	.estimate_system_state		= generic_estimate_system_state,
+	.apply_recommendation		= generic_apply_recommendation,
+	.execute_operation		= generic_execute_operation,
+	.estimate_efficiency		= generic_estimate_efficiency,
+	.error_backpropagation		= generic_error_backpropagation,
+	.correct_system_state		= generic_correct_system_state,
+};
+
+/******************************************************************************
+ *                             ML library API                                 *
+ ******************************************************************************/
+
+void *allocate_ml_model(size_t size, gfp_t gfp)
+{
+	struct ml_lib_model *ml_model;
+
+	if (size < sizeof(struct ml_lib_model))
+		return ERR_PTR(-EINVAL);
+
+	ml_model = kzalloc(size, gfp);
+	if (unlikely(!ml_model))
+		return ERR_PTR(-ENOMEM);
+
+	atomic_set(&ml_model->mode, ML_LIB_UNKNOWN_MODE);
+	atomic_set(&ml_model->state, ML_LIB_UNKNOWN_MODEL_STATE);
+	ml_model->model_ops = &default_ml_model_ops;
+
+	return (void *)ml_model;
+}
+EXPORT_SYMBOL(allocate_ml_model);
+
+void free_ml_model(struct ml_lib_model *ml_model)
+{
+	if (!ml_model)
+		return;
+
+	free_subsystem_object(ml_model->parent);
+	kfree(ml_model);
+}
+EXPORT_SYMBOL(free_ml_model);
+
+void *allocate_subsystem_object(size_t size, gfp_t gfp)
+{
+	struct ml_lib_subsystem *subsystem;
+
+	if (size < sizeof(struct ml_lib_subsystem))
+		return ERR_PTR(-EINVAL);
+
+	subsystem = kzalloc(size, gfp);
+	if (unlikely(!subsystem))
+		return ERR_PTR(-ENOMEM);
+
+	subsystem->size = size;
+	atomic_set(&subsystem->type, ML_LIB_UNKNOWN_SUBSYSTEM_TYPE);
+
+	return (void *)subsystem;
+}
+EXPORT_SYMBOL(allocate_subsystem_object);
+
+void free_subsystem_object(struct ml_lib_subsystem *object)
+{
+	if (!object)
+		return;
+
+	kfree(object);
+}
+EXPORT_SYMBOL(free_subsystem_object);
+
+void *allocate_ml_model_options(size_t size, gfp_t gfp)
+{
+	struct ml_lib_model_options *options;
+
+	if (size < sizeof(struct ml_lib_model_options))
+		return ERR_PTR(-EINVAL);
+
+	options = kzalloc(size, gfp);
+	if (unlikely(!options))
+		return ERR_PTR(-ENOMEM);
+
+	options->sleep_timeout = U32_MAX;
+
+	return (void *)options;
+}
+EXPORT_SYMBOL(allocate_ml_model_options);
+
+void free_ml_model_options(struct ml_lib_model_options *options)
+{
+	if (!options)
+		return;
+
+	kfree(options);
+}
+EXPORT_SYMBOL(free_ml_model_options);
+
+void *allocate_subsystem_state(size_t size, gfp_t gfp)
+{
+	return NULL;
+}
+EXPORT_SYMBOL(allocate_subsystem_state);
+
+void free_subsystem_state(struct ml_lib_subsystem_state *state)
+{
+}
+EXPORT_SYMBOL(free_subsystem_state);
+
+void *allocate_dataset(size_t size, gfp_t gfp)
+{
+	struct ml_lib_dataset *dataset;
+
+	if (size < sizeof(struct ml_lib_dataset))
+		return ERR_PTR(-EINVAL);
+
+	dataset = kzalloc(size, gfp);
+	if (unlikely(!dataset))
+		return ERR_PTR(-ENOMEM);
+
+	atomic_set(&dataset->type, ML_LIB_UNKNOWN_DATASET_TYPE);
+	atomic_set(&dataset->state, ML_LIB_UNKNOWN_DATASET_STATE);
+
+	return (void *)dataset;
+}
+EXPORT_SYMBOL(allocate_dataset);
+
+void free_dataset(struct ml_lib_dataset *dataset)
+{
+	if (!dataset)
+		return;
+
+	kfree(dataset);
+}
+EXPORT_SYMBOL(free_dataset);
+
+void *allocate_request_config(size_t size, gfp_t gfp)
+{
+	return NULL;
+}
+EXPORT_SYMBOL(allocate_request_config);
+
+void free_request_config(struct ml_lib_request_config *config)
+{
+}
+EXPORT_SYMBOL(free_request_config);
+
+int ml_model_create(struct ml_lib_model *ml_model,
+		    const char *subsystem_name,
+		    const char *model_name,
+		    struct kobject *subsystem_kobj)
+{
+	struct kobject *parent = NULL;
+	size_t size;
+	int err = 0;
+
+	if (!ml_model)
+		return -EINVAL;
+
+	if (!subsystem_name)
+		ml_model->subsystem_name = UNKNOWN_SUBSYSTEM_NAME;
+	else
+		ml_model->subsystem_name = subsystem_name;
+
+	if (!model_name)
+		ml_model->model_name = UNKNOWN_ML_MODEL_NAME;
+	else
+		ml_model->model_name = model_name;
+
+	if (!subsystem_kobj)
+		parent = kernel_kobj;
+	else
+		parent = subsystem_kobj;
+
+	spin_lock_init(&ml_model->parent_state_lock);
+	spin_lock_init(&ml_model->options_lock);
+	spin_lock_init(&ml_model->dataset_lock);
+
+	err = ml_model_create_sysfs_group(ml_model, parent);
+	if (err) {
+		pr_err("ml_lib: failed to create sysfs group: err %d\n", err);
+		goto finish_model_create;
+	}
+
+	if (!ml_model->model_ops || !ml_model->model_ops->create) {
+		size = sizeof(struct ml_lib_subsystem);
+
+		ml_model->parent = allocate_subsystem_object(size, GFP_KERNEL);
+		if (unlikely(!ml_model->parent)) {
+			err = -ENOMEM;
+			goto remove_sysfs_group;
+		}
+
+		atomic_set(&ml_model->parent->type, ML_LIB_GENERIC_SUBSYSTEM);
+	} else {
+		err = ml_model->model_ops->create(ml_model);
+		if (unlikely(err)) {
+			pr_err("ml_lib: failed to create ML model: err %d\n",
+				err);
+			goto remove_sysfs_group;
+		}
+	}
+
+	atomic_set(&ml_model->state, ML_LIB_MODEL_CREATED);
+
+	return 0;
+
+remove_sysfs_group:
+	ml_model_delete_sysfs_group(ml_model);
+
+finish_model_create:
+	return err;
+}
+EXPORT_SYMBOL(ml_model_create);
+
+int ml_model_init(struct ml_lib_model *ml_model,
+		  struct ml_lib_model_options *options)
+{
+	struct ml_lib_model_options *old_options;
+	int err = 0;
+
+	if (!ml_model)
+		return -EINVAL;
+
+	if (!ml_model->model_ops || !ml_model->model_ops->init)
+		options->sleep_timeout = ML_LIB_SLEEP_TIMEOUT_DEFAULT;
+	else {
+		err = ml_model->model_ops->init(ml_model, options);
+		if (unlikely(err)) {
+			pr_err("ml_lib: failed to init ML model: err %d\n",
+				err);
+			goto finish_model_init;
+		}
+	}
+
+	spin_lock(&ml_model->options_lock);
+	old_options = rcu_dereference_protected(ml_model->options,
+				lockdep_is_held(&ml_model->options_lock));
+	rcu_assign_pointer(ml_model->options, options);
+	spin_unlock(&ml_model->options_lock);
+	synchronize_rcu();
+	free_ml_model_options(old_options);
+
+	atomic_set(&ml_model->state, ML_LIB_MODEL_INITIALIZED);
+
+finish_model_init:
+	return err;
+}
+EXPORT_SYMBOL(ml_model_init);
+
+int ml_model_re_init(struct ml_lib_model *ml_model,
+		     struct ml_lib_model_options *options)
+{
+	struct ml_lib_model_options *old_options;
+
+	if (!ml_model)
+		return -EINVAL;
+
+	spin_lock(&ml_model->options_lock);
+	old_options = rcu_dereference_protected(ml_model->options,
+				lockdep_is_held(&ml_model->options_lock));
+	rcu_assign_pointer(ml_model->options, options);
+	spin_unlock(&ml_model->options_lock);
+	synchronize_rcu();
+	free_ml_model_options(old_options);
+
+	return 0;
+}
+EXPORT_SYMBOL(ml_model_re_init);
+
+int ml_model_start(struct ml_lib_model *ml_model,
+		   struct ml_lib_model_run_config *config)
+{
+	if (!ml_model)
+		return -EINVAL;
+
+	/* TODO: implement ML model start logic*/
+	atomic_set(&ml_model->state, ML_LIB_MODEL_STARTED);
+	pr_err("ml_lib: TODO: implement start ML model\n");
+	return 0;
+}
+EXPORT_SYMBOL(ml_model_start);
+
+int ml_model_stop(struct ml_lib_model *ml_model)
+{
+	if (!ml_model)
+		return -EINVAL;
+
+	/* TODO: implement ML model stop logic*/
+	atomic_set(&ml_model->state, ML_LIB_MODEL_STOPPED);
+	pr_err("ml_lib: TODO: implement stop ML model\n");
+	return 0;
+}
+EXPORT_SYMBOL(ml_model_stop);
+
+void ml_model_destroy(struct ml_lib_model *ml_model)
+{
+	struct ml_lib_model_options *old_options;
+	struct ml_lib_dataset *old_dataset;
+
+	if (!ml_model)
+		return;
+
+	atomic_set(&ml_model->state, ML_LIB_MODEL_SHUTTING_DOWN);
+
+	ml_model_delete_sysfs_group(ml_model);
+
+	spin_lock(&ml_model->options_lock);
+	old_options = rcu_dereference_protected(ml_model->options,
+				lockdep_is_held(&ml_model->options_lock));
+	rcu_assign_pointer(ml_model->options, NULL);
+	spin_unlock(&ml_model->options_lock);
+	synchronize_rcu();
+	free_ml_model_options(old_options);
+
+	spin_lock(&ml_model->dataset_lock);
+	old_dataset = rcu_dereference_protected(ml_model->dataset,
+				lockdep_is_held(&ml_model->dataset_lock));
+	rcu_assign_pointer(ml_model->dataset, NULL);
+	spin_unlock(&ml_model->dataset_lock);
+	synchronize_rcu();
+
+	if (!ml_model->dataset_ops || !ml_model->dataset_ops->destroy) {
+		/*
+		 * Do nothing
+		 */
+	} else
+		ml_model->dataset_ops->destroy(old_dataset);
+
+	if (!ml_model->dataset_ops || !ml_model->dataset_ops->free)
+		free_dataset(old_dataset);
+	else
+		ml_model->dataset_ops->free(old_dataset);
+
+	if (!ml_model->model_ops || !ml_model->model_ops->destroy) {
+		atomic_set(&ml_model->parent->type,
+			   ML_LIB_UNKNOWN_SUBSYSTEM_TYPE);
+	} else
+		ml_model->model_ops->destroy(ml_model);
+
+	atomic_set(&ml_model->state, ML_LIB_MODEL_STATE_MAX);
+}
+EXPORT_SYMBOL(ml_model_destroy);
+
+struct ml_lib_subsystem_state *get_system_state(struct ml_lib_model *ml_model)
+{
+	return NULL;
+}
+EXPORT_SYMBOL(get_system_state);
+
+int ml_model_get_dataset(struct ml_lib_model *ml_model,
+			 struct ml_lib_request_config *config,
+			 struct ml_lib_user_space_request *request)
+{
+	struct ml_lib_dataset *old_dataset;
+	struct ml_lib_dataset *new_dataset;
+	size_t desc_size = sizeof(struct ml_lib_dataset);
+	int state;
+	int err = 0;
+
+	if (!ml_model)
+		return -EINVAL;
+
+	atomic_set(&ml_model->state, ML_LIB_MODEL_RUNNING);
+
+	rcu_read_lock();
+	old_dataset = rcu_dereference(ml_model->dataset);
+	if (old_dataset)
+		state = atomic_read(&old_dataset->state);
+	else
+		state = ML_LIB_UNKNOWN_DATASET_STATE;
+	rcu_read_unlock();
+
+	switch (state) {
+	case ML_LIB_DATASET_CLEAN:
+	case ML_LIB_DATASET_EXTRACTED_PARTIALLY:
+	case ML_LIB_DATASET_EXTRACTED_COMPLETELY:
+		/* nothing should be done */
+		goto finish_get_dataset;
+
+	default:
+		/* continue logic */
+		break;
+	}
+
+	if (!ml_model->dataset_ops || !ml_model->dataset_ops->allocate)
+		new_dataset = allocate_dataset(desc_size, GFP_KERNEL);
+	else {
+		new_dataset = ml_model->dataset_ops->allocate(desc_size,
+							      GFP_KERNEL);
+	}
+
+	if (IS_ERR(new_dataset)) {
+		err = PTR_ERR(new_dataset);
+		pr_err("ml_lib: Failed to allocate dataset\n");
+		return err;
+	} else if (!new_dataset) {
+		err = -ENOMEM;
+		pr_err("ml_lib: Failed to allocate dataset\n");
+		return err;
+	}
+
+	if (!ml_model->dataset_ops || !ml_model->dataset_ops->init) {
+		/*
+		 * Do nothing
+		 */
+	} else {
+		err = ml_model->dataset_ops->init(new_dataset);
+		if (err) {
+			pr_err("ml_lib: Failed to init dataset: err %d\n",
+				err);
+			goto fail_get_dataset;
+		}
+	}
+
+	if (!ml_model->dataset_ops || !ml_model->dataset_ops->extract) {
+		atomic_set(&new_dataset->type, ML_LIB_EMPTY_DATASET);
+		atomic_set(&new_dataset->state, ML_LIB_DATASET_CLEAN);
+		new_dataset->allocated_size = 0;
+		new_dataset->portion_offset = 0;
+		new_dataset->portion_size = 0;
+	} else {
+		err = ml_model->dataset_ops->extract(ml_model, new_dataset);
+		if (err) {
+			pr_err("ml_lib: Failed to extract dataset: err %d\n",
+				err);
+			goto fail_get_dataset;
+		}
+	}
+
+	spin_lock(&ml_model->dataset_lock);
+	old_dataset = rcu_dereference_protected(ml_model->dataset,
+				lockdep_is_held(&ml_model->dataset_lock));
+	rcu_assign_pointer(ml_model->dataset, new_dataset);
+	spin_unlock(&ml_model->dataset_lock);
+	synchronize_rcu();
+
+	if (!ml_model->dataset_ops || !ml_model->dataset_ops->destroy) {
+		/*
+		 * Do nothing
+		 */
+	} else
+		ml_model->dataset_ops->destroy(old_dataset);
+
+	if (!ml_model->dataset_ops || !ml_model->dataset_ops->free)
+		free_dataset(old_dataset);
+	else
+		ml_model->dataset_ops->free(old_dataset);
+
+finish_get_dataset:
+	return 0;
+
+fail_get_dataset:
+	if (!ml_model->dataset_ops || !ml_model->dataset_ops->destroy) {
+		/*
+		 * Do nothing
+		 */
+	} else
+		ml_model->dataset_ops->destroy(new_dataset);
+
+	if (!ml_model->dataset_ops || !ml_model->dataset_ops->free)
+		free_dataset(new_dataset);
+	else
+		ml_model->dataset_ops->free(new_dataset);
+
+	return err;
+}
+EXPORT_SYMBOL(ml_model_get_dataset);
+
+int ml_model_discard_dataset(struct ml_lib_model *ml_model)
+{
+	struct ml_lib_dataset *old_dataset;
+	struct ml_lib_dataset *new_dataset;
+	size_t desc_size = sizeof(struct ml_lib_dataset);
+	int err;
+
+	if (!ml_model->dataset_ops || !ml_model->dataset_ops->allocate)
+		new_dataset = allocate_dataset(desc_size, GFP_KERNEL);
+	else {
+		new_dataset = ml_model->dataset_ops->allocate(desc_size,
+							      GFP_KERNEL);
+	}
+
+	if (IS_ERR(new_dataset)) {
+		err = PTR_ERR(new_dataset);
+		pr_err("ml_lib: Failed to allocate dataset\n");
+		return err;
+	} else if (!new_dataset) {
+		err = -ENOMEM;
+		pr_err("ml_lib: Failed to allocate dataset\n");
+		return err;
+	}
+
+	spin_lock(&ml_model->dataset_lock);
+	old_dataset = rcu_dereference_protected(ml_model->dataset,
+				lockdep_is_held(&ml_model->dataset_lock));
+	if (old_dataset) {
+		atomic_set(&new_dataset->type, atomic_read(&old_dataset->type));
+		new_dataset->allocated_size = old_dataset->allocated_size;
+		new_dataset->portion_offset = old_dataset->portion_offset;
+		new_dataset->portion_size = old_dataset->portion_size;
+	} else {
+		atomic_set(&new_dataset->type, ML_LIB_EMPTY_DATASET);
+		new_dataset->allocated_size = 0;
+		new_dataset->portion_offset = 0;
+		new_dataset->portion_size = 0;
+	}
+	atomic_set(&new_dataset->state, ML_LIB_DATASET_OBSOLETE);
+	rcu_assign_pointer(ml_model->dataset, new_dataset);
+	spin_unlock(&ml_model->dataset_lock);
+	synchronize_rcu();
+
+	if (!ml_model->dataset_ops || !ml_model->dataset_ops->free)
+		free_dataset(old_dataset);
+	else
+		ml_model->dataset_ops->free(old_dataset);
+
+	return 0;
+}
+EXPORT_SYMBOL(ml_model_discard_dataset);
+
+int ml_model_preprocess_data(struct ml_lib_model *ml_model,
+			     struct ml_lib_dataset *dataset)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(ml_model_preprocess_data);
+
+int ml_model_publish_data(struct ml_lib_model *ml_model,
+			  struct ml_lib_dataset *dataset,
+			  struct ml_lib_user_space_notification *notify)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(ml_model_publish_data);
+
+int ml_model_preprocess_recommendation(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(ml_model_preprocess_recommendation);
+
+int estimate_system_state(struct ml_lib_model *ml_model)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(estimate_system_state);
+
+int apply_ml_model_recommendation(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(apply_ml_model_recommendation);
+
+int execute_ml_model_operation(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint,
+			 struct ml_lib_user_space_request *request)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(execute_ml_model_operation);
+
+int estimate_ml_model_efficiency(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint,
+			 struct ml_lib_user_space_request *request)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(estimate_ml_model_efficiency);
+
+int ml_model_error_backpropagation(struct ml_lib_model *ml_model,
+			    struct ml_lib_backpropagation_feedback *feedback,
+			    struct ml_lib_user_space_notification *notify)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(ml_model_error_backpropagation);
+
+int correct_system_state(struct ml_lib_model *ml_model)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(correct_system_state);
+
+/******************************************************************************
+ *              Generic implementation of ML model's methods                  *
+ ******************************************************************************/
+
+int generic_create_ml_model(struct ml_lib_model *ml_model)
+{
+	size_t size = sizeof(struct ml_lib_subsystem);
+
+	ml_model->parent = allocate_subsystem_object(size, GFP_KERNEL);
+	if (unlikely(!ml_model->parent))
+		return -ENOMEM;
+
+	atomic_set(&ml_model->parent->type, ML_LIB_GENERIC_SUBSYSTEM);
+	atomic_set(&ml_model->mode, ML_LIB_EMERGENCY_MODE);
+
+	return 0;
+}
+EXPORT_SYMBOL(generic_create_ml_model);
+
+int generic_init_ml_model(struct ml_lib_model *ml_model,
+			  struct ml_lib_model_options *options)
+{
+	options->sleep_timeout = ML_LIB_SLEEP_TIMEOUT_DEFAULT;
+	return 0;
+}
+EXPORT_SYMBOL(generic_init_ml_model);
+
+int generic_re_init_ml_model(struct ml_lib_model *ml_model,
+			     struct ml_lib_model_options *options)
+{
+	options->sleep_timeout = ML_LIB_SLEEP_TIMEOUT_DEFAULT;
+	return 0;
+}
+EXPORT_SYMBOL(generic_re_init_ml_model);
+
+int generic_start_ml_model(struct ml_lib_model *ml_model,
+			   struct ml_lib_model_run_config *config)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(generic_start_ml_model);
+
+int generic_stop_ml_model(struct ml_lib_model *ml_model)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(generic_stop_ml_model);
+
+void generic_destroy_ml_model(struct ml_lib_model *ml_model)
+{
+	atomic_set(&ml_model->parent->type, ML_LIB_UNKNOWN_SUBSYSTEM_TYPE);
+	atomic_set(&ml_model->mode, ML_LIB_UNKNOWN_MODE);
+}
+EXPORT_SYMBOL(generic_destroy_ml_model);
+
+struct ml_lib_subsystem_state *
+generic_get_system_state(struct ml_lib_model *ml_model)
+{
+	return NULL;
+}
+EXPORT_SYMBOL(generic_get_system_state);
+
+int generic_get_dataset(struct ml_lib_model *ml_model,
+			struct ml_lib_dataset *dataset)
+{
+	atomic_set(&dataset->type, ML_LIB_EMPTY_DATASET);
+	atomic_set(&dataset->state, ML_LIB_DATASET_CLEAN);
+	dataset->allocated_size = 0;
+	dataset->portion_offset = 0;
+	dataset->portion_size = 0;
+
+	return 0;
+}
+EXPORT_SYMBOL(generic_get_dataset);
+
+int generic_preprocess_data(struct ml_lib_model *ml_model,
+			    struct ml_lib_dataset *dataset)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(generic_preprocess_data);
+
+int generic_publish_data(struct ml_lib_model *ml_model,
+			 struct ml_lib_dataset *dataset,
+			 struct ml_lib_user_space_notification *notify)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(generic_publish_data);
+
+int generic_preprocess_recommendation(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(generic_preprocess_recommendation);
+
+int generic_estimate_system_state(struct ml_lib_model *ml_model)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(generic_estimate_system_state);
+
+int generic_apply_recommendation(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(generic_apply_recommendation);
+
+int generic_execute_operation(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint,
+			 struct ml_lib_user_space_request *request)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(generic_execute_operation);
+
+int generic_estimate_efficiency(struct ml_lib_model *ml_model,
+			 struct ml_lib_user_space_recommendation *hint,
+			 struct ml_lib_user_space_request *request)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(generic_estimate_efficiency);
+
+int generic_error_backpropagation(struct ml_lib_model *ml_model,
+			    struct ml_lib_backpropagation_feedback *feedback,
+			    struct ml_lib_user_space_notification *notify)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(generic_error_backpropagation);
+
+int generic_correct_system_state(struct ml_lib_model *ml_model)
+{
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(generic_correct_system_state);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Viacheslav Dubeyko <slava@dubeyko.com>");
+MODULE_DESCRIPTION("ML library");
+MODULE_VERSION("1.0");
diff --git a/lib/ml-lib/sysfs.c b/lib/ml-lib/sysfs.c
new file mode 100644
index 000000000000..fb4b7f44f793
--- /dev/null
+++ b/lib/ml-lib/sysfs.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Machine Learning (ML) library
+ *
+ * Copyright (C) 2025-2026 Viacheslav Dubeyko <slava@dubeyko.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <linux/ml-lib/ml_lib.h>
+
+#include "sysfs.h"
+
+struct ml_lib_feature_attr {
+	struct attribute attr;
+	ssize_t (*show)(struct ml_lib_feature_attr *,
+			struct ml_lib_model *,
+			char *);
+	ssize_t (*store)(struct ml_lib_feature_attr *,
+				struct ml_lib_model *,
+				const char *, size_t);
+};
+
+#define ML_LIB_ATTR(type, name, mode, show, store) \
+	static struct ml_lib_##type##_attr ml_lib_##type##_attr_##name = \
+		__ATTR(name, mode, show, store)
+
+#define ML_LIB_FEATURE_INFO_ATTR(name) \
+	ML_LIB_ATTR(feature, name, 0444, NULL, NULL)
+#define ML_LIB_FEATURE_RO_ATTR(name) \
+	ML_LIB_ATTR(feature, name, 0444, ml_lib_feature_##name##_show, NULL)
+#define ML_LIB_FEATURE_W_ATTR(name) \
+	ML_LIB_ATTR(feature, name, 0220, NULL, ml_lib_feature_##name##_store)
+#define ML_LIB_FEATURE_RW_ATTR(name) \
+	ML_LIB_ATTR(feature, name, 0644, \
+		    ml_lib_feature_##name##_show, ml_lib_feature_##name##_store)
+
+enum {
+	ML_LIB_START_COMMAND,
+	ML_LIB_STOP_COMMAND,
+	ML_LIB_PREPARE_DATASET_COMMAND,
+	ML_LIB_DISCARD_DATASET_COMMAND,
+	ML_LIB_COMMAND_NUMBER
+};
+
+static const char *control_command_str[ML_LIB_COMMAND_NUMBER] = {
+	"start",
+	"stop",
+	"prepare_dataset",
+	"discard_dataset",
+};
+
+static ssize_t ml_lib_feature_control_store(struct ml_lib_feature_attr *attr,
+					    struct ml_lib_model *ml_model,
+					    const char *buf, size_t len)
+{
+	struct ml_lib_model_run_config config = {0};
+	int i;
+	int err;
+
+	for (i = 0; i < ML_LIB_COMMAND_NUMBER; i++) {
+		size_t iter_len = min(len, strlen(control_command_str[i]));
+
+		if (strncmp(control_command_str[i], buf, iter_len) == 0)
+			break;
+	}
+
+	if (i >= ML_LIB_COMMAND_NUMBER)
+		return -EOPNOTSUPP;
+
+	switch (i) {
+	case ML_LIB_START_COMMAND:
+		err = ml_model_start(ml_model, &config);
+		break;
+
+	case ML_LIB_STOP_COMMAND:
+		err = ml_model_stop(ml_model);
+		break;
+
+	case ML_LIB_PREPARE_DATASET_COMMAND:
+		err = ml_model_get_dataset(ml_model, NULL, NULL);
+		break;
+
+	case ML_LIB_DISCARD_DATASET_COMMAND:
+		err = ml_model_discard_dataset(ml_model);
+		break;
+	}
+
+	if (unlikely(err))
+		return err;
+
+	return len;
+}
+
+ML_LIB_FEATURE_W_ATTR(control);
+
+static struct attribute *ml_model_attrs[] = {
+	&ml_lib_feature_attr_control.attr,
+	NULL,
+};
+
+static const struct attribute_group ml_model_group = {
+	.attrs = ml_model_attrs,
+};
+
+static const struct attribute_group *ml_model_groups[] = {
+	&ml_model_group,
+	NULL,
+};
+
+static
+ssize_t ml_model_attr_show(struct kobject *kobj,
+			   struct attribute *attr,
+			   char *buf)
+{
+	struct ml_lib_model *ml_model = container_of(kobj,
+						     struct ml_lib_model,
+						     kobj);
+	struct ml_lib_feature_attr *ml_model_attr =
+			container_of(attr, struct ml_lib_feature_attr, attr);
+
+	if (!ml_model_attr->show)
+		return -EIO;
+
+	return ml_model_attr->show(ml_model_attr, ml_model, buf);
+}
+
+static
+ssize_t ml_model_attr_store(struct kobject *kobj,
+			    struct attribute *attr,
+			    const char *buf, size_t len)
+{
+	struct ml_lib_model *ml_model = container_of(kobj,
+						     struct ml_lib_model,
+						     kobj);
+	struct ml_lib_feature_attr *ml_model_attr =
+			container_of(attr, struct ml_lib_feature_attr, attr);
+
+	if (!ml_model_attr->store)
+		return -EIO;
+
+	return ml_model_attr->store(ml_model_attr, ml_model, buf, len);
+}
+
+static const struct sysfs_ops ml_model_attr_ops = {
+	.show	= ml_model_attr_show,
+	.store	= ml_model_attr_store,
+};
+
+static inline
+void ml_model_kobj_release(struct kobject *kobj)
+{
+	struct ml_lib_model *ml_model = container_of(kobj,
+						     struct ml_lib_model,
+						     kobj);
+	complete(&ml_model->kobj_unregister);
+}
+
+static struct kobj_type ml_model_ktype = {
+	.default_groups = ml_model_groups,
+	.sysfs_ops	= &ml_model_attr_ops,
+	.release	= ml_model_kobj_release,
+};
+
+int ml_model_create_sysfs_group(struct ml_lib_model *ml_model,
+				struct kobject *subsystem_kobj)
+{
+	int err;
+
+	init_completion(&ml_model->kobj_unregister);
+
+	err = kobject_init_and_add(&ml_model->kobj, &ml_model_ktype,
+				   subsystem_kobj,
+				   "%s", ml_model->model_name);
+	if (err)
+		pr_err("ml_lib: failed to create sysfs group: err %d\n", err);
+
+	return err;
+}
+
+void ml_model_delete_sysfs_group(struct ml_lib_model *ml_model)
+{
+	kobject_del(&ml_model->kobj);
+	kobject_put(&ml_model->kobj);
+	wait_for_completion(&ml_model->kobj_unregister);
+}
diff --git a/lib/ml-lib/sysfs.h b/lib/ml-lib/sysfs.h
new file mode 100644
index 000000000000..6bd3ab64a1c0
--- /dev/null
+++ b/lib/ml-lib/sysfs.h
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Machine Learning (ML) library
+ *
+ * Copyright (C) 2025-2026 Viacheslav Dubeyko <slava@dubeyko.com>
+ */
+
+#ifndef _LINUX_ML_LIB_SYSFS_H
+#define _LINUX_ML_LIB_SYSFS_H
+
+#include <linux/sysfs.h>
+
+int ml_model_create_sysfs_group(struct ml_lib_model *ml_model,
+				struct kobject *subsystem_kobj);
+void ml_model_delete_sysfs_group(struct ml_lib_model *ml_model);
+
+#endif /* _LINUX_ML_LIB_SYSFS_H */
-- 
2.34.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFC PATCH v1 3/4] ml-lib: Implement simple testing character device driver
  2026-02-06 19:11 [RFC PATCH v1 0/4] Machine Learning (ML) library in Linux kernel Viacheslav Dubeyko
  2026-02-06 19:11 ` [RFC PATCH v1 1/4] ml-lib: Introduce Machine Learning (ML) library declarations Viacheslav Dubeyko
  2026-02-06 19:11 ` [RFC PATCH v1 2/4] ml-lib: Implement PoC of Machine Learning (ML) library functionality Viacheslav Dubeyko
@ 2026-02-06 19:11 ` Viacheslav Dubeyko
  2026-02-07 15:55   ` Greg KH
  2026-02-06 19:11 ` [RFC PATCH v1 4/4] ml-lib: Implement simple user-space testing application Viacheslav Dubeyko
  2026-02-06 22:59 ` [RFC PATCH v1 0/4] Machine Learning (ML) library in Linux kernel Jonathan Corbet
  4 siblings, 1 reply; 14+ messages in thread
From: Viacheslav Dubeyko @ 2026-02-06 19:11 UTC (permalink / raw)
  To: linux-fsdevel, linux-mm, bpf; +Cc: Slava.Dubeyko, slava, linux-kernel

Implement simple testing character device driver

Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
---
 lib/ml-lib/test_driver/Kconfig           |  22 +
 lib/ml-lib/test_driver/Makefile          |   5 +
 lib/ml-lib/test_driver/README.md         | 233 ++++++++++
 lib/ml-lib/test_driver/ml_lib_char_dev.c | 530 +++++++++++++++++++++++
 4 files changed, 790 insertions(+)
 create mode 100644 lib/ml-lib/test_driver/Kconfig
 create mode 100644 lib/ml-lib/test_driver/Makefile
 create mode 100644 lib/ml-lib/test_driver/README.md
 create mode 100644 lib/ml-lib/test_driver/ml_lib_char_dev.c

diff --git a/lib/ml-lib/test_driver/Kconfig b/lib/ml-lib/test_driver/Kconfig
new file mode 100644
index 000000000000..183fc1de57a8
--- /dev/null
+++ b/lib/ml-lib/test_driver/Kconfig
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config ML_LIB_TEST_DRIVER
+	tristate "ML library testing character device driver"
+	depends on ML_LIB
+	default n
+	help
+	  This is a ML library testing character device driver for
+	  testing generic ML library functionality. It provides:
+
+	  - Basic read/write operations
+	  - IOCTL interface for device control
+	  - Sysfs attributes for runtime information
+	  - Procfs entry for debugging
+
+	  The driver creates a /dev/mllibdev device node that can be
+	  used to read and write data to a kernel buffer.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mllibdev.
diff --git a/lib/ml-lib/test_driver/Makefile b/lib/ml-lib/test_driver/Makefile
new file mode 100644
index 000000000000..6444bcf8985b
--- /dev/null
+++ b/lib/ml-lib/test_driver/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_ML_LIB_TEST_DRIVER) += ml_lib_test_dev.o
+
+ml_lib_test_dev-y := ml_lib_char_dev.o
diff --git a/lib/ml-lib/test_driver/README.md b/lib/ml-lib/test_driver/README.md
new file mode 100644
index 000000000000..0bb4105c8aa4
--- /dev/null
+++ b/lib/ml-lib/test_driver/README.md
@@ -0,0 +1,233 @@
+# ML Library Testing Device Driver (mllibdev)
+
+ML library testing character device driver for the Linux kernel:
+- Basic read/write operations
+- IOCTL interface for device control
+- Sysfs attributes for runtime information
+- Procfs entry for debugging
+
+## Features
+
+### Character Device Operations
+- **Open/Close**: Device can be opened and closed multiple times
+- **Read**: Read data from a kernel buffer
+- **Write**: Write data to a kernel buffer (1KB capacity)
+- **Seek**: Support for lseek() operations
+
+### IOCTL Commands
+- `ML_LIB_TEST_DEV_IOCRESET`: Clear the device buffer
+- `ML_LIB_TEST_DEV_IOCGETSIZE`: Get current data size
+- `ML_LIB_TEST_DEV_IOCSETSIZE`: Set data size
+
+### Sysfs Attributes
+Located at `/sys/class/ml_lib_test/mllibdev`:
+- `buffer_size`: Maximum buffer capacity (read-only)
+- `data_size`: Current amount of data in buffer (read-only)
+- `access_count`: Number of times device has been opened (read-only)
+- `stats`: Comprehensive statistics (opens, reads, writes)
+
+### Procfs Entry
+Located at `/proc/mllibdev`: Provides formatted driver information
+
+## Building the Driver
+
+### Option 1: Build as a Module
+
+1. Configure the kernel to build mllibdev as a module:
+   ```bash
+   make menuconfig
+   # Navigate to: Library routines -> ML library testing character device driver
+   # Select: <M> ML library testing character device driver
+   ```
+
+2. Build the module:
+   ```bash
+   make -j$(nproc) M=lib/ml-lib/test_driver
+   ```
+
+### Option 2: Build into Kernel
+
+1. Configure the kernel:
+   ```bash
+   make menuconfig
+   # Navigate to: Library routines -> ML library testing character device driver
+   # Select: <*> ML library testing character device driver
+   ```
+
+2. Build the kernel:
+   ```bash
+   make -j$(nproc)
+   ```
+
+### Option 3: Quick Module Build (Out-of-Tree)
+
+For quick testing, you can build just the module:
+
+```bash
+cd lib/ml-lib/test_driver
+make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
+```
+
+## Loading the Driver
+
+If built as a module:
+
+```bash
+# Load the module
+sudo insmod /lib/modules/$(uname -r)/build/lib/ml-lib/test_driver/ml_lib_test_dev.ko
+
+# Verify it's loaded
+sudo lsmod | grep ml_lib_test_dev
+
+# Check kernel messages
+sudo dmesg | tail -20
+```
+
+You should see messages like:
+```
+ml_lib_test_dev: Initializing driver
+ml_lib_test_dev: Device number allocated: XXX:0
+ml_lib_test_dev: Driver initialized successfully
+ml_lib_test_dev: Device created at /dev/mllibdev
+ml_lib_test_dev: Proc entry created at /proc/mllibdev
+```
+
+## Testing the Driver
+
+### Quick Manual Test
+
+```bash
+# Write data to the device
+sudo su
+echo "Hello, kernel!" > /dev/mllibdev
+
+# Read data back
+sudo su
+cat /dev/mllibdev
+
+# Check sysfs attributes
+cat /sys/class/ml_lib_test/mllibdev/stats
+
+# Check proc entry
+cat /proc/mllibdev
+```
+
+### Using the Test Program
+
+1. Compile the test program:
+   ```bash
+   cd lib/ml-lib/test_driver/test_application
+   gcc -o ml_lib_test_dev test_ml_lib_char_dev.c
+   ```
+
+2. Run the test program:
+   ```bash
+   sudo ./ml_lib_test_dev
+   ```
+
+The test program will:
+- Open the device
+- Write test data
+- Read the data back
+- Test all IOCTL commands
+- Display sysfs attributes
+- Show procfs information
+
+### Example Test Output
+
+```
+ML Library Testing Device Driver Test Program
+==================================
+Device opened successfully: /dev/mllibdev
+
+========== Write Test ==========
+Successfully wrote 62 bytes
+Data: "Hello from userspace! This is a test of the mllibdev driver."
+
+========== Read Test ==========
+Successfully read 62 bytes
+Data: "Hello from userspace! This is a test of the mllibdev driver."
+
+========== IOCTL Tests ==========
+Current data size: 62 bytes
+Set data size to: 50 bytes
+Verified new size: 50 bytes
+Buffer reset successfully
+Size after reset: 0 bytes
+
+========== Sysfs Attributes ==========
+buffer_size: 1024
+data_size: 0
+access_count: 1
+
+stats: Opens: 1
+Reads: 1
+Writes: 1
+
+========== Procfs Information ==========
+ML Library Testing Device Driver Information
+=================================
+Device name:     mllibdev
+Buffer size:     1024 bytes
+Data size:       0 bytes
+Access count:    1
+Read count:      1
+Write count:     1
+
+========== Final Test ==========
+All tests completed successfully!
+```
+
+## Unloading the Driver
+
+```bash
+# Remove the module
+sudo rmmod ml_lib_test_dev
+
+# Verify it's unloaded
+sudo lsmod | grep ml_lib_test_dev
+
+# Check cleanup messages
+sudo dmesg | tail -10
+```
+
+## Troubleshooting
+
+### Device node doesn't exist
+```bash
+# Check if udev created the device
+ls -l /dev/mllibdev
+
+# Manually create if needed (shouldn't be necessary)
+sudo mknod /dev/mllibdev c MAJOR MINOR
+```
+
+### Permission denied
+```bash
+# Run commands with sudo
+sudo cat /dev/mllibdev
+
+# Or change permissions
+sudo chmod 666 /dev/mllibdev
+```
+
+### Module won't load
+```bash
+# Check kernel messages for errors
+dmesg | tail -20
+
+# Verify module dependencies
+modinfo lib/ml-lib/test_driver/ml_lib_test_dev.ko
+```
+
+## License
+
+This driver is licensed under GPL-2.0.
+
+## Author
+
+Viacheslav Dubeyko <slava@dubeyko.com>
+
+## Version
+
+1.0
diff --git a/lib/ml-lib/test_driver/ml_lib_char_dev.c b/lib/ml-lib/test_driver/ml_lib_char_dev.c
new file mode 100644
index 000000000000..b2d6e27ece28
--- /dev/null
+++ b/lib/ml-lib/test_driver/ml_lib_char_dev.c
@@ -0,0 +1,530 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Machine Learning (ML) library
+ * Testing Character Device Driver
+ *
+ * Copyright (C) 2025-2026 Viacheslav Dubeyko <slava@dubeyko.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/mutex.h>
+#include <linux/ml-lib/ml_lib.h>
+
+#define DEVICE_NAME "mllibdev"
+#define CLASS_NAME "ml_lib_test"
+#define BUFFER_SIZE 1024
+
+/* IOCTL commands */
+#define ML_LIB_TEST_DEV_IOC_MAGIC   'M'
+#define ML_LIB_TEST_DEV_IOCRESET    _IO(ML_LIB_TEST_DEV_IOC_MAGIC, 0)
+#define ML_LIB_TEST_DEV_IOCGETSIZE  _IOR(ML_LIB_TEST_DEV_IOC_MAGIC, 1, int)
+#define ML_LIB_TEST_DEV_IOCSETSIZE  _IOW(ML_LIB_TEST_DEV_IOC_MAGIC, 2, int)
+
+/* Device data structure */
+struct ml_lib_test_dev_data {
+	struct cdev cdev;
+	struct device *device;
+	char *dataset_buf;
+	size_t dataset_buf_size;
+	size_t dataset_size;
+	char *recommendations_buf;
+	size_t recommendations_buf_size;
+	size_t recommendations_size;
+	struct mutex lock;
+	unsigned long access_count;
+	unsigned long read_count;
+	unsigned long write_count;
+
+	struct ml_lib_model *ml_model1;
+};
+
+#define ML_MODEL_1_NAME "ml_model1"
+
+static
+int ml_lib_test_dev_extract_dataset(struct ml_lib_model *ml_model,
+				    struct ml_lib_dataset *dataset);
+
+static struct ml_lib_dataset_operations ml_lib_test_dev_dataset_ops = {
+	.extract = ml_lib_test_dev_extract_dataset,
+};
+
+static dev_t dev_number;
+static struct class *ml_lib_test_dev_class;
+static struct ml_lib_test_dev_data *dev_data;
+static struct proc_dir_entry *proc_entry;
+
+/* ML model operations */
+static
+int ml_lib_test_dev_extract_dataset(struct ml_lib_model *ml_model,
+				    struct ml_lib_dataset *dataset)
+{
+	struct ml_lib_test_dev_data *data =
+		(struct ml_lib_test_dev_data *)ml_model->parent->private;
+	u8 pattern;
+
+	mutex_lock(&data->lock);
+	get_random_bytes(&pattern, 1);
+	memset(data->dataset_buf, pattern, data->dataset_buf_size);
+	data->dataset_size = data->dataset_buf_size;
+	atomic_set(&dataset->type, ML_LIB_MEMORY_STREAM_DATASET);
+	atomic_set(&dataset->state, ML_LIB_DATASET_CLEAN);
+	dataset->allocated_size = data->dataset_buf_size;
+	dataset->portion_offset = 0;
+	dataset->portion_size = data->dataset_buf_size;
+	mutex_unlock(&data->lock);
+
+	return 0;
+}
+
+/* File operations */
+static int ml_lib_test_dev_open(struct inode *inode, struct file *file)
+{
+	struct ml_lib_test_dev_data *data = container_of(inode->i_cdev,
+						struct ml_lib_test_dev_data,
+						cdev);
+
+	file->private_data = data;
+
+	mutex_lock(&data->lock);
+	data->access_count++;
+	mutex_unlock(&data->lock);
+
+	pr_info("ml_lib_test_dev: Device opened (total opens: %lu)\n",
+		data->access_count);
+
+	return 0;
+}
+
+static int ml_lib_test_dev_release(struct inode *inode, struct file *file)
+{
+	pr_info("ml_lib_test_dev: Device closed\n");
+	return 0;
+}
+
+static ssize_t ml_lib_test_dev_read(struct file *file, char __user *buf,
+				    size_t count, loff_t *ppos)
+{
+	struct ml_lib_test_dev_data *data = file->private_data;
+	size_t to_read;
+	int ret;
+
+	mutex_lock(&data->lock);
+
+	if (*ppos >= data->dataset_size) {
+		mutex_unlock(&data->lock);
+		return 0;
+	}
+
+	to_read = min(count, data->dataset_size - (size_t)*ppos);
+
+	ret = copy_to_user(buf, data->dataset_buf + *ppos, to_read);
+	if (ret) {
+		mutex_unlock(&data->lock);
+		return -EFAULT;
+	}
+
+	*ppos += to_read;
+	data->read_count++;
+
+	mutex_unlock(&data->lock);
+
+	pr_info("ml_lib_test_dev: Read %zu bytes\n", to_read);
+
+	return to_read;
+}
+
+static ssize_t ml_lib_test_dev_write(struct file *file, const char __user *buf,
+				     size_t count, loff_t *ppos)
+{
+	struct ml_lib_test_dev_data *data = file->private_data;
+	size_t to_write;
+	int ret;
+
+	mutex_lock(&data->lock);
+
+	if (*ppos >= data->recommendations_buf_size) {
+		mutex_unlock(&data->lock);
+		return -ENOSPC;
+	}
+
+	to_write = min(count, data->recommendations_buf_size - (size_t)*ppos);
+
+	ret = copy_from_user(data->recommendations_buf + *ppos, buf, to_write);
+	if (ret) {
+		mutex_unlock(&data->lock);
+		return -EFAULT;
+	}
+
+	*ppos += to_write;
+	if (*ppos > data->recommendations_size)
+		data->recommendations_size = *ppos;
+
+	data->write_count++;
+
+	mutex_unlock(&data->lock);
+
+	pr_info("ml_lib_test_dev: Wrote %zu bytes\n", to_write);
+
+	return to_write;
+}
+
+static long ml_lib_test_dev_ioctl(struct file *file, unsigned int cmd,
+				  unsigned long arg)
+{
+	struct ml_lib_test_dev_data *data = file->private_data;
+	int size;
+
+	switch (cmd) {
+	case ML_LIB_TEST_DEV_IOCRESET:
+		mutex_lock(&data->lock);
+		memset(data->dataset_buf,
+			0, data->dataset_buf_size);
+		data->dataset_size = 0;
+		memset(data->recommendations_buf,
+			0, data->recommendations_buf_size);
+		data->recommendations_size = 0;
+		mutex_unlock(&data->lock);
+		pr_info("ml_lib_test_dev: Buffer reset via IOCTL\n");
+		break;
+
+	case ML_LIB_TEST_DEV_IOCGETSIZE:
+		mutex_lock(&data->lock);
+		size = data->dataset_size;
+		mutex_unlock(&data->lock);
+		if (copy_to_user((int __user *)arg, &size, sizeof(size)))
+			return -EFAULT;
+		break;
+
+	case ML_LIB_TEST_DEV_IOCSETSIZE:
+		if (copy_from_user(&size, (int __user *)arg, sizeof(size)))
+			return -EFAULT;
+		if (size < 0 || size > data->recommendations_buf_size)
+			return -EINVAL;
+		mutex_lock(&data->lock);
+		data->recommendations_size = size;
+		mutex_unlock(&data->lock);
+		pr_info("ml_lib_test_dev: Data size set to %d via IOCTL\n", size);
+		break;
+
+	default:
+		return -ENOTTY;
+	}
+
+	return 0;
+}
+
+static const struct file_operations ml_lib_test_dev_fops = {
+	.owner = THIS_MODULE,
+	.open = ml_lib_test_dev_open,
+	.release = ml_lib_test_dev_release,
+	.read = ml_lib_test_dev_read,
+	.write = ml_lib_test_dev_write,
+	.unlocked_ioctl = ml_lib_test_dev_ioctl,
+	.llseek = default_llseek,
+};
+
+/* Sysfs attributes */
+static ssize_t buffer_size_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct ml_lib_test_dev_data *data = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%zu\n", data->dataset_buf_size);
+}
+
+static ssize_t data_size_show(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct ml_lib_test_dev_data *data = dev_get_drvdata(dev);
+	size_t size;
+
+	mutex_lock(&data->lock);
+	size = data->dataset_size;
+	mutex_unlock(&data->lock);
+
+	return sprintf(buf, "%zu\n", size);
+}
+
+static ssize_t access_count_show(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct ml_lib_test_dev_data *data = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%lu\n", data->access_count);
+}
+
+static ssize_t stats_show(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	struct ml_lib_test_dev_data *data = dev_get_drvdata(dev);
+
+	return sprintf(buf, "Opens: %lu\nReads: %lu\nWrites: %lu\n",
+		       data->access_count, data->read_count,
+		       data->write_count);
+}
+
+static DEVICE_ATTR_RO(buffer_size);
+static DEVICE_ATTR_RO(data_size);
+static DEVICE_ATTR_RO(access_count);
+static DEVICE_ATTR_RO(stats);
+
+static struct attribute *ml_lib_test_dev_attrs[] = {
+	&dev_attr_buffer_size.attr,
+	&dev_attr_data_size.attr,
+	&dev_attr_access_count.attr,
+	&dev_attr_stats.attr,
+	NULL,
+};
+
+static const struct attribute_group ml_lib_test_dev_attr_group = {
+	.attrs = ml_lib_test_dev_attrs,
+};
+
+/* Procfs operations */
+static int ml_lib_test_dev_proc_show(struct seq_file *m, void *v)
+{
+	struct ml_lib_test_dev_data *data = dev_data;
+
+	seq_printf(m, "ML Library Testing Device Driver Information\n");
+	seq_printf(m, "=================================\n");
+	seq_printf(m, "Device name:     %s\n", DEVICE_NAME);
+	seq_printf(m, "Buffer size:     %zu bytes\n", data->dataset_buf_size);
+	seq_printf(m, "Data size:       %zu bytes\n", data->dataset_size);
+	seq_printf(m, "Access count:    %lu\n", data->access_count);
+	seq_printf(m, "Read count:      %lu\n", data->read_count);
+	seq_printf(m, "Write count:     %lu\n", data->write_count);
+
+	return 0;
+}
+
+static int ml_lib_test_dev_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ml_lib_test_dev_proc_show, NULL);
+}
+
+static const struct proc_ops ml_lib_test_dev_proc_ops = {
+	.proc_open = ml_lib_test_dev_proc_open,
+	.proc_read = seq_read,
+	.proc_lseek = seq_lseek,
+	.proc_release = single_release,
+};
+
+/* Module initialization */
+static int __init ml_lib_test_dev_init(void)
+{
+	struct ml_lib_model_options *options;
+	int ret;
+
+	pr_info("ml_lib_test_dev: Initializing driver\n");
+
+	/* Allocate device data */
+	dev_data = kzalloc(sizeof(struct ml_lib_test_dev_data), GFP_KERNEL);
+	if (!dev_data)
+		return -ENOMEM;
+
+	/* Allocate dataset buffer */
+	dev_data->dataset_buf = kzalloc(BUFFER_SIZE, GFP_KERNEL);
+	if (!dev_data->dataset_buf) {
+		ret = -ENOMEM;
+		goto err_free_data;
+	}
+
+	dev_data->dataset_buf_size = BUFFER_SIZE;
+	dev_data->dataset_size = 0;
+
+	/* Allocate recomendations buffer */
+	dev_data->recommendations_buf = kzalloc(BUFFER_SIZE, GFP_KERNEL);
+	if (!dev_data->recommendations_buf) {
+		ret = -ENOMEM;
+		goto err_free_dataset_buffer;
+	}
+
+	dev_data->recommendations_buf_size = BUFFER_SIZE;
+	dev_data->recommendations_size = 0;
+
+	mutex_init(&dev_data->lock);
+
+	/* Allocate device number */
+	ret = alloc_chrdev_region(&dev_number, 0, 1, DEVICE_NAME);
+	if (ret < 0) {
+		pr_err("ml_lib_test_dev: Failed to allocate device number\n");
+		goto err_free_recommendations_buffer;
+	}
+
+	pr_info("ml_lib_test_dev: Device number allocated: %d:%d\n",
+		MAJOR(dev_number), MINOR(dev_number));
+
+	/* Create device class */
+	ml_lib_test_dev_class = class_create(CLASS_NAME);
+	if (IS_ERR(ml_lib_test_dev_class)) {
+		ret = PTR_ERR(ml_lib_test_dev_class);
+		pr_err("ml_lib_test_dev: Failed to create class\n");
+		goto err_unregister_chrdev;
+	}
+
+	/* Initialize and add cdev */
+	cdev_init(&dev_data->cdev, &ml_lib_test_dev_fops);
+	dev_data->cdev.owner = THIS_MODULE;
+
+	ret = cdev_add(&dev_data->cdev, dev_number, 1);
+	if (ret < 0) {
+		pr_err("ml_lib_test_dev: Failed to add cdev\n");
+		goto err_class_destroy;
+	}
+
+	/* Create device */
+	dev_data->device = device_create(ml_lib_test_dev_class,
+					 NULL, dev_number,
+					 dev_data, DEVICE_NAME);
+	if (IS_ERR(dev_data->device)) {
+		ret = PTR_ERR(dev_data->device);
+		pr_err("ml_lib_test_dev: Failed to create device\n");
+		goto err_cdev_del;
+	}
+
+	/* Create sysfs attributes */
+	ret = sysfs_create_group(&dev_data->device->kobj,
+				 &ml_lib_test_dev_attr_group);
+	if (ret < 0) {
+		pr_err("ml_lib_test_dev: Failed to create sysfs group\n");
+		goto err_device_destroy;
+	}
+
+	/* Create procfs entry */
+	proc_entry = proc_create(DEVICE_NAME, 0444, NULL,
+				 &ml_lib_test_dev_proc_ops);
+	if (!proc_entry) {
+		pr_err("ml_lib_test_dev: Failed to create proc entry\n");
+		ret = -ENOMEM;
+		goto err_sysfs_remove;
+	}
+
+	dev_data->ml_model1 = allocate_ml_model(sizeof(struct ml_lib_model),
+						GFP_KERNEL);
+	if (IS_ERR(dev_data->ml_model1)) {
+		ret = PTR_ERR(dev_data->ml_model1);
+		pr_err("ml_lib_test_dev: Failed to allocate ML model\n");
+		goto err_procfs_remove;
+	} else if (!dev_data->ml_model1) {
+		ret = -ENOMEM;
+		pr_err("ml_lib_test_dev: Failed to allocate ML model\n");
+		goto err_procfs_remove;
+	}
+
+	ret = ml_model_create(dev_data->ml_model1, CLASS_NAME,
+			      ML_MODEL_1_NAME, &dev_data->device->kobj);
+	if (ret < 0) {
+		pr_err("ml_lib_test_dev: Failed to create ML model\n");
+		goto err_ml_model_free;
+	}
+
+	dev_data->ml_model1->parent->private = dev_data;
+	dev_data->ml_model1->model_ops = NULL;
+	dev_data->ml_model1->dataset_ops = &ml_lib_test_dev_dataset_ops;
+
+	options = allocate_ml_model_options(sizeof(struct ml_lib_model_options),
+					    GFP_KERNEL);
+	if (IS_ERR(options)) {
+		ret = PTR_ERR(options);
+		pr_err("ml_lib_test_dev: Failed to allocate ML model options\n");
+		goto err_ml_model_destroy;
+	} else if (!options) {
+		ret = -ENOMEM;
+		pr_err("ml_lib_test_dev: Failed to allocate ML model options\n");
+		goto err_ml_model_destroy;
+	}
+
+	ret = ml_model_init(dev_data->ml_model1, options);
+	if (ret < 0) {
+		pr_err("ml_lib_test_dev: Failed to init ML model\n");
+		goto err_ml_model_options_free;
+	}
+
+	pr_info("ml_lib_test_dev: Driver initialized successfully\n");
+	pr_info("ml_lib_test_dev: Device created at /dev/%s\n",
+		DEVICE_NAME);
+	pr_info("ml_lib_test_dev: Proc entry created at /proc/%s\n",
+		DEVICE_NAME);
+
+	return 0;
+
+err_ml_model_options_free:
+	free_ml_model_options(options);
+err_ml_model_destroy:
+	ml_model_destroy(dev_data->ml_model1);
+err_ml_model_free:
+	free_ml_model(dev_data->ml_model1);
+err_procfs_remove:
+	proc_remove(proc_entry);
+err_sysfs_remove:
+	sysfs_remove_group(&dev_data->device->kobj,
+			   &ml_lib_test_dev_attr_group);
+err_device_destroy:
+	device_destroy(ml_lib_test_dev_class, dev_number);
+err_cdev_del:
+	cdev_del(&dev_data->cdev);
+err_class_destroy:
+	class_destroy(ml_lib_test_dev_class);
+err_unregister_chrdev:
+	unregister_chrdev_region(dev_number, 1);
+err_free_recommendations_buffer:
+	kfree(dev_data->recommendations_buf);
+err_free_dataset_buffer:
+	kfree(dev_data->dataset_buf);
+err_free_data:
+	kfree(dev_data);
+	return ret;
+}
+
+/* Module cleanup */
+static void __exit ml_lib_test_dev_exit(void)
+{
+	pr_info("ml_lib_test_dev: Cleaning up driver\n");
+
+	/* Destroy ML model */
+	ml_model_destroy(dev_data->ml_model1);
+	free_ml_model(dev_data->ml_model1);
+
+	/* Remove procfs entry */
+	proc_remove(proc_entry);
+
+	/* Remove sysfs attributes */
+	sysfs_remove_group(&dev_data->device->kobj,
+			   &ml_lib_test_dev_attr_group);
+
+	/* Destroy device */
+	device_destroy(ml_lib_test_dev_class, dev_number);
+
+	/* Delete cdev */
+	cdev_del(&dev_data->cdev);
+
+	/* Destroy class */
+	class_destroy(ml_lib_test_dev_class);
+
+	/* Unregister device number */
+	unregister_chrdev_region(dev_number, 1);
+
+	/* Free buffers */
+	kfree(dev_data->recommendations_buf);
+	kfree(dev_data->dataset_buf);
+	kfree(dev_data);
+
+	pr_info("ml_lib_test_dev: Driver removed successfully\n");
+}
+
+module_init(ml_lib_test_dev_init);
+module_exit(ml_lib_test_dev_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Viacheslav Dubeyko <slava@dubeyko.com>");
+MODULE_DESCRIPTION("ML libraray testing character device driver");
+MODULE_VERSION("1.0");
-- 
2.34.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFC PATCH v1 4/4] ml-lib: Implement simple user-space testing application
  2026-02-06 19:11 [RFC PATCH v1 0/4] Machine Learning (ML) library in Linux kernel Viacheslav Dubeyko
                   ` (2 preceding siblings ...)
  2026-02-06 19:11 ` [RFC PATCH v1 3/4] ml-lib: Implement simple testing character device driver Viacheslav Dubeyko
@ 2026-02-06 19:11 ` Viacheslav Dubeyko
  2026-02-06 22:59 ` [RFC PATCH v1 0/4] Machine Learning (ML) library in Linux kernel Jonathan Corbet
  4 siblings, 0 replies; 14+ messages in thread
From: Viacheslav Dubeyko @ 2026-02-06 19:11 UTC (permalink / raw)
  To: linux-fsdevel, linux-mm, bpf; +Cc: Slava.Dubeyko, slava, linux-kernel

Implement simple user-space testing application

Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
---
 .../test_application/ml_lib_char_dev_ioctl.h  |  21 ++
 .../test_application/test_ml_lib_char_dev.c   | 206 ++++++++++++++++++
 2 files changed, 227 insertions(+)
 create mode 100644 lib/ml-lib/test_driver/test_application/ml_lib_char_dev_ioctl.h
 create mode 100644 lib/ml-lib/test_driver/test_application/test_ml_lib_char_dev.c

diff --git a/lib/ml-lib/test_driver/test_application/ml_lib_char_dev_ioctl.h b/lib/ml-lib/test_driver/test_application/ml_lib_char_dev_ioctl.h
new file mode 100644
index 000000000000..7ea74e840fda
--- /dev/null
+++ b/lib/ml-lib/test_driver/test_application/ml_lib_char_dev_ioctl.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Machine Learning (ML) library
+ *
+ * Userspace API for ml_lib_dev testing driver
+ *
+ * Copyright (C) 2025-2026 Viacheslav Dubeyko <slava@dubeyko.com>
+ */
+
+#ifndef _ML_LIB_TEST_DEV_IOCTL_H
+#define _ML_LIB_TEST_DEV_IOCTL_H
+
+#include <linux/ioctl.h>
+
+/* IOCTL commands */
+#define ML_LIB_TEST_DEV_IOC_MAGIC   'M'
+#define ML_LIB_TEST_DEV_IOCRESET    _IO(ML_LIB_TEST_DEV_IOC_MAGIC, 0)
+#define ML_LIB_TEST_DEV_IOCGETSIZE  _IOR(ML_LIB_TEST_DEV_IOC_MAGIC, 1, int)
+#define ML_LIB_TEST_DEV_IOCSETSIZE  _IOW(ML_LIB_TEST_DEV_IOC_MAGIC, 2, int)
+
+#endif /* _ML_LIB_TEST_DEV_IOCTL_H */
diff --git a/lib/ml-lib/test_driver/test_application/test_ml_lib_char_dev.c b/lib/ml-lib/test_driver/test_application/test_ml_lib_char_dev.c
new file mode 100644
index 000000000000..432b8a0ad068
--- /dev/null
+++ b/lib/ml-lib/test_driver/test_application/test_ml_lib_char_dev.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Machine Learning (ML) library
+ *
+ * Test program for ml_lib_dev testing driver
+ *
+ * Copyright (C) 2025-2026 Viacheslav Dubeyko <slava@dubeyko.com>
+ *
+ * Compile with: gcc -o test_ml_lib_char_dev test_ml_lib_char_dev.c
+ * Run with:     sudo ./test_ml_lib_char_dev
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include "ml_lib_char_dev_ioctl.h"
+
+#define DEVICE_PATH "/dev/mllibdev"
+#define SYSFS_BASE "/sys/class/ml_lib_test/mllibdev"
+#define PROC_PATH "/proc/mllibdev"
+
+static void print_separator(const char *title)
+{
+	printf("\n========== %s ==========\n", title);
+}
+
+static void read_sysfs_attr(const char *attr_name)
+{
+	char path[256];
+	char buffer[256];
+	FILE *fp;
+
+	snprintf(path, sizeof(path), "%s/%s", SYSFS_BASE, attr_name);
+	fp = fopen(path, "r");
+	if (!fp) {
+		perror("Failed to open sysfs attribute");
+		return;
+	}
+
+	if (fgets(buffer, sizeof(buffer), fp)) {
+		printf("  %s: %s", attr_name, buffer);
+	}
+
+	fclose(fp);
+}
+
+static void show_sysfs_info(void)
+{
+	print_separator("Sysfs Attributes");
+	read_sysfs_attr("buffer_size");
+	read_sysfs_attr("data_size");
+	read_sysfs_attr("access_count");
+	printf("\n");
+	read_sysfs_attr("stats");
+}
+
+static void show_proc_info(void)
+{
+	char buffer[1024];
+	FILE *fp;
+
+	print_separator("Procfs Information");
+
+	fp = fopen(PROC_PATH, "r");
+	if (!fp) {
+		perror("Failed to open procfs entry");
+		return;
+	}
+
+	while (fgets(buffer, sizeof(buffer), fp)) {
+		printf("%s", buffer);
+	}
+
+	fclose(fp);
+}
+
+static void test_write(int fd)
+{
+	const char *test_data = "Hello from userspace! This is a test of the mllibdev driver.";
+	ssize_t ret;
+
+	print_separator("Write Test");
+
+	ret = write(fd, test_data, strlen(test_data));
+	if (ret < 0) {
+		perror("Write failed");
+		return;
+	}
+
+	printf("Successfully wrote %zd bytes\n", ret);
+	printf("Data: \"%s\"\n", test_data);
+}
+
+static void test_read(int fd)
+{
+	char buffer[256];
+	ssize_t ret;
+
+	print_separator("Read Test");
+
+	/* Seek to beginning */
+	lseek(fd, 0, SEEK_SET);
+
+	ret = read(fd, buffer, sizeof(buffer) - 1);
+	if (ret < 0) {
+		perror("Read failed");
+		return;
+	}
+
+	buffer[ret] = '\0';
+	printf("Successfully read %zd bytes\n", ret);
+	printf("Data: \"%s\"\n", buffer);
+}
+
+static void test_ioctl(int fd)
+{
+	int size;
+	int ret;
+
+	print_separator("IOCTL Tests");
+
+	/* Get current size */
+	ret = ioctl(fd, ML_LIB_TEST_DEV_IOCGETSIZE, &size);
+	if (ret < 0) {
+		perror("IOCTL GETSIZE failed");
+		return;
+	}
+	printf("Current data size: %d bytes\n", size);
+
+	/* Set new size */
+	size = 50;
+	ret = ioctl(fd, ML_LIB_TEST_DEV_IOCSETSIZE, &size);
+	if (ret < 0) {
+		perror("IOCTL SETSIZE failed");
+		return;
+	}
+	printf("Set data size to: %d bytes\n", size);
+
+	/* Verify new size */
+	ret = ioctl(fd, ML_LIB_TEST_DEV_IOCGETSIZE, &size);
+	if (ret < 0) {
+		perror("IOCTL GETSIZE failed");
+		return;
+	}
+	printf("Verified new size: %d bytes\n", size);
+
+	/* Reset buffer */
+	ret = ioctl(fd, ML_LIB_TEST_DEV_IOCRESET);
+	if (ret < 0) {
+		perror("IOCTL RESET failed");
+		return;
+	}
+	printf("Buffer reset successfully\n");
+
+	/* Verify size after reset */
+	ret = ioctl(fd, ML_LIB_TEST_DEV_IOCGETSIZE, &size);
+	if (ret < 0) {
+		perror("IOCTL GETSIZE failed");
+		return;
+	}
+	printf("Size after reset: %d bytes\n", size);
+}
+
+int main(void)
+{
+	int fd;
+
+	printf("ML Library Testing Device Driver Test Program\n");
+	printf("==================================\n");
+
+	/* Open the device */
+	fd = open(DEVICE_PATH, O_RDWR);
+	if (fd < 0) {
+		perror("Failed to open device");
+		printf("\nMake sure:\n");
+		printf("1. The driver module is loaded (lsmod | grep mllibdev)\n");
+		printf("2. You have proper permissions (run with sudo)\n");
+		printf("3. The device node exists (ls -l /dev/mllibdev)\n");
+		return 1;
+	}
+
+	printf("Device opened successfully: %s\n", DEVICE_PATH);
+
+	/* Run tests */
+	test_write(fd);
+	test_read(fd);
+	test_ioctl(fd);
+
+	/* Show sysfs and proc information */
+	show_sysfs_info();
+	show_proc_info();
+
+	/* Final stats */
+	print_separator("Final Test");
+	printf("All tests completed successfully!\n\n");
+
+	/* Close the device */
+	close(fd);
+
+	return 0;
+}
-- 
2.34.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH v1 0/4] Machine Learning (ML) library in Linux kernel
  2026-02-06 19:11 [RFC PATCH v1 0/4] Machine Learning (ML) library in Linux kernel Viacheslav Dubeyko
                   ` (3 preceding siblings ...)
  2026-02-06 19:11 ` [RFC PATCH v1 4/4] ml-lib: Implement simple user-space testing application Viacheslav Dubeyko
@ 2026-02-06 22:59 ` Jonathan Corbet
  2026-02-09 20:33   ` Viacheslav Dubeyko
  4 siblings, 1 reply; 14+ messages in thread
From: Jonathan Corbet @ 2026-02-06 22:59 UTC (permalink / raw)
  To: Viacheslav Dubeyko, linux-fsdevel, linux-mm, bpf
  Cc: Slava.Dubeyko, slava, linux-kernel

Viacheslav Dubeyko <slava@dubeyko.com> writes:

> This patchset introduces initial vision of Machine Learning (ML) library
> in Linux kernel. It is an effort to define the ML library API and
> to elaborate the way of running ML models in Linux kernel.

I went looking for the documentation files ... but then I've always been
known as an optimist.  That would be a nice thing to fill in.

Perhaps more important, though, would be a real user for this facility.
You must certainly have one in mind, can we see it to get a sense for
how this library is meant to be used?

Thanks,

jon


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH v1 1/4] ml-lib: Introduce Machine Learning (ML) library declarations
  2026-02-06 19:11 ` [RFC PATCH v1 1/4] ml-lib: Introduce Machine Learning (ML) library declarations Viacheslav Dubeyko
@ 2026-02-07 15:52   ` Greg KH
  2026-02-09 20:48     ` Viacheslav Dubeyko
  0 siblings, 1 reply; 14+ messages in thread
From: Greg KH @ 2026-02-07 15:52 UTC (permalink / raw)
  To: Viacheslav Dubeyko
  Cc: linux-fsdevel, linux-mm, bpf, Slava.Dubeyko, linux-kernel

On Fri, Feb 06, 2026 at 11:11:33AM -0800, Viacheslav Dubeyko wrote:
> + * @kobj: /sys/<subsystem>/<ml_model>/ ML model object
> + * @kobj_unregister: completion state for <ml_model> kernel object
> + */
> +struct ml_lib_model {
> +	atomic_t mode;
> +	atomic_t state;
> +	const char *subsystem_name;
> +	const char *model_name;
> +
> +	struct ml_lib_subsystem *parent;
> +
> +	spinlock_t parent_state_lock;
> +	struct ml_lib_subsystem_state * __rcu parent_state;
> +
> +	spinlock_t options_lock;
> +	struct ml_lib_model_options * __rcu options;
> +
> +	spinlock_t dataset_lock;
> +	struct ml_lib_dataset * __rcu dataset;
> +
> +	struct ml_lib_model_operations *model_ops;
> +	struct ml_lib_subsystem_state_operations *system_state_ops;
> +	struct ml_lib_dataset_operations *dataset_ops;
> +	struct ml_lib_request_config_operations *request_config_ops;
> +
> +	/* /sys/<subsystem>/<ml_model>/ */
> +	struct kobject kobj;
> +	struct completion kobj_unregister;
> +};

Do NOT abuse sysfs for something like this.  Please make your own
filesystem or char device or something else, but this is not what sysfs
is for at all, sorry.

greg k-h


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH v1 3/4] ml-lib: Implement simple testing character device driver
  2026-02-06 19:11 ` [RFC PATCH v1 3/4] ml-lib: Implement simple testing character device driver Viacheslav Dubeyko
@ 2026-02-07 15:55   ` Greg KH
  2026-02-09 20:56     ` Viacheslav Dubeyko
  0 siblings, 1 reply; 14+ messages in thread
From: Greg KH @ 2026-02-07 15:55 UTC (permalink / raw)
  To: Viacheslav Dubeyko
  Cc: linux-fsdevel, linux-mm, bpf, Slava.Dubeyko, linux-kernel

On Fri, Feb 06, 2026 at 11:11:35AM -0800, Viacheslav Dubeyko wrote:
> Implement simple testing character device driver
> 
> Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>

It's hard to tell if this is just an early april-fools joke or not, but
if it's not:

> +### Character Device Operations
> +- **Open/Close**: Device can be opened and closed multiple times
> +- **Read**: Read data from a kernel buffer
> +- **Write**: Write data to a kernel buffer (1KB capacity)
> +- **Seek**: Support for lseek() operations
> +
> +### IOCTL Commands
> +- `ML_LIB_TEST_DEV_IOCRESET`: Clear the device buffer
> +- `ML_LIB_TEST_DEV_IOCGETSIZE`: Get current data size
> +- `ML_LIB_TEST_DEV_IOCSETSIZE`: Set data size
> +
> +### Sysfs Attributes
> +Located at `/sys/class/ml_lib_test/mllibdev`:
> +- `buffer_size`: Maximum buffer capacity (read-only)
> +- `data_size`: Current amount of data in buffer (read-only)
> +- `access_count`: Number of times device has been opened (read-only)
> +- `stats`: Comprehensive statistics (opens, reads, writes)

Again, this is not an acceptable use of sysfs.

> +	/* Allocate device number */
> +	ret = alloc_chrdev_region(&dev_number, 0, 1, DEVICE_NAME);

Don't burn a cdev for this, please use the misc device api.

good luck!

greg k-h


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [RFC PATCH v1 0/4] Machine Learning (ML) library in Linux kernel
  2026-02-06 22:59 ` [RFC PATCH v1 0/4] Machine Learning (ML) library in Linux kernel Jonathan Corbet
@ 2026-02-09 20:33   ` Viacheslav Dubeyko
  0 siblings, 0 replies; 14+ messages in thread
From: Viacheslav Dubeyko @ 2026-02-09 20:33 UTC (permalink / raw)
  To: linux-mm, corbet, slava, linux-fsdevel, bpf; +Cc: linux-kernel

On Fri, 2026-02-06 at 15:59 -0700, Jonathan Corbet wrote:
> Viacheslav Dubeyko <slava@dubeyko.com> writes:
> 
> > This patchset introduces initial vision of Machine Learning (ML) library
> > in Linux kernel. It is an effort to define the ML library API and
> > to elaborate the way of running ML models in Linux kernel.
> 
> I went looking for the documentation files ... but then I've always been
> known as an optimist.  That would be a nice thing to fill in.

Yeah, I can see your pain. :) I totally agree that documentation is necessary.
This patchset is only the first small step to share and discuss with the
community. I am sharing the initial vision of the idea and API with the hope to
have the review and discussion. If the API vision makes sense and it looks good,
then it makes sense to prepare documentation. I am planning to have the
documentation after checking the whole infrastructure with a real-life use-
case(s).

> 
> Perhaps more important, though, would be a real user for this facility.
> You must certainly have one in mind, can we see it to get a sense for
> how this library is meant to be used?

I believe there are multiple potential real-life use-cases. Currently, I have
implemented very simple testing driver that generates random numbers and,
potentially, some ML model can be trained on this "mess". :) But it's not very
interesting example. As a next step, I am considering to use this ML library
infrastructure for: (1) GC subsystem in LFS file systems (NILFS2, F2FS, SSDFS),
(2) ML-based DAMON extension with the goal to check the whole idea for real-life
use-cases.

So, let me make the next step and we will be able to discuss this ML library for
real-life use-cases. But the main approach is the collaboration of kernel
subsystem and ML model running in user-space.

Thanks,
Slava.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [RFC PATCH v1 1/4] ml-lib: Introduce Machine Learning (ML) library declarations
  2026-02-07 15:52   ` Greg KH
@ 2026-02-09 20:48     ` Viacheslav Dubeyko
  2026-02-10  5:20       ` gregkh
  0 siblings, 1 reply; 14+ messages in thread
From: Viacheslav Dubeyko @ 2026-02-09 20:48 UTC (permalink / raw)
  To: gregkh, slava; +Cc: linux-mm, linux-fsdevel, linux-kernel, bpf

On Sat, 2026-02-07 at 16:52 +0100, Greg KH wrote:
> On Fri, Feb 06, 2026 at 11:11:33AM -0800, Viacheslav Dubeyko wrote:
> > + * @kobj: /sys/<subsystem>/<ml_model>/ ML model object
> > + * @kobj_unregister: completion state for <ml_model> kernel object
> > + */
> > +struct ml_lib_model {
> > +	atomic_t mode;
> > +	atomic_t state;
> > +	const char *subsystem_name;
> > +	const char *model_name;
> > +
> > +	struct ml_lib_subsystem *parent;
> > +
> > +	spinlock_t parent_state_lock;
> > +	struct ml_lib_subsystem_state * __rcu parent_state;
> > +
> > +	spinlock_t options_lock;
> > +	struct ml_lib_model_options * __rcu options;
> > +
> > +	spinlock_t dataset_lock;
> > +	struct ml_lib_dataset * __rcu dataset;
> > +
> > +	struct ml_lib_model_operations *model_ops;
> > +	struct ml_lib_subsystem_state_operations *system_state_ops;
> > +	struct ml_lib_dataset_operations *dataset_ops;
> > +	struct ml_lib_request_config_operations *request_config_ops;
> > +
> > +	/* /sys/<subsystem>/<ml_model>/ */
> > +	struct kobject kobj;
> > +	struct completion kobj_unregister;
> > +};
> 
> Do NOT abuse sysfs for something like this.  Please make your own
> filesystem or char device or something else, but this is not what sysfs
> is for at all, sorry.
> 

Currently, sysfs entry is used for sending commands (start, stop,
prepare_dataset, discard_dataset) from user-space on the kernel-space side. And
the intention of using sysfs entries is the export information about kernel
subsystem and exchanging by commands and notifications between user-space and
kernel-space sides. Do you mean that it is wrong using of sysfs? Have I
misunderstood your point?

Thanks,
Slava.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [RFC PATCH v1 3/4] ml-lib: Implement simple testing character device driver
  2026-02-07 15:55   ` Greg KH
@ 2026-02-09 20:56     ` Viacheslav Dubeyko
  2026-02-10  5:21       ` greg
  0 siblings, 1 reply; 14+ messages in thread
From: Viacheslav Dubeyko @ 2026-02-09 20:56 UTC (permalink / raw)
  To: greg, slava; +Cc: linux-mm, linux-fsdevel, linux-kernel, bpf

On Sat, 2026-02-07 at 16:55 +0100, Greg KH wrote:
> On Fri, Feb 06, 2026 at 11:11:35AM -0800, Viacheslav Dubeyko wrote:
> > Implement simple testing character device driver
> > 
> > Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
> 
> It's hard to tell if this is just an early april-fools joke or not, but
> if it's not:
> 
> > +### Character Device Operations
> > +- **Open/Close**: Device can be opened and closed multiple times
> > +- **Read**: Read data from a kernel buffer
> > +- **Write**: Write data to a kernel buffer (1KB capacity)
> > +- **Seek**: Support for lseek() operations
> > +
> > +### IOCTL Commands
> > +- `ML_LIB_TEST_DEV_IOCRESET`: Clear the device buffer
> > +- `ML_LIB_TEST_DEV_IOCGETSIZE`: Get current data size
> > +- `ML_LIB_TEST_DEV_IOCSETSIZE`: Set data size
> > +
> > +### Sysfs Attributes
> > +Located at `/sys/class/ml_lib_test/mllibdev`:
> > +- `buffer_size`: Maximum buffer capacity (read-only)
> > +- `data_size`: Current amount of data in buffer (read-only)
> > +- `access_count`: Number of times device has been opened (read-only)
> > +- `stats`: Comprehensive statistics (opens, reads, writes)
> 
> Again, this is not an acceptable use of sysfs.

Maybe, I am missing your point. Are you assuming that I am going to share huge
pieces of data by means of sysfs? If so, then I am not going to use sysfs for
it.

> 
> > +	/* Allocate device number */
> > +	ret = alloc_chrdev_region(&dev_number, 0, 1, DEVICE_NAME);
> 
> Don't burn a cdev for this, please use the misc device api.
> 

It is not real-life driver. It is only testing driver with the goal to
check/test the ML library infrastructure and to show the potential way of using
the ML library.

As the next step, I am planning to use the ML library for two potential real-
life use-case: (1) GC subsystem of LFS file system, (2) ML-based DAMON approach.

So, this driver is only testing engine of implementing and testing the vision of
ML library.

Thanks,
Slava.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH v1 1/4] ml-lib: Introduce Machine Learning (ML) library declarations
  2026-02-09 20:48     ` Viacheslav Dubeyko
@ 2026-02-10  5:20       ` gregkh
  2026-02-10 22:44         ` Viacheslav Dubeyko
  0 siblings, 1 reply; 14+ messages in thread
From: gregkh @ 2026-02-10  5:20 UTC (permalink / raw)
  To: Viacheslav Dubeyko; +Cc: slava, linux-mm, linux-fsdevel, linux-kernel, bpf

On Mon, Feb 09, 2026 at 08:48:17PM +0000, Viacheslav Dubeyko wrote:
> On Sat, 2026-02-07 at 16:52 +0100, Greg KH wrote:
> > On Fri, Feb 06, 2026 at 11:11:33AM -0800, Viacheslav Dubeyko wrote:
> > > + * @kobj: /sys/<subsystem>/<ml_model>/ ML model object
> > > + * @kobj_unregister: completion state for <ml_model> kernel object
> > > + */
> > > +struct ml_lib_model {
> > > +	atomic_t mode;
> > > +	atomic_t state;
> > > +	const char *subsystem_name;
> > > +	const char *model_name;
> > > +
> > > +	struct ml_lib_subsystem *parent;
> > > +
> > > +	spinlock_t parent_state_lock;
> > > +	struct ml_lib_subsystem_state * __rcu parent_state;
> > > +
> > > +	spinlock_t options_lock;
> > > +	struct ml_lib_model_options * __rcu options;
> > > +
> > > +	spinlock_t dataset_lock;
> > > +	struct ml_lib_dataset * __rcu dataset;
> > > +
> > > +	struct ml_lib_model_operations *model_ops;
> > > +	struct ml_lib_subsystem_state_operations *system_state_ops;
> > > +	struct ml_lib_dataset_operations *dataset_ops;
> > > +	struct ml_lib_request_config_operations *request_config_ops;
> > > +
> > > +	/* /sys/<subsystem>/<ml_model>/ */
> > > +	struct kobject kobj;
> > > +	struct completion kobj_unregister;
> > > +};
> > 
> > Do NOT abuse sysfs for something like this.  Please make your own
> > filesystem or char device or something else, but this is not what sysfs
> > is for at all, sorry.
> > 
> 
> Currently, sysfs entry is used for sending commands (start, stop,
> prepare_dataset, discard_dataset) from user-space on the kernel-space side. And
> the intention of using sysfs entries is the export information about kernel
> subsystem and exchanging by commands and notifications between user-space and
> kernel-space sides. Do you mean that it is wrong using of sysfs? Have I
> misunderstood your point?

Yes, this is NOT the correct use of sysfs, do NOT use it for an api like
this at all.  Use the correct ones instead.

thanks,

greg k-h


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH v1 3/4] ml-lib: Implement simple testing character device driver
  2026-02-09 20:56     ` Viacheslav Dubeyko
@ 2026-02-10  5:21       ` greg
  0 siblings, 0 replies; 14+ messages in thread
From: greg @ 2026-02-10  5:21 UTC (permalink / raw)
  To: Viacheslav Dubeyko; +Cc: slava, linux-mm, linux-fsdevel, linux-kernel, bpf

On Mon, Feb 09, 2026 at 08:56:47PM +0000, Viacheslav Dubeyko wrote:
> On Sat, 2026-02-07 at 16:55 +0100, Greg KH wrote:
> > On Fri, Feb 06, 2026 at 11:11:35AM -0800, Viacheslav Dubeyko wrote:
> > > Implement simple testing character device driver
> > > 
> > > Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
> > 
> > It's hard to tell if this is just an early april-fools joke or not, but
> > if it's not:
> > 
> > > +### Character Device Operations
> > > +- **Open/Close**: Device can be opened and closed multiple times
> > > +- **Read**: Read data from a kernel buffer
> > > +- **Write**: Write data to a kernel buffer (1KB capacity)
> > > +- **Seek**: Support for lseek() operations
> > > +
> > > +### IOCTL Commands
> > > +- `ML_LIB_TEST_DEV_IOCRESET`: Clear the device buffer
> > > +- `ML_LIB_TEST_DEV_IOCGETSIZE`: Get current data size
> > > +- `ML_LIB_TEST_DEV_IOCSETSIZE`: Set data size
> > > +
> > > +### Sysfs Attributes
> > > +Located at `/sys/class/ml_lib_test/mllibdev`:
> > > +- `buffer_size`: Maximum buffer capacity (read-only)
> > > +- `data_size`: Current amount of data in buffer (read-only)
> > > +- `access_count`: Number of times device has been opened (read-only)
> > > +- `stats`: Comprehensive statistics (opens, reads, writes)
> > 
> > Again, this is not an acceptable use of sysfs.
> 
> Maybe, I am missing your point. Are you assuming that I am going to share huge
> pieces of data by means of sysfs? If so, then I am not going to use sysfs for
> it.

Please do not use sysfs for this at all.

> > > +	/* Allocate device number */
> > > +	ret = alloc_chrdev_region(&dev_number, 0, 1, DEVICE_NAME);
> > 
> > Don't burn a cdev for this, please use the misc device api.
> > 
> 
> It is not real-life driver. It is only testing driver with the goal to
> check/test the ML library infrastructure and to show the potential way of using
> the ML library.
> 
> As the next step, I am planning to use the ML library for two potential real-
> life use-case: (1) GC subsystem of LFS file system, (2) ML-based DAMON approach.
> 
> So, this driver is only testing engine of implementing and testing the vision of
> ML library.

We don't take code that uses apis incorrectly. Please do not use a cdev
for this type of "testing" driver, that is the incorrect thing to do and
actually makes your code more complex than it needs to.

good luck!

greg k-h


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [RFC PATCH v1 1/4] ml-lib: Introduce Machine Learning (ML) library declarations
  2026-02-10  5:20       ` gregkh
@ 2026-02-10 22:44         ` Viacheslav Dubeyko
  0 siblings, 0 replies; 14+ messages in thread
From: Viacheslav Dubeyko @ 2026-02-10 22:44 UTC (permalink / raw)
  To: gregkh; +Cc: linux-mm, slava, linux-fsdevel, linux-kernel, bpf

On Tue, 2026-02-10 at 06:20 +0100, gregkh@linuxfoundation.org wrote:
> On Mon, Feb 09, 2026 at 08:48:17PM +0000, Viacheslav Dubeyko wrote:
> > On Sat, 2026-02-07 at 16:52 +0100, Greg KH wrote:
> > > On Fri, Feb 06, 2026 at 11:11:33AM -0800, Viacheslav Dubeyko wrote:
> > > > + * @kobj: /sys/<subsystem>/<ml_model>/ ML model object
> > > > + * @kobj_unregister: completion state for <ml_model> kernel object
> > > > + */
> > > > +struct ml_lib_model {
> > > > +	atomic_t mode;
> > > > +	atomic_t state;
> > > > +	const char *subsystem_name;
> > > > +	const char *model_name;
> > > > +
> > > > +	struct ml_lib_subsystem *parent;
> > > > +
> > > > +	spinlock_t parent_state_lock;
> > > > +	struct ml_lib_subsystem_state * __rcu parent_state;
> > > > +
> > > > +	spinlock_t options_lock;
> > > > +	struct ml_lib_model_options * __rcu options;
> > > > +
> > > > +	spinlock_t dataset_lock;
> > > > +	struct ml_lib_dataset * __rcu dataset;
> > > > +
> > > > +	struct ml_lib_model_operations *model_ops;
> > > > +	struct ml_lib_subsystem_state_operations *system_state_ops;
> > > > +	struct ml_lib_dataset_operations *dataset_ops;
> > > > +	struct ml_lib_request_config_operations *request_config_ops;
> > > > +
> > > > +	/* /sys/<subsystem>/<ml_model>/ */
> > > > +	struct kobject kobj;
> > > > +	struct completion kobj_unregister;
> > > > +};
> > > 
> > > Do NOT abuse sysfs for something like this.  Please make your own
> > > filesystem or char device or something else, but this is not what sysfs
> > > is for at all, sorry.
> > > 
> > 
> > Currently, sysfs entry is used for sending commands (start, stop,
> > prepare_dataset, discard_dataset) from user-space on the kernel-space side. And
> > the intention of using sysfs entries is the export information about kernel
> > subsystem and exchanging by commands and notifications between user-space and
> > kernel-space sides. Do you mean that it is wrong using of sysfs? Have I
> > misunderstood your point?
> 
> Yes, this is NOT the correct use of sysfs, do NOT use it for an api like
> this at all.  Use the correct ones instead.
> 
> 

So, to summarize your recommendations:
(1) Do not use sysfs;
(2) Do not use character device but misc device instead;
(3) Implement specialized file system;
(4) eBPF?

Would you like to share any other recommendations?

Thanks,
Slava.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-02-10 22:44 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-06 19:11 [RFC PATCH v1 0/4] Machine Learning (ML) library in Linux kernel Viacheslav Dubeyko
2026-02-06 19:11 ` [RFC PATCH v1 1/4] ml-lib: Introduce Machine Learning (ML) library declarations Viacheslav Dubeyko
2026-02-07 15:52   ` Greg KH
2026-02-09 20:48     ` Viacheslav Dubeyko
2026-02-10  5:20       ` gregkh
2026-02-10 22:44         ` Viacheslav Dubeyko
2026-02-06 19:11 ` [RFC PATCH v1 2/4] ml-lib: Implement PoC of Machine Learning (ML) library functionality Viacheslav Dubeyko
2026-02-06 19:11 ` [RFC PATCH v1 3/4] ml-lib: Implement simple testing character device driver Viacheslav Dubeyko
2026-02-07 15:55   ` Greg KH
2026-02-09 20:56     ` Viacheslav Dubeyko
2026-02-10  5:21       ` greg
2026-02-06 19:11 ` [RFC PATCH v1 4/4] ml-lib: Implement simple user-space testing application Viacheslav Dubeyko
2026-02-06 22:59 ` [RFC PATCH v1 0/4] Machine Learning (ML) library in Linux kernel Jonathan Corbet
2026-02-09 20:33   ` Viacheslav Dubeyko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox