diff --git a/README.md b/README.md index c96d9dd6b3d0b178f4cd5513c822e83db17fcb76..070fb42cf1610eff7e51616a60f1896aec7df59c 100644 --- a/README.md +++ b/README.md @@ -153,9 +153,13 @@ patch -p1 < patch-xxx-rt-xx ## 3.4 å†…æ ¸å‡½æ•°é€‰ç‚¹ -- [Doc:观测点选择](https://gitlab.eduxiji.net/T202411664993243/project2210132-239754/-/blob/main/doc/%E8%A7%82%E6%B5%8B%E7%82%B9%E9%80%89%E6%8B%A9.md) +> å…¨æ–‡è§æœ¬ä»“库:[Doc:结构体åŠå‡½æ•°è¯„ä¼°](https://gitlab.eduxiji.net/T202411664993243/project2210132-239754/-/blob/main/doc/%E7%BB%93%E6%9E%84%E4%BD%93%E5%8F%8A%E5%87%BD%E6%95%B0%E8%AF%84%E4%BC%B0.md) -- [Doc:结构体åŠå‡½æ•°è¯„ä¼°](https://gitlab.eduxiji.net/T202411664993243/project2210132-239754/-/blob/main/doc/%E7%BB%93%E6%9E%84%E4%BD%93%E5%8F%8A%E5%87%BD%E6%95%B0%E8%AF%84%E4%BC%B0.md) +- `tracepoint:sched/sched_switch` +- `kprobe:__handle_irq_event_percpu` +- `kprobe:enqueue_task_fair/dequeue_task_fair` +- `kprobe:update_rq_clock` +- `kprobe:irq_forced_thread_fn` ## 3.5 机器å¦ä¹ 实践 @@ -168,4 +172,15 @@ patch -p1 < patch-xxx-rt-xx # 4.å¼€å‘æŠ¥å‘Š +## 4.1 åˆèµ›å·²å®ŒæˆåŠŸèƒ½/任务 + +- [x] RT-Patch Kernel ç†è®ºç ”ç©¶ã€è®ºæ–‡ç ”ç©¶ +- [x] RT-Patch Kernel 开呿œºå†…æ ¸ç¼–è¯‘ã€çŽ¯å¢ƒéƒ¨ç½² +- [x] ç¡®è®¤ç“¶é¢ˆè§‚æµ‹åˆ†æžæŠ€æœ¯æ ˆ +- [x] RT-Patch 瓶颈分æžçš„å†…æ ¸å‡½æ•°é€‰ç‚¹ +- [x] 编写RT-Patch 䏿–上åŠéƒ¨åˆ†ã€ä¸æ–下åŠéƒ¨åˆ†æ—¶é—´åŠè¿›ç¨‹åˆ†å¸ƒè§‚æµ‹ç¨‹åº +- [x] 编写æ¯ç§’å¹³å‡è°ƒåº¦æŠ¢å 观测程åºã€‚ +- [x] 编写CPU进程队列长度观测程åºã€‚ +- [x] 编写CPU进程调度延迟观测程åºã€‚ + # 5.部署测试 diff --git "a/doc/\347\273\223\346\236\204\344\275\223\345\217\212\345\207\275\346\225\260\350\257\204\344\274\260.md" "b/doc/\347\273\223\346\236\204\344\275\223\345\217\212\345\207\275\346\225\260\350\257\204\344\274\260.md" index f8244063cb68f5d3d4b1dd566fb73b3858df42ab..cf6006b8da58b8da566a13e00d9b005b9f4dee1e 100644 --- "a/doc/\347\273\223\346\236\204\344\275\223\345\217\212\345\207\275\346\225\260\350\257\204\344\274\260.md" +++ "b/doc/\347\273\223\346\236\204\344\275\223\345\217\212\345\207\275\346\225\260\350\257\204\344\274\260.md" @@ -1,21 +1,51 @@ -# struct irqaction -- `irq_handler_t handler`: 䏿–处ç†ç¨‹åºçš„å‡½æ•°æŒ‡é’ˆã€‚è¿™æ˜¯å½“ä¸æ–å‘ç”Ÿæ—¶ï¼Œå†…æ ¸é¦–å…ˆè°ƒç”¨çš„å‡½æ•°ã€‚ -- `void *dev_id`: 设备ID或设备特定信æ¯çš„æŒ‡é’ˆã€‚它å¯ä»¥ç”¨äºŽåŒºåˆ†å…±äº«åŒä¸€ä¸æ–å·çš„ä¸åŒè®¾å¤‡ã€‚ -- `void *percpu_dev_id`: æ¯ä¸ªCPU的设备ID。对于æŸäº›ç±»åž‹çš„䏿–ï¼Œè¿™ä¸ªå—æ®µå¯ä»¥å¸®åŠ©å¤„ç†æ¯ä¸ªCPU特定的数æ®ã€‚ +# 1.观测点选择 -- `struct irqaction *next`: 指å‘下一个irqactionç»“æž„ä½“çš„æŒ‡é’ˆã€‚å¦‚æžœå¤šä¸ªä¸æ–处ç†ç¨‹åºæ³¨å†Œåˆ°äº†åŒä¸€ä¸ªIRQ,这些结构体就会形æˆä¸€ä¸ªé“¾è¡¨ã€‚ -- `irq_handler_t thread_fn`: 指å‘䏿–çº¿ç¨‹å‡½æ•°çš„æŒ‡é’ˆã€‚å¦‚æžœä¸æ–处ç†ç¨‹åºè¢«çº¿ç¨‹åŒ–(å³å®ƒè¿è¡Œåœ¨ä¸€ä¸ªç‹¬ç«‹çš„å†…æ ¸çº¿ç¨‹ä¸ï¼Œè€Œä¸æ˜¯åœ¨ç¡¬ä»¶ä¸æ–上下文ä¸ï¼‰ï¼Œè¿™ä¸ªå‡½æ•°ä¼šè¢«è°ƒç”¨ã€‚ -- `struct task_struct *thread`: 指å‘䏿–线程的task_structç»“æž„ä½“çš„æŒ‡é’ˆã€‚å¦‚æžœä¸æ–è¢«çº¿ç¨‹åŒ–ï¼Œè¿™ä¸ªå—æ®µä»£è¡¨ä¸æ–处ç†çš„å†…æ ¸çº¿ç¨‹ã€‚ -- `struct irqaction *secondary`: æŒ‡å‘æ¬¡çº§ä¸æ–处ç†ç¨‹åºçš„æŒ‡é’ˆã€‚这用于那些需è¦ä¸¤ä¸ªé˜¶æ®µå¤„ç†çš„䏿–。 -- `unsigned int irq`: 与æ¤ä¸æ–处ç†ç¨‹åºç›¸å…³è”çš„IRQå·ã€‚ -- `unsigned int flags`: 䏿–æ ‡å¿—ï¼Œå®šä¹‰äº†ä¸æ–处ç†ç¨‹åºçš„å„ç§å±žæ€§ï¼Œå¦‚䏿–类型ç‰ã€‚ -- `long unsigned int thread_flags`: 䏿–çº¿ç¨‹çš„æ ‡å¿—ã€‚è¿™äº›æ ‡å¿—ç”¨äºŽç®¡ç†ä¸æ–线程的行为。 -- `long unsigned int thread_mask`: 䏿–线程掩ç ,决定了哪些CPUå¯ä»¥è¿è¡Œè¿™ä¸ªä¸æ–线程。 -- `const char *name`: 指å‘䏿–åç§°çš„æŒ‡é’ˆï¼Œé€šå¸¸æ˜¯ä¸Žè¯¥ä¸æ–å…³è”的设备å称。 -- `struct proc_dir_entry *dir`: 指å‘proc文件系统ä¸è¡¨ç¤ºæ¤ä¸æ–ä¿¡æ¯çš„目录的指针。这用于在/proc/irq/ä¸‹åˆ›å»ºæœ‰å…³è¿™ä¸ªä¸æ–çš„ä¿¡æ¯æ–‡ä»¶ã€‚ +>以下观测点选择的实现方å¼ä»…ä½œä¸ºä¸´æ—¶å¼€å‘æŸ¥çœ‹ï¼Œéžæœ€ç»ˆå®žçŽ°æ–¹å¼ã€‚ +## 1.1 䏿–线程的处ç†å‡½æ•°è¿½è¸ª `irq_forced_thread_fn` -# struct irq_desc +irq_forced_thread_fn函数是处ç†çº¿ç¨‹åŒ–䏿–çš„å‡½æ•°ã€‚çº¿ç¨‹åŒ–ä¸æ–å…è®¸å†…æ ¸å°†ä¸æ–处ç†ä¸‹åŠéƒ¨å»¶è¿Ÿæ‰§è¡Œï¼Œè½¬è€Œä½œä¸ºå†…æ ¸çº¿ç¨‹çš„å½¢å¼è¿è¡Œï¼Œå‡å°‘äº†ä¸æ–处ç†åœ¨ç³»ç»Ÿä¸Šçš„峿—¶è´Ÿè½½ã€‚监控æ¤å‡½æ•°æœ‰åŠ©äºŽåˆ†æžä¸‹åŠéƒ¨ä¸æ–处ç†å¯¹å®žæ—¶æ€§èƒ½çš„å½±å“。 + +```shell +sudo bpftrace -e 'kprobe:irq_forced_thread_fn { @[comm] = count(); }' +``` + +## 1.2 `__handle_irq_event_percpu` +该函数是上åŠéƒ¨ä¸æ–处ç†çš„关键入å£ç‚¹ï¼Œè´Ÿè´£å¤„ç†æ¯ä¸ª CPU çš„ç¡¬ä»¶ä¸æ–。对其进行跟踪å¯ä»¥å¸®åŠ©æˆ‘ä»¬ç†è§£ç¡¬ä»¶ä¸æ–在整个系统的分布和频率,从而分æžç¡¬ä»¶ä¸æ–å¯èƒ½åœ¨ç³»ç»Ÿå“应时间ä¸å¼•入的延迟。 + +## 1.3 `sched:sched_switch` +æ¤è·Ÿè¸ªç‚¹æ¶‰åŠåˆ°è°ƒåº¦å™¨çš„上下文切æ¢ã€‚通过测é‡çжæ€ä¸ºTASK_RUNNING(prev_state == 0)的进程被抢å 的次数,我们能够定é‡åˆ†æžç³»ç»Ÿçš„æŠ¢å 行为和频度,评估抢å 对实时任务性能的影å“。 + +## 1.4 `enqueue_task_fair/dequeue_task_fair` +函数dequeue_task_fair是从è¿è¡Œé˜Ÿåˆ—ä¸ç§»é™¤ä»»åŠ¡çš„å‡½æ•°ã€‚ç›‘æŽ§æ¤å‡½æ•°å¯ä»¥èŽ·å¾—è¿›ç¨‹è¢«è°ƒåº¦çš„å»¶è¿Ÿã€‚ + +## 1.5. `update_rq_clock` +update_rq_clock函数是更新调度器时钟的é‡è¦å‡½æ•°ï¼Œæ¯æ¬¡å¯¹è¿è¡Œé˜Ÿåˆ—进行æ“作之å‰éƒ½ä¼šè¢«è°ƒç”¨ã€‚通过该函数进行CPUè¿è¡Œé˜Ÿåˆ—长度的hook + +# 2. ç›¸å…³ç»“æž„ä½“åˆ†æž + +## 2.1 struct irqaction + +```c +struct irqaction{ + irq_handler_t handler; //䏿–处ç†ç¨‹åºçš„å‡½æ•°æŒ‡é’ˆã€‚è¿™æ˜¯å½“ä¸æ–å‘ç”Ÿæ—¶ï¼Œå†…æ ¸é¦–å…ˆè°ƒç”¨çš„å‡½æ•°ã€‚ + void *dev_id; //设备ID或设备特定信æ¯çš„æŒ‡é’ˆã€‚它å¯ä»¥ç”¨äºŽåŒºåˆ†å…±äº«åŒä¸€ä¸æ–å·çš„ä¸åŒè®¾å¤‡ã€‚ + void *percpu_dev_id; //æ¯ä¸ªCPU的设备ID。对于æŸäº›ç±»åž‹çš„䏿–ï¼Œè¿™ä¸ªå—æ®µå¯ä»¥å¸®åŠ©å¤„ç†æ¯ä¸ªCPU特定的数æ®ã€‚ + + struct irqaction *next; //指å‘下一个irqactionç»“æž„ä½“çš„æŒ‡é’ˆã€‚å¦‚æžœå¤šä¸ªä¸æ–处ç†ç¨‹åºæ³¨å†Œåˆ°äº†åŒä¸€ä¸ªIRQ,这些结构体就会形æˆä¸€ä¸ªé“¾è¡¨ã€‚ + irq_handler_t thread_fn; //指å‘䏿–çº¿ç¨‹å‡½æ•°çš„æŒ‡é’ˆã€‚å¦‚æžœä¸æ–处ç†ç¨‹åºè¢«çº¿ç¨‹åŒ–(å³å®ƒè¿è¡Œåœ¨ä¸€ä¸ªç‹¬ç«‹çš„å†…æ ¸çº¿ç¨‹ä¸ï¼Œè€Œä¸æ˜¯åœ¨ç¡¬ä»¶ä¸æ–上下文ä¸ï¼‰ï¼Œè¿™ä¸ªå‡½æ•°ä¼šè¢«è°ƒç”¨ã€‚ + struct task_struct *thread; //指å‘䏿–线程的task_structç»“æž„ä½“çš„æŒ‡é’ˆã€‚å¦‚æžœä¸æ–è¢«çº¿ç¨‹åŒ–ï¼Œè¿™ä¸ªå—æ®µä»£è¡¨ä¸æ–处ç†çš„å†…æ ¸çº¿ç¨‹ã€‚ + struct irqaction *secondary; // æŒ‡å‘æ¬¡çº§ä¸æ–处ç†ç¨‹åºçš„æŒ‡é’ˆã€‚这用于那些需è¦ä¸¤ä¸ªé˜¶æ®µå¤„ç†çš„䏿–。 + unsigned int irq; //与æ¤ä¸æ–处ç†ç¨‹åºç›¸å…³è”çš„IRQå·ã€‚ + unsigned int flags; //䏿–æ ‡å¿—ï¼Œå®šä¹‰äº†ä¸æ–处ç†ç¨‹åºçš„å„ç§å±žæ€§ï¼Œå¦‚䏿–类型ç‰ã€‚ + long unsigned int thread_flags;//䏿–çº¿ç¨‹çš„æ ‡å¿—ã€‚è¿™äº›æ ‡å¿—ç”¨äºŽç®¡ç†ä¸æ–线程的行为。 + long unsigned int thread_mask; //䏿–线程掩ç ,决定了哪些CPUå¯ä»¥è¿è¡Œè¿™ä¸ªä¸æ–线程。 + const char *name`: 指å‘䏿–åç§°çš„æŒ‡é’ˆï¼Œé€šå¸¸æ˜¯ä¸Žè¯¥ä¸æ–å…³è”的设备å称。 + struct proc_dir_entry *dir; // 指å‘proc文件系统ä¸è¡¨ç¤ºæ¤ä¸æ–ä¿¡æ¯çš„目录的指针。这用于在/proc/irq/ä¸‹åˆ›å»ºæœ‰å…³è¿™ä¸ªä¸æ–çš„ä¿¡æ¯æ–‡ä»¶ã€‚ +} +``` + +## 2.2 struct irq_desc ```c struct irq_desc { struct irq_common_data irq_common_data; // 包å«IRQçš„é€šç”¨ä¿¡æ¯ diff --git "a/doc/\350\247\202\346\265\213\347\202\271\351\200\211\346\213\251.md" "b/doc/\350\247\202\346\265\213\347\202\271\351\200\211\346\213\251.md" deleted file mode 100644 index b9fe3c4f6e41178443e3b8fac0c1b50d96ab64a4..0000000000000000000000000000000000000000 --- "a/doc/\350\247\202\346\265\213\347\202\271\351\200\211\346\213\251.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 观测点选择 - ->以下观测点选择的实现方å¼ä»…ä½œä¸ºä¸´æ—¶å¼€å‘æŸ¥çœ‹ï¼Œéžæœ€ç»ˆå®žçŽ°æ–¹å¼ã€‚ - -• 䏿–线程的处ç†å‡½æ•°è¿½è¸ª `irq_forced_thread_fn` -```shell -sudo bpftrace -e 'kprobe:irq_forced_thread_fn { @[comm] = count(); }' -``` -