Project

General

Profile

How to send patches to kernel » History » Version 12

Alexey Khoroshilov, 08/16/2022 10:39 AM

1 1 Alexey Khoroshilov
{{toc}}
2
3
h1. Сообщение об ошибке в виде патча
4
5 3 Vitaly Omelchenko
Ниже на примере рассматривается подготовка и отправка в kernel.org почтовой версии набора коммитов (патча) с исправлением ошибки, найденной в в коде драйвера при помощи Svace. Более полную информацию о разработке, подготовке и отправке патчей, в том числе для случаев изменений в коде драйверов и связанном с  платформами конечных устройств, а также о требованиях к отправляемому коду, можно получить в документации на "docs.kernel.org":https://docs.kernel.org/ ("Submitting patches: the essential guide to getting your code into the kernel":https://docs.kernel.org/process/submitting-patches.html, "Linux Kernel patch submission checklist":https://docs.kernel.org/process/submit-checklist.html, "A guide to the Kernel Development Process":https://docs.kernel.org/process/development-process.html).
6 1 Alexey Khoroshilov
7
h2. Предварительная настройка git
8
9 3 Vitaly Omelchenko
10 12 Alexey Khoroshilov
Для корректного оформления патчей все коммиты должны быть подписаны при помощи опции --signoff команды git commit. Для этого необходимо добавить в конфигурацию Git ваше имя и электронную почту в параметры user.name и user.email, например:
11 3 Vitaly Omelchenko
12
 git config --global user.name "Alexey Khoroshilov"
13
git config --global user.email "khoroshilov@ispras.ru"
14
15
Чтобы патчи, подготовленные для отправки в списки рассылки, не вставлять вручную в почтовый клиент,  можно использовать команду "git send-email":https://git-scm.com/docs/git-send-email. Для этого в конфигурацию Git в раздел [sendemail] необходимо добавить параметры, соответствующие настройкам сервера SMTP, через который будет отправляться почта. Часто достаточно задать адрес сервера SMTP, порт и тип шифрования:
16
17
 git config --global sendemail.smtpServer "mail.ispras.ru"
18
git config --global sendemail.smtpServerPort "587"
19 1 Alexey Khoroshilov
git config --global sendemail.smtpEncryption "tls"
20 12 Alexey Khoroshilov
git config --global sendemail.smtpUser "ВАША ПОЧТА"
21 3 Vitaly Omelchenko
22
Также для изменения конфигурации Git можно использовать команду git config --global --edit, которая открывает файл конфигурации Git в редакторе.  
23
24
Конфигурация Git для рассматриваемого примера выглядит следующим образом:
25
26 1 Alexey Khoroshilov
 cat ~/.gitconfig 
27
[user]
28
      name = Alexey Khoroshilov
29
      email = khoroshilov@ispras.ru
30
[sendemail]
31
      smtpserver = mail.ispras.ru
32
      smtpEncryption = tls
33
      smtpserverport = 587
34 12 Alexey Khoroshilov
      smtpuser = ВАША ПОЧТА
35 1 Alexey Khoroshilov
36 12 Alexey Khoroshilov
h2. Обновление репозитория до самой свежей версии и создание новой ветки.
37 1 Alexey Khoroshilov
38 3 Vitaly Omelchenko
Перед внесением изменений в код ядра необходимо склонировать или обновить соответствующий репозиторий ядра и создать новую ветку для подготовки патча.
39 1 Alexey Khoroshilov
40 3 Vitaly Omelchenko
Как правило, клонируется или обновляется основной репозиторий ядра: 
41 1 Alexey Khoroshilov
42 3 Vitaly Omelchenko
 git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
43 1 Alexey Khoroshilov
44 3 Vitaly Omelchenko
или, если репозиторий был уже склонирован ранее
45 1 Alexey Khoroshilov
46 3 Vitaly Omelchenko
 git pull
47
48
Создаем отдельную ветку для подготовки исправления (в рассматриваемом примере ветка названа по имени драйвера):
49
50 1 Alexey Khoroshilov
 git checkout -b usb_gadget master
51
52
h2. Вносим необходимые исправления в код, соблюдая принятые правила форматирования
53
54 3 Vitaly Omelchenko
При внесении изменений в код необходимо соблюдать принятые в сообществе разработчиков ядра Linux правила форматирования кода (см. "Linux kernel coding style":https://docs.kernel.org/process/coding-style.html, 
55
"root/Documentation/process/coding-style.rst":https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/coding-style.rst).  
56 1 Alexey Khoroshilov
57 3 Vitaly Omelchenko
h2. Проверяем компилируемость ядра
58 1 Alexey Khoroshilov
59 3 Vitaly Omelchenko
После внесения изменений в код запускаем сборку ядра, по завершении которой необходимо проверить, что измененные файлы были скомпилированы:
60
61 1 Alexey Khoroshilov
 make allmodconfig
62
make prepare
63
make modules_prepare
64 3 Vitaly Omelchenko
make M=drivers/xxx/  #или
65
make drivers/xxx/filename.o
66 1 Alexey Khoroshilov
67
h2. Проверяем отсутствие ошибок после исправления
68
69
**TODO:** Предоставить возможность прогнать SVACE на версии с применённым патчем.
70
71
h2. Коммитим исправления
72
73
Делаем коммит.  Используем --signoff, чтобы добавить  строчку "Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>"  (обязательно нужна).
74
75
 git commit --signoff drivers/usb/gadget/inode.c
76
77
В теле коммита, для простоты, можно сразу писать багрепорт.  Шаблон такой:
78
79
<pre>
80
usb-gadget: Add module_put on error path in if_open()
81
82
If something happens (describe the path), then module_put is not 
83
called (describe the problem).
84
    
85
Make if_open() do module_put on error path (describe the solution in imperative mood).
86
If the solution is trivial, this section can be omitted.
87
    
88 4 Alexey Khoroshilov
Found by Linux Verification Center (linuxtesting.org) with SVACE.
89 1 Alexey Khoroshilov
</pre>
90 4 Alexey Khoroshilov
91
Если ошибка найдена не при помощи SVACE, то это необходимо отразить в последней строчке, например:
92
Found by Linux Verification Center (linuxtesting.org) with syzkaller.
93 1 Alexey Khoroshilov
94
Рекомендуется познакомиться с "общими правилами оформления сообщений коммитов":https://chris.beams.io/posts/git-commit/, которые применимы в том числе и для коммитов в ядро Linux.
95
96
Вместо usb-gadget нужен определённый идентифицирующий префикс; его можно посмотреть в логе изменений конкретного файла.
97
98 7 Alexey Khoroshilov
При совместной разработке патча в конце коммита желательно указать участвующих коллег:
99 1 Alexey Khoroshilov
100
<pre>
101
Co-developed-by: Co-Author <coauthor@ispras.ru>
102
Signed-off-by: Co-Author <coauthor@ispras.ru>
103
</pre>
104
105 9 Alexey Khoroshilov
*Hint.* Если известен коммит, в котором была внесена исправляемая ошибка, то в текст коммита (перед строчкой "Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>") рекомендуется вставить строчку с префиксом "Fixes:". Её можно сгенерировать при помощи команды:
106 1 Alexey Khoroshilov
107
<pre>
108 5 Alexey Khoroshilov
 git show -s --pretty="format:Fixes: %h (\"%s\")" HASH-OF-COMMIT-THAT-INTRODUCED-BUG
109 1 Alexey Khoroshilov
</pre>
110
111
В последнее время разработчики достаточно регулярно просят указать данный тег, поэтому рекомедуется делать это в обязательном порядке, даже если при этом приходится ссылаться на первоначальный коммит, который добавил соответствующий драйвер в ядро, т.е. ошибка была в коде изначально.
112
113 11 Alexey Khoroshilov
При поиске коммита, который внёс ошибку важно учитывать перемещения файла между директориями. Для этого бывает удобно воспользоваться опцией --follow, которая позволяет увидеть историю изменений в файле с учётом его перемещений внутри репозитория:
114
115
<pre>
116
 git log -p --follow drivers/usb/gadget/legacy/inode.c
117
</pre>
118
119
120 1 Alexey Khoroshilov
h2. Создаем сам патч
121
122
 git format-patch master..usb_gadget
123
124
Гит сделает что-то типа письма из того коммита, который был сделан ранее.
125
126
*Hint.* Имя текущей ветки можно и опустить:
127
128
<pre>
129
 git format-patch master..
130
</pre>
131
132
*Hint.* При генерации второй и последующих версий используйте аргумент -v:
133
134
<pre>
135
 git format-patch -v 2 master..
136
</pre>
137
138
139
h2. Проверяем его форматирование
140
141
 ./scripts/checkpatch.pl 0001-xxx.patch
142
143
h2. Редактируем файл с патчем
144
145
h3. Тема письма
146
147
Если всё сделали правильно, то формат-патч сам создаст такую тему:
148
149
 [PATCH] prefix: short description
150 10 Alexey Khoroshilov
151 1 Alexey Khoroshilov
h3. Идентифицируем адресатов
152
153
 ./scripts/get_maintainer.pl 0001-xxx.patch
154
155
Удаляем то, что в скобочках круглых, ставим первому адресату To:, а остальным — Cc:.  Дописываем в письмо. Также добавляем в Cc список рассылки: ldv-project@linuxtesting.org.
156
157
На этом этапе в текст письма можно внести произвольные изменения.
158
159
В результате получается что-то типа:
160
161
<pre>
162
From 9bbb34d71038fc7015917646a3365bca20cacb02 Mon Sep 17 00:00:00 2001
163
From: Alexey Khoroshilov <khoroshilov@ispras.ru>
164
To: Mauro Carvalho Chehab <mchehab@infradead.org>
165
Cc: linux-media@vger.kernel.org
166
Cc: linux-kernel@vger.kernel.org
167
Cc: ldv-project@linuxtesting.org
168
Date: Thu, 26 May 2011 00:38:12 +0400
169
Subject: [PATCH] usb-gadget: unlock data->lock mutex on error path in ep_write()
170
171
ep_read() acquires data->lock mutex in get_ready_ep() and releases it on
172
all paths except for one: when usb_endpoint_xfer_isoc() failed. The
173
patch adds mutex_unlock(&data->lock) at that path.
174
175
Found by Linux Verification Center (linuxtesting.org) with SVACE.
176
177 10 Alexey Khoroshilov
Fixes: 193ab2a60700 ("usb: gadget: allow multiple gadgets to be built")
178 1 Alexey Khoroshilov
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
179
---
180
 drivers/usb/gadget/inode.c |    4 +++-
181
 1 files changed, 3 insertions(+), 1 deletions(-)
182
183
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
184
index 3ed73f4..a01383f 100644
185
--- a/drivers/usb/gadget/inode.c
186
+++ b/drivers/usb/gadget/inode.c
187
@@ -386,8 +386,10 @@ ep_read (struct file *fd, char __user *buf, size_tlen, loff_t *ptr)
188
189
	/* halt any endpoint by doing a "wrong direction" i/o call */
190
	if (usb_endpoint_dir_in(&data->desc)) {
191
-		if (usb_endpoint_xfer_isoc(&data->desc))
192
+		if (usb_endpoint_xfer_isoc(&data->desc)) {
193
+			mutex_unlock(&data->lock);
194
			return -EINVAL;
195
+		}
196
		DBG (data->dev, "%s halt\n", data->name);
197
		spin_lock_irq (&data->dev->lock);
198
		if (likely (data->ep != NULL))
199
-- 1.7.0.4
200
</pre>
201
202
h3. Внимательно проверяем орфографию
203
204
Например, можно скопировать текст из 0001-xxx.patch в какой-нибудь редактор документов, в котором включены соответствующие проверки. Это позволит не нервировать разработчиков орфографическими ошибками, а также избежать повторной отправки патчей.
205
206
h2. Отправляем
207
208
 git send-email 0001-xxx.patch
209
210 8 Alexey Khoroshilov
Можно указать несколько патчей сразу через пробел, но если это независимые патчи, то делать этого **не нужно**, ибо тогда git скомпонует из них одну цепочку (письма будут ответами на первое). Конечно, если вы посылаете серию патчей, то это делается одной командой:
211 1 Alexey Khoroshilov
212
 git send-email 0001-xxx.patch 0002-yyy.patch 0003-zzz.patch
213
214
Команда git send-email спрашивает кому отправить письма и т.д. Если в теле патча всё указано верно, то можно смело нажимать Enter ничего не вводя и git воспользуется значениями указанными в теле патча.
215
216
h1. Сообщение об ошибке без патча
217
218
Если вкратце, то готовим такое же письмо как и выше, и посылаем его тем же адресатам (см. ./scripts/get_maintainer.pl -f path_to_file), но только с описанием проблемы и её последствий, без предложения по исправлению. Посылаем из любого почтового клиента **плоским текстом (не HTML)**.
219
220
В конце письма необходимо вставить строчку:
221
222
 Found by Linux Verification Center (linuxtesting.org) with SVACE.
223 12 Alexey Khoroshilov
224
225
h1. Перенос патчей в стабильную ветку ядра
226
227
h2. 1. Подготовка репозитория
228
229
Клонируем репозиторий со стабильными версиями ядра:
230
231
 git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
232
cd linux-stable
233
234
Для перехода на ветку, в которою переносим патч, выполните команду:
235
236
 git checkout linux-5.10.y
237
238
Создайте отдельную ветку для подготовки исправления (в рассматриваемом примере ветка названа по имени драйвера):
239
240
 git checkout -b ath9k linux-5.10.y
241
242
h2. 2. Внесение необходимых изменений в код
243
244
Предполагается, что мы знаем хэш коммита, который необходимо перенести. Посмотрим, могут ли изменения, внесенные коммитом, чисто примениться к стабильной ветке:
245
246
 git cherry-pick HASH-OF-COMMIT-THAT-NEEDS-TO-BE-BACKPORTED  
247
248
Смотрим на вывод команды - существует несколько вариантов:
249
250
* Патч чисто применен. Отлично! Успешный @git cherry-pick@ автоматически применяет коммит к текущей ветке (что можно увидеть с помощью @git log@).
251
252
* Во время применения изменений произошел конфликт (CONFLICT). Это значит, что нам нужно вручную попытаться адаптировать изменения, внесенные коммитом, к коду стабильной ветки. Открываем файл, в котором произошел конфликт, находим конфликтное место и, по возможности, разрешаем конфликт. Важно осознавать, не привнесут ли ручные изменения новых багов и не нарушат ли логику кода. После коммитим свои исправления:
253
<pre>
254
 git add FILE_WITH_CONFLICT
255
 git commit -m "Fixed conflict in [FILE_WITH_CONFLICT]"
256
</pre>
257
 Иногда бывает, что менее трудоемким и более безопасным путем будет откат к изначальному состоянию:
258
<pre>
259
 git cherry-pick --abort
260
</pre>
261
262
Возможно выяснится, что предварительно необходимо перенести ряд других коммитов и после этого вернуться к переносу или адаптации целевого коммита.
263
264
Рекомендуется ознакомиться с документацией: @man git-cherry-pick@, либо https://git-scm.com/docs/git-cherry-pick. 
265
266
После того как все необходимые изменения внесены, необходимо проверить компилируемость ядра и отсутствие ошибок после исправления - см. выше раздел про внесение патчей в основную ветку ядра.
267
268
h2. 3. Создание патча (серии патчей)
269
270
 git format-patch linux-5.10.y..ath9k
271
272
Эта команда сгенерирует заготовку письма из того коммита, который мы перенесли.
273
274
*Hint.* Имя текущей ветки можно и опустить:
275
276
<pre>
277
 git format-patch linux-5.10.y..
278
</pre>
279
280
*Hint.* При генерации второй и последующих версий используйте аргумент -v:
281
282
<pre>
283
 git format-patch -v 2 linux-5.10.y..
284
</pre>
285
286
h2. 4. Редактирование файла с патчем
287
288
Строку @From: Автор оригинального коммита@ следует поместить в само письмо (т. е. поместить ниже заголовка письма и отделить одной строкой).
289
290
В заголовке правим отправителя и дату:
291
 
292
 From: ВАШИ ИМЯ И ФАМИЛИЯ <ПОЧТА>
293
Date: <АКТУАЛЬНАЯ ДАТА>
294
295
296
В теме письма Subject *указываем [PATCH 5.10 1/1]*. При переносе патчей используется письмо с номером 0 (сопроводительное письмо для обоснования необходимости переноса), поэтому всегда посылаем серией. Если бэкпортируемых патчей два и более, то заключаем их в серию патчей. Например, если патчей два, то в первом письме указываем [PATCH 5.10 1/2], во втором соответственно [PATCH 5.10 2/2]. 
297
298
299
Через строку после @From: Автор оригинального коммита@ пишем, *не сокращая* хэш коммита:
300
301
 commit HASH-OF-COMMIT-THAT-NEEDS-TO-BE-BACKPORTED upstream.
302
303
*Обязательно подписываем патч*:
304
<pre>
305
Signed-off-by: ВАШИ ИМЯ И ФАМИЛИЯ <ПОЧТА>
306
</pre>
307
308
Текст описания оригинального патча оставляем как есть. 
309
310
Если нами были внесены какие-либо адаптивные изменения, их стоит описать после текста оригинального патча, до строк с подписями.
311
312
*Основными адресатами* являются: stable@vger.kernel.org и Greg Kroah-Hartman <gregkh@linuxfoundation.org>.
313
Остальных адресатов, которым отправим копии, идентифицируем с помощью скрипта. В конце добавляем:
314
<pre>
315
 Cc: ldv-project@linuxtesting.org
316
</pre>
317
В результате получится примерно следующее:
318
319
<pre>
320
From 63845fa0bdcd3ea538c4f1e5d298a3b0e343fe20 Mon Sep 17 00:00:00 2001
321
From: ВАШИ ИМЯ И ФАМИЛИЯ <ПОЧТА>
322
To: stable@vger.kernel.org
323
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
324
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
325
Cc: Kalle Valo <quic_kvalo@quicinc.com>
326
Cc: Alexey Khoroshilov <khoroshilov@ispras.ru>
327
Cc: ldv-project@linuxtesting.org
328
Date: Fri, 12 Aug 2022 22:06:23 +0900
329
Subject: [PATCH 5.10 1/1] ath9k_htc: fix NULL pointer dereference at ath9k_htc_rxep()
330
331
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
332
333
commit b0ec7e55fce65f125bd1d7f02e2dc4de62abee34 upstream.
334
335
syzbot is reporting lockdep warning followed by kernel panic at
336
ath9k_htc_rxep() [1], for ath9k_htc_rxep() depends on ath9k_rx_init()
337
being already completed.
338
339
Since ath9k_htc_rxep() is set by ath9k_htc_connect_svc(WMI_BEACON_SVC)
340
from ath9k_init_htc_services(), it is possible that ath9k_htc_rxep() is
341
called via timer interrupt before ath9k_rx_init() from ath9k_init_device()
342
is called.
343
344
Since we can't call ath9k_init_device() before ath9k_init_htc_services(),
345
let's hold ath9k_htc_rxep() no-op until ath9k_rx_init() completes.
346
347
Link: https://syzkaller.appspot.com/bug?extid=4d2d56175b934b9a7bf9 [1]
348
Reported-by: syzbot <syzbot+4d2d56175b934b9a7bf9@syzkaller.appspotmail.com>
349
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
350
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
351
Signed-off-by: ВАШИ ИМЯ И ФАМИЛИЯ <ПОЧТА>
352
---
353
 drivers/net/wireless/ath/ath9k/htc.h          | 1 +
354
 drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 8 ++++++++
355
 2 files changed, 9 insertions(+)
356
357
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
358
index 0a1634238e67..4f71e962279a 100644
359
--- a/drivers/net/wireless/ath/ath9k/htc.h
360
+++ b/drivers/net/wireless/ath/ath9k/htc.h
361
@@ -281,6 +281,7 @@ struct ath9k_htc_rxbuf {
362
 struct ath9k_htc_rx {
363
 	struct list_head rxbuf;
364
 	spinlock_t rxbuflock;
365
+	bool initialized;
366
 };
367
 
368
 #define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */
369
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
370
index 30ddf333e04d..592034ea4b68 100644
371
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
372
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
373
@@ -1133,6 +1133,10 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
374
 	struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
375
 	unsigned long flags;
376
 
377
+	/* Check if ath9k_rx_init() completed. */
378
+	if (!data_race(priv->rx.initialized))
379
+		goto err;
380
+
381
 	spin_lock_irqsave(&priv->rx.rxbuflock, flags);
382
 	list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
383
 		if (!tmp_buf->in_process) {
384
@@ -1188,6 +1192,10 @@ int ath9k_rx_init(struct ath9k_htc_priv *priv)
385
 		list_add_tail(&rxbuf->list, &priv->rx.rxbuf);
386
 	}
387
 
388
+	/* Allow ath9k_htc_rxep() to operate. */
389
+	smp_wmb();
390
+	priv->rx.initialized = true;
391
+
392
 	return 0;
393
 
394
 err:
395
-- 
396
2.25.1
397
</pre>
398
399
h2. 5. Сопроводительное письмо
400
401
Также следует включить письмо с кратким описанием того, почему мы бэкпортируем коммит.
402
Письмо нужно включить в отправляемую серию патчей *под номером 0*.
403
404
Примерный вид письма:
405
<pre>
406
From: ВАШИ ИМЯ И ФАМИЛИЯ <ПОЧТА>
407
To: stable@vger.kernel.org
408
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
409
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
410
Cc: Kalle Valo <quic_kvalo@quicinc.com>
411
Cc: Alexey Khoroshilov <khoroshilov@ispras.ru>
412
Cc: ldv-project@linuxtesting.org
413
Date: Mon, 1 Aug 2022 18:40:23 -0300
414
Subject: [PATCH 5.10 0/1] ath9k_htc: fix NULL pointer dereference at ath9k_htc_rxep()
415
416
Syzkaller reports NULL pointer dereference issue at ath9k_htc_rxep()
417
in 5.10 stable releases. The problem has been fixed by the following
418
patch which can be cleanly applied to the 5.10 branch.
419
420
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
421
</pre>
422
423
h2. 6. Отправка патчей
424
425
Как обычно используем команду git send-email:
426
427
 git send-email 0000-xxx.patch 0001-yyy.patch 0002-zzz.patch 0003-xyz.patch