【Linux】内核线程创建 kthread_run 函数和内核中断

kthread_run函数详解

以PCIE的热插拔内核线程创建为例说明
注意:内核线程和RTOS的线程略有不同,这里Linux上创建以后直接运行,RTOS上有的是需要加入到调度队列中后才会执行,比如RT-Thread的系统
【Linux】内核线程创建 kthread_run 函数和内核中断_第1张图片

kthread_run 是 Linux 内核中的一个函数,用于创建和运行内核线程(Kernel Thread)。

在 Linux 内核中,线程是一种轻量级的执行单位,可以独立运行并共享进程资源。与用户空间线程(User Space Thread)不同,内核线程运行在内核态,具有更高的特权级别和更广泛的系统资源访问权限。

kthread_run 函数的作用是创建一个新的内核线程,并自动将其添加到内核线程调度器中进行调度。它接受两个参数:threadfn 和 data。

threadfn 是一个函数指针,表示要在新线程中执行的函数。这个函数应该没有任何参数,并且返回类型为 int。通常,开发者会在 threadfn 函数中编写新线程需要执行的代码逻辑。

data 是一个指针,表示传递给 threadfn 函数的参数。开发者可以使用 data 参数来传递自定义的数据结构或其他信息给新线程。

kthread_run 函数会创建一个新的内核线程,并将指定的 threadfn 函数作为新线程的入口点。然后,新线程会开始执行 threadfn 函数中的代码。开发者可以在 threadfn 中编写自定义的逻辑,例如执行某些任务、处理中断、驱动硬件等。

kthread_run 是用于创建并运行内核线程的一个函数,它接受一个函数指针作为线程的入口,并可以传递参数给线程函数。通过使用 kthread_run,开发者可以在 Linux 内核中创建和管理自己的线程,实现各种类型的异步任务处理和并发操作。

schedule_timeout_idle 空闲状态下执行超时调度函数

作用

通常情况下,当一个任务调用 schedule_timeout 函数进行休眠时,它将被视为负载贡献者,即会对系统的负载平均值(load average)产生影响。然而,有些特定的任务可能希望在休眠期间不被计算为系统负载的一部分;

/*
 * Like schedule_timeout_uninterruptible(), except this task will not contribute
 * to load average.
 */
signed long __sched schedule_timeout_idle(signed long timeout)
{
	__set_current_state(TASK_IDLE);
	return schedule_timeout(timeout);
}

schedule_timeout_idle 函数中,首先调用 __set_current_state 函数将当前任务的状态设置为 TASK_IDLE,表示该任务处于空闲状态。然后,通过调用 schedule_timeout 函数,在指定的超时时间内进行休眠。

schedule_timeout 函数会将当前任务挂起,并根据指定的超时时间(以嘀嗒数为单位)来决定任务何时被唤醒。当超时时间到达或者有其他引起任务唤醒的事件发生时,被挂起的任务将被重新调度执行。

schedule_timeout_idle 函数是一个特殊的休眠函数,它将当前任务的状态设置为 TASK_IDLE,使得任务在休眠期间不会被计算为系统负载的一部分。然后,它与标准的 schedule_timeout 函数一起使用,实现在指定超时时间内进行休眠并重新调度的功能。

request_threaded_irq 请求线程中断

用于请求一个带有线程化处理的中断

【Linux】内核线程创建 kthread_run 函数和内核中断_第2张图片

 */
int request_threaded_irq(unsigned int irq, irq_handler_t handler,
			 irq_handler_t thread_fn, unsigned long irqflags,
			 const char *devname, void *dev_id)
{

参数说明如下:

irq:要请求的中断号。 handler:指向顶半部(top half)中断处理程序的函数指针。当中断被触发时,由内核调用此处理程序来进行快速的中断处理操作。
thread_fn:指向底半部(bottom half)中断处理程序的函数指针。当中断被触发时,内核将创建一个内核线程,并调度执行该处理程序。这个线程会在中断上下文之外运行,可以执行一些较长或需要睡眠的处理操作。
irqflags:中断标志,用于指定中断请求的属性和行为。可以使用预定义的中断标志宏来设置。
devname:设备名称,用于标识请求中断的设备。 dev_id:设备ID,将传递给中断处理程序的参数。
request_threaded_irq 函数用于请求一个带有线程化处理的中断,并将中断处理函数 handler 和底半部处理函数
thread_fn分别关联到该中断上。这样,在中断触发时,首先会调用顶半部处理程序进行快速的中断响应,然后内核会创建一个内核线程,并调度执行底半部处理程序,以完成较长或需要睡眠的处理操作。

这种线程化中断处理机制可以提高中断处理的实时性和可伸缩性,使得中断处理函数能够更灵活地执行复杂的操作而不阻塞其他重要任务的执行。

共享中断的限制和注意事项

【Linux】内核线程创建 kthread_run 函数和内核中断_第3张图片

1、 共享中断需要传递一个真正的设备ID(dev-ID)作为参数。如果没有提供真实的设备ID,后续将难以确定哪个中断对应于哪个设备,可能会导致中断释放逻辑等出现问题。

2、 禁用自动使能(auto enable)与共享中断不兼容。在禁用状态下,共享中断可能会请求启用,然后永远等待中断的到来,从而导致问题。

3、 IRQF_COND_SUSPEND 只有在共享中断时才有意义,并且不能与 IRQF_NO_SUSPEND 同时设置。IRQF_COND_SUSPEND 是用于中断在挂起(suspend)期间的条件处理,它表示仅当某些条件满足时,中断才会被挂起。而 IRQF_NO_SUSPEND 表示中断不会挂起。

以上注释说明了共享中断的一些限制和使用注意事项。要确保共享中断的正确性和可靠性,需要满足这些要求。

你可能感兴趣的:(Linux,linux,运维)