1 /*
2 * Copyright (C) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include <linux/module.h>
20 #include <linux/kernel.h>
21 #include <linux/printk.h>
22 #include <linux/kthread.h>
23 #include <linux/slab.h>
24 #include <linux/version.h>
25 #include <linux/sched.h>
26 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
27 #include <uapi/linux/sched/types.h>
28 #endif
29 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
30 #include <linux/sched/types.h>
31 #endif
32
33 #include "hi_osal.h"
34 #include "securec.h"
35
osal_kthread_create(osal_kthread_handler handler,void * data,const char * name,unsigned int stack_size)36 osal_task *osal_kthread_create(osal_kthread_handler handler, void *data, const char *name, unsigned int stack_size)
37 {
38 struct task_struct *k = NULL;
39 errno_t err;
40
41 osal_task *p = (osal_task *)kmalloc(sizeof(osal_task), GFP_KERNEL);
42 if (p == NULL) {
43 osal_printk("%s - kmalloc error!\n", __FUNCTION__);
44 return NULL;
45 }
46
47 err = memset_s(p, sizeof(osal_task), 0, sizeof(osal_task));
48 if (err != EOK) {
49 kfree(p);
50 osal_printk("memset_s is failed.\n");
51 return NULL;
52 }
53
54 k = kthread_run(handler, data, name);
55 if (IS_ERR(k)) {
56 osal_printk("%s - kthread create error!\n", __FUNCTION__);
57 kfree(p);
58 return NULL;
59 }
60 p->task = k;
61 return p;
62 }
63 EXPORT_SYMBOL(osal_kthread_create);
64
osal_kthread_set_priority(osal_task * task,osal_task_priority priority)65 void osal_kthread_set_priority(osal_task *task, osal_task_priority priority)
66 {
67 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0))
68 struct sched_param param;
69
70 switch (priority) {
71 case OSAL_TASK_PRIORITY_HIGH:
72 param.sched_priority = 99; // 99 is priority
73 break;
74 case OSAL_TASK_PRIORITY_MIDDLE:
75 param.sched_priority = 50; // 50 is priority
76 break;
77 case OSAL_TASK_PRIORITY_LOW:
78 param.sched_priority = 10; // 10 is priority
79 break;
80 default:
81 return;
82 }
83
84 sched_setscheduler(task->task, SCHED_RR, ¶m);
85 #endif
86 }
87 EXPORT_SYMBOL(osal_kthread_set_priority);
88
osal_kthread_set_affinity(osal_task * task,int cpu_mask)89 void osal_kthread_set_affinity(osal_task *task, int cpu_mask)
90 {
91 struct cpumask cpumask_set;
92
93 if (task == NULL) {
94 return;
95 }
96
97 if (cpu_mask == 0) {
98 return;
99 }
100
101 cpumask_clear(&cpumask_set);
102
103 ((OSAL_CPU_0 & (unsigned int)cpu_mask) == 0) ?
104 0 : cpumask_set_cpu(0, &cpumask_set);
105
106 ((OSAL_CPU_1 & (unsigned int)cpu_mask) == 0) ?
107 0 : cpumask_set_cpu(1, &cpumask_set);
108
109 ((OSAL_CPU_2 & (unsigned int)cpu_mask) == 0) ?
110 0 : cpumask_set_cpu(2, &cpumask_set); /* cpu2 */
111
112 ((OSAL_CPU_3 & (unsigned int)cpu_mask) == 0) ?
113 0 : cpumask_set_cpu(3, &cpumask_set); /* cpu3 */
114 }
115 EXPORT_SYMBOL(osal_kthread_set_affinity);
116
osal_kthread_should_stop(void)117 int osal_kthread_should_stop(void)
118 {
119 return kthread_should_stop();
120 }
121 EXPORT_SYMBOL(osal_kthread_should_stop);
122
osal_kthread_destroy(osal_task * task,unsigned int stop_flag)123 void osal_kthread_destroy(osal_task *task, unsigned int stop_flag)
124 {
125 if (task == NULL) {
126 osal_printk("%s - parameter invalid!\n", __FUNCTION__);
127 return;
128 }
129 /* note: When you call the Kthread_stop function, the thread function cannot be finished, otherwise it will oops. */
130 if (stop_flag != 0) {
131 kthread_stop ((struct task_struct *)(task->task));
132 }
133 task->task = NULL;
134 kfree(task);
135 }
136 EXPORT_SYMBOL(osal_kthread_destroy);
137
138