-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathlinux-uek4-msi-and-irq.patch
292 lines (275 loc) · 12.2 KB
/
linux-uek4-msi-and-irq.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
From 8341d67c3bcc058230a910aafaff4f9452526e01 Mon Sep 17 00:00:00 2001
From: Dongli Zhang <dongli.zhang0129@gmail.com>
Date: Fri, 23 Aug 2019 16:19:19 +0800
Subject: [PATCH 1/1] linux uek4 msi and irq
v4.1.12-124.23.4
Signed-off-by: Dongli Zhang <dongli.zhang0129@gmail.com>
---
arch/x86/include/asm/hw_irq.h | 51 +++++++++++++++++++++++++++++++++++++++++++
arch/x86/kernel/apic/vector.c | 13 +++++++++++
arch/x86/kernel/irq.c | 12 ++++++++++
arch/x86/kernel/smpboot.c | 11 ++++++++++
arch/x86/xen/smp.c | 3 +++
drivers/pci/msi.c | 5 +++++
include/linux/irq.h | 8 +++++++
kernel/smpboot.c | 5 +++++
kernel/stop_machine.c | 10 +++++++++
9 files changed, 118 insertions(+)
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 08017d3..929e0d9 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -186,9 +186,60 @@ extern char irq_entries_start[];
#define trace_irq_entries_start irq_entries_start
#endif
+/*
+ * 在以下使用VECTOR_UNDEFINED:
+ * - arch/x86/kernel/irqinit.c|56| <<global>> [0 ... NR_VECTORS - 1] = VECTOR_UNDEFINED,
+ * - arch/x86/kernel/apic/vector.c|177| <<__assign_irq_vector>> VECTOR_UNDEFINED)
+ * - arch/x86/kernel/apic/vector.c|224| <<clear_irq_vector>> per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED;
+ * - arch/x86/kernel/apic/vector.c|239| <<clear_irq_vector>> per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED;
+ * - arch/x86/kernel/apic/vector.c|299| <<__setup_vector_irq>> if (irq <= VECTOR_UNDEFINED)
+ * - arch/x86/kernel/apic/vector.c|304| <<__setup_vector_irq>> per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED;
+ * - arch/x86/kernel/apic/vector.c|433| <<smp_irq_move_cleanup_interrupt>> if (irq <= VECTOR_UNDEFINED)
+ * - arch/x86/kernel/apic/vector.c|473| <<smp_irq_move_cleanup_interrupt>> __this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
+ * - arch/x86/kernel/irq.c|208| <<do_IRQ>> __this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
+ * - arch/x86/kernel/irq.c|470| <<fixup_irqs>> if (__this_cpu_read(vector_irq[vector]) <= VECTOR_UNDEFINED)
+ * - arch/x86/kernel/irq.c|488| <<fixup_irqs>> __this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
+ * - arch/x86/kernel/irqinit.c|64| <<vector_used_by_percpu_irq>> if (per_cpu(vector_irq, cpu)[vector] > VECTOR_UNDEFINED)
+ */
#define VECTOR_UNDEFINED (-1)
+/*
+ * 在以下使用VECTOR_RETRIGGERED:
+ * - arch/x86/kernel/irq.c|203| <<do_IRQ>> if (irq != VECTOR_RETRIGGERED) {
+ * - arch/x86/kernel/irq.c|483| <<fixup_irqs>> __this_cpu_write(vector_irq[vector], VECTOR_RETRIGGERED);
+ * - arch/x86/kernel/irq.c|487| <<fixup_irqs>> if (__this_cpu_read(vector_irq[vector]) != VECTOR_RETRIGGERED)
+ */
#define VECTOR_RETRIGGERED (-2)
+/*
+ * 在以下设置vector_irq:
+ * - arch/x86/kernel/apic/vector.c|184| <<__assign_irq_vector>> per_cpu(vector_irq, new_cpu)[vector] = irq;
+ * - arch/x86/kernel/apic/vector.c|219| <<clear_irq_vector>> per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED;
+ * - arch/x86/kernel/apic/vector.c|234| <<clear_irq_vector>> per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED;
+ * - arch/x86/kernel/apic/vector.c|285| <<__setup_vector_irq>> per_cpu(vector_irq, cpu)[vector] = irq;
+ * - arch/x86/kernel/apic/vector.c|295| <<__setup_vector_irq>> per_cpu(vector_irq, cpu)[vector] = VECTOR_UNDEFINED;
+ * - arch/x86/kernel/apic/vector.c|315| <<setup_vector_irq>> per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
+ * - arch/x86/kernel/apic/vector.c|460| <<smp_irq_move_cleanup_interrupt>> __this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
+ * - arch/x86/kernel/irq.c|208| <<do_IRQ>> __this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
+ * - arch/x86/kernel/irq.c|479| <<fixup_irqs>> __this_cpu_write(vector_irq[vector], VECTOR_RETRIGGERED);
+ * - arch/x86/kernel/irq.c|484| <<fixup_irqs>> __this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
+ * - arch/x86/kernel/irqinit.c|98| <<init_IRQ>> per_cpu(vector_irq, 0)[IRQ0_VECTOR + i] = i;
+ * - arch/x86/lguest/boot.c|868| <<lguest_init_IRQ>> __this_cpu_write(vector_irq[i], i - FIRST_EXTERNAL_VECTOR);
+ *
+ * 在以下使用vector_irq:
+ * - arch/x86/include/asm/hw_irq.h|193| <<global>> DECLARE_PER_CPU_USER_MAPPED(vector_irq_t, vector_irq);
+ * - arch/x86/kernel/irqinit.c|55| <<global>> DEFINE_PER_CPU_USER_MAPPED(vector_irq_t, vector_irq) = {
+ * - arch/x86/kernel/apic/vector.c|171| <<__assign_irq_vector>> if (per_cpu(vector_irq, new_cpu)[vector] >
+ * - arch/x86/kernel/apic/vector.c|232| <<clear_irq_vector>> if (per_cpu(vector_irq, cpu)[vector] != irq)
+ * - arch/x86/kernel/apic/vector.c|289| <<__setup_vector_irq>> irq = per_cpu(vector_irq, cpu)[vector];
+ * - arch/x86/kernel/apic/vector.c|418| <<smp_irq_move_cleanup_interrupt>> irq = __this_cpu_read(vector_irq[vector]);
+ * - arch/x86/kernel/irq.c|198| <<do_IRQ>> irq = __this_cpu_read(vector_irq[vector]);
+ * - arch/x86/kernel/irq.c|302| <<check_irq_vectors_for_cpu_disable>> irq = __this_cpu_read(vector_irq[vector]);
+ * - arch/x86/kernel/irq.c|361| <<check_irq_vectors_for_cpu_disable>> per_cpu(vector_irq, cpu)[vector] < 0)
+ * - arch/x86/kernel/irq.c|466| <<fixup_irqs>> if (__this_cpu_read(vector_irq[vector]) <= VECTOR_UNDEFINED)
+ * - arch/x86/kernel/irq.c|471| <<fixup_irqs>> irq = __this_cpu_read(vector_irq[vector]);
+ * - arch/x86/kernel/irq.c|483| <<fixup_irqs>> if (__this_cpu_read(vector_irq[vector]) != VECTOR_RETRIGGERED)
+ * - arch/x86/kernel/irqinit.c|64| <<vector_used_by_percpu_irq>> if (per_cpu(vector_irq, cpu)[vector] > VECTOR_UNDEFINED)
+ */
typedef int vector_irq_t[NR_VECTORS];
DECLARE_PER_CPU_USER_MAPPED(vector_irq_t, vector_irq);
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 4902161..42a40e2 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -98,6 +98,11 @@ static void free_irq_cfg(unsigned int at, struct irq_cfg *cfg)
kfree(cfg);
}
+/*
+ * called by:
+ * - arch/x86/kernel/apic/vector.c|201| <<assign_irq_vector>> err = __assign_irq_vector(irq, cfg, mask);
+ * - arch/x86/kernel/apic/vector.c|512| <<arch_setup_hwirq>> ret = __assign_irq_vector(irq, cfg, apic->target_cpus());
+ */
static int
__assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
{
@@ -267,6 +272,10 @@ int __init arch_early_irq_init(void)
return arch_early_ioapic_init();
}
+/*
+ * called by only:
+ * - arch/x86/kernel/apic/vector.c|317| <<setup_vector_irq>> __setup_vector_irq(cpu);
+ */
static void __setup_vector_irq(int cpu)
{
/* Initialize vector_irq on a new cpu */
@@ -299,6 +308,10 @@ static void __setup_vector_irq(int cpu)
/*
* Setup the vector to irq mappings. Must be called with vector_lock held.
*/
+/*
+ * called by:
+ * - arch/x86/kernel/smpboot.c|261| <<start_secondary>> setup_vector_irq(smp_processor_id());
+ */
void setup_vector_irq(int cpu)
{
int irq;
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 30e8e57..331dab8 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -372,6 +372,10 @@ int check_irq_vectors_for_cpu_disable(void)
}
/* A cpu has been removed from cpu_online_mask. Reset irq affinities. */
+/*
+ * called by:
+ * - arch/x86/kernel/smpboot.c|1409| <<cpu_disable_common>> fixup_irqs();
+ */
void fixup_irqs(void)
{
unsigned int irq, vector;
@@ -396,6 +400,10 @@ void fixup_irqs(void)
data = irq_desc_get_irq_data(desc);
affinity = data->affinity;
+ /*
+ * 关于cpumask_subset(), 如果affinity是cpu_online_mask的subset, 返回1
+ * 否则返回0
+ */
if (!irq_has_action(irq) || irqd_is_per_cpu(data) ||
cpumask_subset(affinity, cpu_online_mask)) {
raw_spin_unlock(&desc->lock);
@@ -409,6 +417,10 @@ void fixup_irqs(void)
*/
irq_force_complete_move(irq);
+ /*
+ * Returns >= nr_cpu_ids if no cpus set.
+ * 如果affinity里没有online的cpu了...
+ */
if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
break_affinity = 1;
affinity = cpu_online_mask;
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 6af203b..361a9c3 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1391,6 +1391,11 @@ static void __ref remove_cpu_from_maps(int cpu)
numa_remove_cpu(cpu);
}
+/*
+ * called by:
+ * - arch/x86/kernel/smpboot.c|1416| <<native_cpu_disable>> cpu_disable_common();
+ * - arch/x86/xen/smp.c|504| <<xen_cpu_disable>> cpu_disable_common();
+ */
void cpu_disable_common(void)
{
int cpu = smp_processor_id();
@@ -1404,6 +1409,12 @@ void cpu_disable_common(void)
fixup_irqs();
}
+/*
+ * called by:
+ * - arch/x86/include/asm/smp.h|125| <<__cpu_disable>> return smp_ops.cpu_disable();
+ *
+ * struct smp_ops smp_ops.cpu_disable = native_cpu_disable()
+ */
int native_cpu_disable(void)
{
int ret;
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 28b4ad6..af8df77 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -495,6 +495,9 @@ static void xen_smp_cpus_done(unsigned int max_cpus)
}
#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * struct smp_ops xen_smp_ops.cpu_disable = xen_cpu_disable()
+ */
static int xen_cpu_disable(void)
{
unsigned int cpu = smp_processor_id();
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index c3e7dfc..fcfdefd 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -246,6 +246,11 @@ static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
* file. This saves a few milliseconds when initialising devices with lots
* of MSI-X interrupts.
*/
+/*
+ * called by:
+ * - drivers/pci/msi.c|268| <<msix_mask_irq>> desc->masked = __pci_msix_desc_mask_irq(desc, flag);
+ * - drivers/pci/msi.c|1027| <<pci_msix_shutdown>> __pci_msix_desc_mask_irq(entry, 1);
+ */
u32 __pci_msix_desc_mask_irq(struct msi_desc *desc, u32 flag)
{
u32 mask_bits = desc->masked;
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 3532dca..a2684fc 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -187,6 +187,14 @@ enum {
IRQD_TRIGGER_MASK = 0xf,
IRQD_SETAFFINITY_PENDING = (1 << 8),
IRQD_NO_BALANCING = (1 << 10),
+ /*
+ * 在以下设置和使用IRQD_PER_CPU:
+ * - include/linux/irq.h|208| <<irqd_is_per_cpu>> return d->state_use_accessors & IRQD_PER_CPU;
+ * - include/linux/irq.h|213| <<irqd_can_balance>> return !(d->state_use_accessors & (IRQD_PER_CPU | IRQD_NO_BALANCING));
+ * - kernel/irq/chip.c|800| <<irq_modify_status>> irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU |
+ * - kernel/irq/chip.c|805| <<irq_modify_status>> irqd_set(&desc->irq_data, IRQD_PER_CPU);
+ * - kernel/irq/manage.c|1205| <<__setup_irq>> irqd_set(&desc->irq_data, IRQD_PER_CPU);
+ */
IRQD_PER_CPU = (1 << 11),
IRQD_AFFINITY_SET = (1 << 12),
IRQD_LEVEL = (1 << 13),
diff --git a/kernel/smpboot.c b/kernel/smpboot.c
index c697f73..50f086a 100644
--- a/kernel/smpboot.c
+++ b/kernel/smpboot.c
@@ -102,6 +102,10 @@ enum {
*
* Returns 1 when the thread should exit, 0 otherwise.
*/
+/*
+ * used by:
+ * - kernel/smpboot.c|182| <<__smpboot_create_thread>> tsk = kthread_create_on_cpu(smpboot_thread_fn, td, cpu,
+ */
static int smpboot_thread_fn(void *data)
{
struct smpboot_thread_data *td = data;
@@ -159,6 +163,7 @@ static int smpboot_thread_fn(void *data)
} else {
__set_current_state(TASK_RUNNING);
preempt_enable();
+ /* cpu_stopper_thread() ??? */
ht->thread_fn(td->cpu);
}
}
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
index 695f0c6..e04110a 100644
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -445,6 +445,12 @@ static int cpu_stop_should_run(unsigned int cpu)
return run;
}
+/*
+ * called by:
+ * - kernel/smpboot.c|166| <<smpboot_thread_fn>> ht->thread_fn(td->cpu);
+ *
+ * struct smp_hotplug_thread cpu_stop_threads.thread_fn = cpu_stopper_thread()
+ */
static void cpu_stopper_thread(unsigned int cpu)
{
struct cpu_stopper *stopper = &per_cpu(cpu_stopper, cpu);
@@ -516,6 +522,10 @@ static void cpu_stop_unpark(unsigned int cpu)
spin_unlock_irq(&stopper->lock);
}
+/*
+ * used by:
+ * - kernel/stop_machine.c|545| <<cpu_stop_init>> BUG_ON(smpboot_register_percpu_thread(&cpu_stop_threads));
+ */
static struct smp_hotplug_thread cpu_stop_threads = {
.store = &cpu_stopper_task,
.thread_should_run = cpu_stop_should_run,
--
2.7.4