22690 views|1 replies

139

Posts

0

Resources
The OP

SinlinxA33 development board Linux kernel workqueue (with actual test code) [Copy link]

Overview of kernel workqueues Workqueues are another way to postpone work execution. Workqueues can postpone work and hand it over to a kernel thread for execution. In other words, the lower half can be executed in the context of a process. The most important thing is that workqueues allow for rescheduling and even sleeping. How Linux workqueues work During Linux system startup, a worker kernel thread named kworker/u:x (x is an integer starting from 0, indicating the CPU number) is created. After the thread is created, it is in the sleep state. From the perspective of the scheduler, a kernel thread is a process that can be scheduled; from the code representation, it is essentially a function. Work queue structure principle work_struct,workqueue_struct,struct cpu_workqueue_structThe relationship between the three is as follows:
  • When the kernel starts, a cpu_workqueue_struct structure will be created for each CPU, and there will also be a kernel working thread. After this thread is created, it will be in a dormant state, waiting for the user to join the work to wake up the thread to schedule the work function in the work structure work_struct.
  • The work work_struct is connected to the cpu_workqueue_struct through a linked list, and the other work_structs are connected to the previous one to form a queue
  • After the worker thread is awakened, it will go to the work queue it is responsible for and execute the work functions in the above struct_work structure in sequence. After the execution is completed, the work_struct will be deleted from the linked list.
  • If you want to use the work queue to delay the execution of a section of code, you must first create work_struct -> cpu_workqueue_struct, and then add the work node work_struct to the workqueue_struct work queue. After joining, the worker thread will be awakened and the work function will be executed at the appropriate time.
Work queue data structure work_struct We call the postponed task work, and the data structure that describes it is work_struct Path: workqueue.h /work/lichee/linux-3.4/include/linux/workqueue.h
struct work_struct { atomic_long_t data; struct list_head entry; //The linked list pointer connects each work to a linked list to form a doubly linked list work_func_t func; //The function pointer points to the work function #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map; #endif }; Supplement work_func_t structure typedef void (*work_func_t)(void *work); Supplement list_head structure struct list_head { struct list_head *next, *prev; }; When programming, we only need to pay attention to the func member, which is the work function pointer, which is the code that the user needs to delay execution workqueue_struct This structure is used to describe the data structure of the kernel queue. Defined in workqueue.c The specific definition is as follows: struct workqueue_struct { unsigned int flags; /* W: WQ_* flags */ [color=#00 0] union { struct cpu_workqueue_struct __percpu *pcpu; struct cpu_workqueue_struct *single; unsigned long v; } cpu_wq; /* I: cwq's */ struct list_head list; /* W: list of all workqueues */ struct mutex flush_mutex; /* protects wq flushing */ int work_color; /* F: current work color */ int flush_color; /* F:current flush color */ atomic_t nr_cwqs_to_flush; /* flush in progress */ struct wq_flusher *first_flusher; /* F: first flusher */[/ color] struct list_head flusher_queue; /* F: flush waiters */ struct list_head flusher_overflow; /* F: flush overflow list */ mayday_mask_t mayday_mask; /* cpus requesting rescue */ struct worker *rescuer; /* I: rescue worker */ int nr_drainers; /* W: drain in progress */ int saved_max_active; /* W: saved cwq max_active */ #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map ; #endif char name[]; /* I: workqueue name */ };[/ color] Note: This structure represents a work queue. Generally, driver developers do not need to touch too many members of this structure. Regarding queue operations, the kernel provides corresponding API functions. [color =#000]cpu_workqueue_struct struct cpu_workqueue_struct { struct global_cwq *gcwq; /* I: the associated gcwq */ struct workqueue_struct *wq; /* I: the owning workqueue */ int work_color; / * L: current color */ int flush_color; /* L: flushing color */ int nr_in_flight[WORK_NR_COLORS]; /* L: nr of in_flight works */ int nr_active; /* L: nr of active works */ int max_active; /* L: max active works */ struct list_head delayed_works; /* L: delayed works */}; The kernel connects the first work_struct through the delayed_works member, and the subsequent work_struct connects itself through its own entry member. On the linked list. Kernel work queue classification Kernel work queues are divided into shared work queues and custom work queues. Two Shared Work Queues The system automatically creates a work queue at startup. If the driver developer wants to When using this queue, you do not need to create a work queue yourself, you only need to add your work to this work queue. Use the schedule_work function to add work_struct to the work queue Custom work queue [color= #000]Since the shared work queue is used by everyone, if the work function above is blocked, it will affect the execution time of the subsequent work. To avoid the impact of other work functions, you can create a work queue yourself and then add your own work to this custom work queue. Using a custom work queue is divided into two steps: Creating a work queue: Use creat_workqueue(name) to create a work queue named name [/color ] Add the work to the work queue created above: Use the queue_work function to add a work structure work_struc to the specified work queue [ color=#333333]Linux kernel shared work queue shared work queue introduction In order to facilitate driver developers to use the work queue, the kernel creates a work queue for us. As long as the work nodes added using schedule_work are added to the kernel shared work queue, the usage method only requires the developer to implement a work_struct structure and then add it to the shared work. Kernel shared queue API Statically define the work structure DECLARE_WORK #define DECLARE_WORK (n, f) \ struct work_struct n = __WORK_INITIALIZER (n,f) Function: Define a work_struct structure variable named n and initialize it. The work is f. Parameters: n is the name of the work_struct structure variable to be defined, f is the work function, and the code to be executed later Dynamically initialize the work structure INIT_WORK #define INIT_WORK(_work, _func) \ do { \ __INIT_WORK((_work), (_func), 0); \ } while (0) Function: Dynamically initialize the work_struct structure during operation Parameters: _work is the address of the work_struct structure variable to be defined, _func is the work function, and the code to be executed later Schedule work schedule_work The declaration path is in workqueue.h workqueue.h /work/lichee/linux-3.4/include/linux/workqueue.h int queue_work(struct workqueue_struct *wq, struct work_struct *work) { int ret; ret = queue_work_on(get_cpu(), wq, work); put_cpu(); return ret; } Function: Add a work_struct to the shared work queue and make it a work node. Parameter: work The name and address of the work_struct structure variable to be defined Return value: 0 Indicates that it has been attached to the shared work queue but has not been executed yet. Non-0 Other cases are not explained in the kernel. Function return values usually do not require attention from driver developers. Steps to use shared queues Work queues are required to create work scheduling work (create work nodes). For shared work queues, the first step is already there, and steps 2/3 need to be done.
  1. #include<linux module.h="">
  2. #include<linux init.h="">
  3. //Add header file #include<linux workqueue.h="">
  4. __FUNCTION__); return 0; } static void __exit mywork_exit(void) { printk("mywork is exit!\r\n"); } module_init(mywork_init); module_exit(mywork_exit); MODULE_LICENSE("GPL");
复制代码
Reference blog post: https://blog.csdn.net/z961968549/article/details/78758527




This post is from Embedded System

Latest reply

Thanks for sharing!  Details Published on 2019-2-18 15:59

108

Posts

0

Resources
2
Thanks for sharing!
This post is from Embedded System
Personal signatureIIS7站群大全

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

Related articles more>>

    EEWorld
    subscription
    account

    EEWorld
    service
    account

    Automotive
    development
    circle

    Robot
    development
    community

    About Us Customer Service Contact Information Datasheet Sitemap LatestNews

    Room 1530, Zhongguancun MOOC Times Building, Block B, 18 Zhongguancun Street, Haidian District, Beijing 100190, China Tel:(010)82350740 Postcode:100190

    Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
    快速回复 返回顶部 Return list