Linux 内核开发流程的一个典型例子
gudong366 2025-07-27 17:24 4 浏览
>author Linus Torvalds <torvalds@linux-foundation.org> 2025-07-08 13:31:29 -0700
>committer Linus Torvalds <torvalds@linux-foundation.org> 2025-07-08 13:31:29 -0700
>commit 733923397fd95405a48f165c9b1fbc8c4b0a4681 (patch)
>tree 0da1a8e1f47adfda2687455f1f9b6ac4e46ebf1e
>parent 72782127388d96e971f0186996a5bd44e64a1665 (diff)
>parent 505b730ede7f5c4083ff212aa955155b5b92e574 (diff)
>download linux-733923397fd95405a48f165c9b1fbc8c4b0a4681.tar.gz
>Merge tag 'pwm/for-6.16-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linuxHEADmaster
>Pull pwm fixes from Uwe Kleine-K"onig:
> "Two fixes for v6.16-rc6
>
> The first patch fixes an embarrassing bug in the pwm core. I really
> wonder this wasn't found earlier since it's introduction in v6.11-rc1
> as it greatly disturbs driving a PWM via sysfs.
>
> The second and last patch fixes a clock balance issue in an error path
> of the Mediatek PWM driver"
>
>* tag 'pwm/for-6.16-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux:
> pwm: mediatek: Ensure to disable clocks in error path
> pwm: Fix invalid state detection
>Diffstat
>-rw-r--r-- drivers/pwm/core.c 2
>-rw-r--r-- drivers/pwm/pwm-mediatek.c 13
>2 files changed, 9 insertions, 6 deletions
>diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
>index 4d842c69219445..edf776b8ad53b9 100644
>--- a/drivers/pwm/core.c
>+++ b/drivers/pwm/core.c
>@@ -596,7 +596,7 @@ static bool pwm_state_valid(const struct pwm_state *state)
> * and supposed to be ignored. So also ignore any strange values and
> * consider the state ok.
> */
>- if (state->enabled)
>+ if (!state->enabled)
> return true;
>
> if (!state->period)
>diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
>index 7eaab58314995c..33d3554b9197ab 100644
>--- a/drivers/pwm/pwm-mediatek.c
>+++ b/drivers/pwm/pwm-mediatek.c
>@@ -130,8 +130,10 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
> return ret;
>
> clk_rate = clk_get_rate(pc->clk_pwms[pwm->hwpwm]);
>- if (!clk_rate)
>- return -EINVAL;
>+ if (!clk_rate) {
>+ ret = -EINVAL;
>+ goto out;
>+ }
>
> /* Make sure we use the bus clock and not the 26MHz clock */
> if (pc->soc->has_ck_26m_sel)
>@@ -150,9 +152,9 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
> }
>
> if (clkdiv > PWM_CLK_DIV_MAX) {
>- pwm_mediatek_clk_disable(chip, pwm);
> dev_err(pwmchip_parent(chip), "period of %d ns not supported\n", period_ns);
>- return -EINVAL;
>+ ret = -EINVAL;
>+ goto out;
> }
>
> if (pc->soc->pwm45_fixup && pwm->hwpwm > 2) {
>@@ -169,9 +171,10 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
> pwm_mediatek_writel(pc, pwm->hwpwm, reg_width, cnt_period);
> pwm_mediatek_writel(pc, pwm->hwpwm, reg_thres, cnt_duty);
>
>+out:
> pwm_mediatek_clk_disable(chip, pwm);
>
>- return 0;
>+ return ret;
> }
>
> static int pwm_mediatek_enable(struct pwm_chip *chip, struct pwm_device *pwm)
>
>
这是一个标准的 Linux 内核代码提交(Commit)的展示页面,它包含了元数据、提交信息和具体的代码变更。我们可以分步来解析。
### 总体概述
这是一个由 **Linus Torvalds**(Linux 内核的创造者和最高维护者)执行的**合并提交(Merge Commit)**。
它的核心作用是:将 **PWM(脉冲宽度调制)子系统**的一个修复分支合并到 Linux 内核的主干代码中。这次合并包含了两个针对 v6.16-rc6(Linux 6.16 版本的第 6 个候选发布版)的紧急修复。
---
### 详细解析
我们按信息块来分析:
#### 1. 元数据(Metadata)
这部分是关于这个提交本身的信息。
* `author Linus Torvalds <...>`: 指出这次**合并操作**的执行者是 Linus Torvalds。
* `committer Linus Torvalds <...>`: 同样,确认是 Linus 完成了这次提交。
* `commit 73392339...`: 这是本次提交的唯一标识符(SHA-1 哈希值)。你可以用这个哈希值在 Git 历史中精确定位到这次变更。
* `parent 72782127...`: 这是父提交之一,代表 Linus 的主分支在合并**之前**的状态。
* `parent 505b730e...`: 这是另一个父提交,代表被合并进来的那个 PWM 修复分支的最新状态。一个合并提交通常有两个(或更多)父提交。
* `Merge tag 'pwm/for-6.16-rc6-fixes' ...`: 这是提交的标题,清楚地说明了这是一次合并操作,合并的是一个名为 `pwm/for-6.16-rc6-fixes` 的 Git 标签。
* `download ...`: 提供了下载这个版本代码快照的链接。
**注意**: 这里的日期 `2025-07-08` 看起来是未来的,这在真实的 git log 中很罕见,可能是 cgit 系统显示问题或这是一个示例。但这不影响对代码本身的分析。
#### 2. 提交信息(Commit Message)
这部分是 Linus Torvalds 引用自 PWM 子系统维护者 **Uwe Kleine-K"onig** 的“拉取请求”(Pull Request)信息,解释了为什么要进行这次合并。
* `Pull pwm fixes from Uwe Kleine-K"onig:`: 说明这些修复来自于 PWM 子系统维护者 Uwe。
* `Two fixes for v6.16-rc6`: 明确指出这是为 6.16-rc6 版本准备的两个修复。
* **第一个修复**:
> "The first patch fixes an embarrassing bug in the pwm core... it greatly disturbs driving a PWM via sysfs."
* **问题**: PWM 核心代码中有一个“令人尴尬的”bug,从 v6.11-rc1 引入以来一直没被发现。这个 bug 严重影响了通过 `sysfs`(一种用户空间与内核交互的文件系统接口)来控制 PWM 设备的功能。
* **修复**: 对应下面的 `pwm: Fix invalid state detection`。
* **第二个修复**:
> "The second and last patch fixes a clock balance issue in an error path of the Mediatek PWM driver"
* **问题**: 在联发科(Mediatek)的 PWM 驱动中,某个错误处理路径上存在“时钟不平衡”的问题。这通常意味着在发生错误时,一个已经被启用的时钟没有被正确地禁用,导致资源泄漏。
* **修复**: 对应下面的 `pwm: mediatek: Ensure to disable clocks in error path`。
#### 3. 代码变更(Diff)
这部分是本次提交所包含的实际代码修改。
##### 文件 1: `drivers/pwm/core.c`
这是 PWM 的核心框架代码,这里的修改会影响所有使用该框架的 PWM 驱动。
* **变更**:
```diff
-if (state->enabled)
+if (!state->enabled)
return true;
```
* **含义**:
* 这个函数 `pwm_state_valid` 用于检查一个 PWM 状态是否有效。
* **修改前**: `if (state->enabled)` 意味着**只有在** PWM 被启用时,才直接返回 `true`(认为状态有效),然后继续检查周期(period)等参数。这逻辑是错的。
* **修改后**: `if (!state->enabled)` 意味着**如果** PWM 是**未启用**状态,就直接返回 `true`。根据代码注释,当 PWM 未启用时,其周期和占空比等参数是无意义的,不应该去校验它们。所以,只要是“未启用”状态,就应该被认为是有效的。
* **总结**: 这是一个简单的逻辑修正,修复了之前提到的影响 `sysfs` 的 bug。
##### 文件 2: `
drivers/pwm/pwm-mediatek.c`
这是针对联发科(Mediatek)芯片的 PWM 驱动程序。
* **变更**:
* 多处错误处理代码从直接 `return -EINVAL;` 改为了 `ret = -EINVAL; goto out;`。
* 在函数末尾增加了一个 `out:` 标签。
* 函数结尾的 `return 0;` 改为了 `return ret;`。
* **含义**:
* 这是一个经典的**错误处理重构**。
* **修改前**: 在 `pwm_mediatek_config` 函数中,如果 `clk_get_rate()` 返回 0 或者 `clkdiv` 计算值过大,函数会直接 `return -EINVAL;` 退出。问题在于,函数开头调用了 `pwm_mediatek_clk_enable()` 来启用时钟,但这些提前退出的路径**没有**调用 `pwm_mediatek_clk_disable()` 来关闭时钟。
* **修改后**: 通过引入 `goto out;` 语句,所有错误路径都会跳转到函数末尾的 `out:` 标签处。`out:` 标签后面紧跟着 `pwm_mediatek_clk_disable()` 调用。这样就**保证了**无论函数是正常执行完毕还是因错误中途退出,之前打开的时钟都会被正确关闭。
* **总结**: 这修复了提交信息中提到的“时钟不平衡”问题,避免了时钟资源泄漏。
---
### 最终总结
这个提交是 Linux 内核开发流程的一个典型例子:
1. **子系统维护者**(Uwe Kleine-K"onig)收集并测试了针对 PWM 子系统的两个重要 bug 修复。
2. 他将这些修复打包,并向 **Linus Torvalds** 发送了一个拉取请求。
3. **Linus** 审查了这个请求,认为修复是必要且正确的,于是执行了一次**合并操作**,将这些修复正式集成到内核主线代码中,以便它们能包含在下一个候选版本(v6.16-rc6)里。
这两个修复分别解决了一个核心逻辑错误和一个驱动资源泄漏问题,提高了内核的稳定性和正确性。
相关推荐
- 理解Linux进程和线程(linux的进程和线程的区别)
-
#进程-进程是一个执行中的程序,它拥有自己独立的内存空间,不同进程的地址空间是相互隔离的。-进程有自身的代码段,数据段,堆,栈等。进程需要耗费资源创建和销毁。-进程之间的通信需要借助IPC(I...
- Linux进程上下文切换过程context_switch详解
-
1前言1.1Linux的调度器组成2个调度器可以用两种方法来激活调度一种是直接的,比如进程打算睡眠或出于其他原因放弃CPU另一种是通过周期性的机制,以固定的频率运行,不时的检测是否有必要因此...
- linux init进程(linux init 1)
-
一.init是Linux系统操作中不可缺少的程序之一。所谓的init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通...
- 【Linux系统编程】特殊进程之守护进程
-
01.守护进程概述守护进程(DaemonProcess),也就是通常说的Daemon进程(精灵进程),是Linux中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地...
- 在 Linux 中如何强制停止进程?kill 和 killall 命令有什么区别?
-
在日常工作中,您会遇到两个用于在Linux中强制结束程序的命令;kill和killall。虽然许多Linux用户都知道kill命令,但知道并使用killall命令的人并不多。这两个命令...
- 嵌入式Linux系统编程——连进程间通信都不懂,还自称linux大神?
-
所有学嵌入式Linux系统的看过来了,以下内容是每一位想学习Linux嵌入式系统想要了解的内容,真的很想要分享给大家!本文分享的内容主要如下几个方面:(绝对的精品资料,不收藏可惜了)6.1共享内存...
- Linux基础运维篇:Linux进程与服务管理(第010课)
-
在Linux系统里,进程和服务管理就像是一个大管家的工作,得把各种程序的运行安排得明明白白,这样系统才能稳稳当当地干活。进程就是程序跑起来的一个实例,服务呢,是那种一直在后台默默工作的进程,咱下面...
- 深度剖析Linux内核《如何唤醒线程》
-
linux内核如何唤醒线程//本文代码片段出自linux内核版本:4.1.15linux内核唤醒线程主要使用wake_up_process()。一、wake_up_process()分析在linux内...
- 字节因它而跳动!顶级资深大牛整理的“深入理解Linux内核”
-
如果你对Linux如何工作。其性能又为什么会如此之高怀有强烈的好奇心。你将会从这里找到答案.阅读本文之后,你会通过上千行代码找到自己的方式来区别重要数据结构和次要数据结构的不同,简而言之,你蒋成为一名...
- 都说Linux内核很吊,它到底是个啥玩意儿?
-
了解完基本信息之后,我们来看一看,为什么说它吊?吊在哪里?甚至我觉得不仅仅是c/c++Linux开发的可以学习,Java、Python等方面的都可以学习提升一下。linux内核有什么用?linux内核...
- 77% 的 Linux 运维都不懂的内核问题,这篇全告诉你了
-
前言之前在实习时,听了OOM的分享之后,就对Linux内核内存管理充满兴趣,但是这块知识非常庞大,没有一定积累,不敢写下,担心误人子弟,所以经过一个一段时间的积累,对内核内存有一定了解之后,今...
- Linux 内核开发流程的一个典型例子
-
>authorLinusTorvalds<torvalds@linux-foundation.org>2025-07-0813:31:29-0700>committ...
- Vold原理介绍(volte基本原理)
-
一、Vold简介Android中Vold是volumeDaemon,即Volume守护进程,用来管理Android中存储类的热拔插事件。这里的热插拔涉及的场景如:手机usb以MTP或者传输照片方式...
- 2-剖析Linux内核源码分析《中断处理》
-
一、中断向量及汇编指令1、中断向量Intelx86系列机器共支持256种向量中断,Intel用一个8位无符号整数叫做一个向量,因此也叫中断向量。所有256种中断可分为两大类:异常和中断,异常又称为故...
- 剖析linux内核(一文看懂linux内核)
-
PASmm_struct详解malloc()函数是用户态常用的分配内存接口,mmap()函数是用户态常用创建文件映射或匿名映射。进程地址空间在linux内核当中使用structvm_area...
- 一周热门
- 最近发表
- 标签列表
-
- linux一键安装 (31)
- linux运行java (33)
- ln linux (27)
- linux 磁盘管理 (31)
- linux 内核升级 (30)
- linux 运行python (28)
- linux 备份文件 (30)
- linux 网络测试 (30)
- linux 网关配置 (31)
- linux jre (32)
- linux 杀毒软件 (32)
- linux语法 (33)
- linux博客 (33)
- linux 压缩目录 (37)
- linux 查看任务 (32)
- 制作linux启动u盘 (35)
- linux 查看存储 (29)
- linux乌班图 (31)
- linux挂载镜像 (31)
- linux 软件源 (28)
- linux题目 (30)
- linux 定时脚本 (30)
- linux 网站搭建 (28)
- linux 远程控制 (34)
- linux bind (31)