Skip to content

Commit f89db78

Browse files
committed
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar: "Two documentation updates, plus a debugging annotation fix" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/crash: Update the stale comment in reserve_crashkernel() x86/irq, trace: Add __irq_entry annotation to x86's platform IRQ handlers Documentation, x86, resctrl: Recommend locking for resctrlfs
2 parents 65314ed + 8312593 commit f89db78

File tree

10 files changed

+144
-22
lines changed

10 files changed

+144
-22
lines changed

Documentation/x86/intel_rdt_ui.txt

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,117 @@ Finally we move core 4-7 over to the new group and make sure that the
212212
kernel and the tasks running there get 50% of the cache.
213213

214214
# echo C0 > p0/cpus
215+
216+
4) Locking between applications
217+
218+
Certain operations on the resctrl filesystem, composed of read/writes
219+
to/from multiple files, must be atomic.
220+
221+
As an example, the allocation of an exclusive reservation of L3 cache
222+
involves:
223+
224+
1. Read the cbmmasks from each directory
225+
2. Find a contiguous set of bits in the global CBM bitmask that is clear
226+
in any of the directory cbmmasks
227+
3. Create a new directory
228+
4. Set the bits found in step 2 to the new directory "schemata" file
229+
230+
If two applications attempt to allocate space concurrently then they can
231+
end up allocating the same bits so the reservations are shared instead of
232+
exclusive.
233+
234+
To coordinate atomic operations on the resctrlfs and to avoid the problem
235+
above, the following locking procedure is recommended:
236+
237+
Locking is based on flock, which is available in libc and also as a shell
238+
script command
239+
240+
Write lock:
241+
242+
A) Take flock(LOCK_EX) on /sys/fs/resctrl
243+
B) Read/write the directory structure.
244+
C) funlock
245+
246+
Read lock:
247+
248+
A) Take flock(LOCK_SH) on /sys/fs/resctrl
249+
B) If success read the directory structure.
250+
C) funlock
251+
252+
Example with bash:
253+
254+
# Atomically read directory structure
255+
$ flock -s /sys/fs/resctrl/ find /sys/fs/resctrl
256+
257+
# Read directory contents and create new subdirectory
258+
259+
$ cat create-dir.sh
260+
find /sys/fs/resctrl/ > output.txt
261+
mask = function-of(output.txt)
262+
mkdir /sys/fs/resctrl/newres/
263+
echo mask > /sys/fs/resctrl/newres/schemata
264+
265+
$ flock /sys/fs/resctrl/ ./create-dir.sh
266+
267+
Example with C:
268+
269+
/*
270+
* Example code do take advisory locks
271+
* before accessing resctrl filesystem
272+
*/
273+
#include <sys/file.h>
274+
#include <stdlib.h>
275+
276+
void resctrl_take_shared_lock(int fd)
277+
{
278+
int ret;
279+
280+
/* take shared lock on resctrl filesystem */
281+
ret = flock(fd, LOCK_SH);
282+
if (ret) {
283+
perror("flock");
284+
exit(-1);
285+
}
286+
}
287+
288+
void resctrl_take_exclusive_lock(int fd)
289+
{
290+
int ret;
291+
292+
/* release lock on resctrl filesystem */
293+
ret = flock(fd, LOCK_EX);
294+
if (ret) {
295+
perror("flock");
296+
exit(-1);
297+
}
298+
}
299+
300+
void resctrl_release_lock(int fd)
301+
{
302+
int ret;
303+
304+
/* take shared lock on resctrl filesystem */
305+
ret = flock(fd, LOCK_UN);
306+
if (ret) {
307+
perror("flock");
308+
exit(-1);
309+
}
310+
}
311+
312+
void main(void)
313+
{
314+
int fd, ret;
315+
316+
fd = open("/sys/fs/resctrl", O_DIRECTORY);
317+
if (fd == -1) {
318+
perror("open");
319+
exit(-1);
320+
}
321+
resctrl_take_shared_lock(fd);
322+
/* code to read directory contents */
323+
resctrl_release_lock(fd);
324+
325+
resctrl_take_exclusive_lock(fd);
326+
/* code to read and write directory contents */
327+
resctrl_release_lock(fd);
328+
}

arch/x86/kernel/apic/apic.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,14 +1865,14 @@ static void __smp_spurious_interrupt(u8 vector)
18651865
"should never happen.\n", vector, smp_processor_id());
18661866
}
18671867

1868-
__visible void smp_spurious_interrupt(struct pt_regs *regs)
1868+
__visible void __irq_entry smp_spurious_interrupt(struct pt_regs *regs)
18691869
{
18701870
entering_irq();
18711871
__smp_spurious_interrupt(~regs->orig_ax);
18721872
exiting_irq();
18731873
}
18741874

1875-
__visible void smp_trace_spurious_interrupt(struct pt_regs *regs)
1875+
__visible void __irq_entry smp_trace_spurious_interrupt(struct pt_regs *regs)
18761876
{
18771877
u8 vector = ~regs->orig_ax;
18781878

@@ -1923,14 +1923,14 @@ static void __smp_error_interrupt(struct pt_regs *regs)
19231923

19241924
}
19251925

1926-
__visible void smp_error_interrupt(struct pt_regs *regs)
1926+
__visible void __irq_entry smp_error_interrupt(struct pt_regs *regs)
19271927
{
19281928
entering_irq();
19291929
__smp_error_interrupt(regs);
19301930
exiting_irq();
19311931
}
19321932

1933-
__visible void smp_trace_error_interrupt(struct pt_regs *regs)
1933+
__visible void __irq_entry smp_trace_error_interrupt(struct pt_regs *regs)
19341934
{
19351935
entering_irq();
19361936
trace_error_apic_entry(ERROR_APIC_VECTOR);

arch/x86/kernel/apic/vector.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ void send_cleanup_vector(struct irq_cfg *cfg)
559559
__send_cleanup_vector(data);
560560
}
561561

562-
asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
562+
asmlinkage __visible void __irq_entry smp_irq_move_cleanup_interrupt(void)
563563
{
564564
unsigned vector, me;
565565

arch/x86/kernel/cpu/mcheck/mce_amd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -816,14 +816,14 @@ static inline void __smp_deferred_error_interrupt(void)
816816
deferred_error_int_vector();
817817
}
818818

819-
asmlinkage __visible void smp_deferred_error_interrupt(void)
819+
asmlinkage __visible void __irq_entry smp_deferred_error_interrupt(void)
820820
{
821821
entering_irq();
822822
__smp_deferred_error_interrupt();
823823
exiting_ack_irq();
824824
}
825825

826-
asmlinkage __visible void smp_trace_deferred_error_interrupt(void)
826+
asmlinkage __visible void __irq_entry smp_trace_deferred_error_interrupt(void)
827827
{
828828
entering_irq();
829829
trace_deferred_error_apic_entry(DEFERRED_ERROR_VECTOR);

arch/x86/kernel/cpu/mcheck/therm_throt.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,14 +396,16 @@ static inline void __smp_thermal_interrupt(void)
396396
smp_thermal_vector();
397397
}
398398

399-
asmlinkage __visible void smp_thermal_interrupt(struct pt_regs *regs)
399+
asmlinkage __visible void __irq_entry
400+
smp_thermal_interrupt(struct pt_regs *regs)
400401
{
401402
entering_irq();
402403
__smp_thermal_interrupt();
403404
exiting_ack_irq();
404405
}
405406

406-
asmlinkage __visible void smp_trace_thermal_interrupt(struct pt_regs *regs)
407+
asmlinkage __visible void __irq_entry
408+
smp_trace_thermal_interrupt(struct pt_regs *regs)
407409
{
408410
entering_irq();
409411
trace_thermal_apic_entry(THERMAL_APIC_VECTOR);

arch/x86/kernel/cpu/mcheck/threshold.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ static inline void __smp_threshold_interrupt(void)
2323
mce_threshold_vector();
2424
}
2525

26-
asmlinkage __visible void smp_threshold_interrupt(void)
26+
asmlinkage __visible void __irq_entry smp_threshold_interrupt(void)
2727
{
2828
entering_irq();
2929
__smp_threshold_interrupt();
3030
exiting_ack_irq();
3131
}
3232

33-
asmlinkage __visible void smp_trace_threshold_interrupt(void)
33+
asmlinkage __visible void __irq_entry smp_trace_threshold_interrupt(void)
3434
{
3535
entering_irq();
3636
trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR);

arch/x86/kernel/irq.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ void __smp_x86_platform_ipi(void)
264264
x86_platform_ipi_callback();
265265
}
266266

267-
__visible void smp_x86_platform_ipi(struct pt_regs *regs)
267+
__visible void __irq_entry smp_x86_platform_ipi(struct pt_regs *regs)
268268
{
269269
struct pt_regs *old_regs = set_irq_regs(regs);
270270

@@ -315,7 +315,7 @@ __visible void smp_kvm_posted_intr_wakeup_ipi(struct pt_regs *regs)
315315
}
316316
#endif
317317

318-
__visible void smp_trace_x86_platform_ipi(struct pt_regs *regs)
318+
__visible void __irq_entry smp_trace_x86_platform_ipi(struct pt_regs *regs)
319319
{
320320
struct pt_regs *old_regs = set_irq_regs(regs);
321321

arch/x86/kernel/irq_work.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,22 @@
99
#include <linux/hardirq.h>
1010
#include <asm/apic.h>
1111
#include <asm/trace/irq_vectors.h>
12+
#include <linux/interrupt.h>
1213

1314
static inline void __smp_irq_work_interrupt(void)
1415
{
1516
inc_irq_stat(apic_irq_work_irqs);
1617
irq_work_run();
1718
}
1819

19-
__visible void smp_irq_work_interrupt(struct pt_regs *regs)
20+
__visible void __irq_entry smp_irq_work_interrupt(struct pt_regs *regs)
2021
{
2122
ipi_entering_ack_irq();
2223
__smp_irq_work_interrupt();
2324
exiting_irq();
2425
}
2526

26-
__visible void smp_trace_irq_work_interrupt(struct pt_regs *regs)
27+
__visible void __irq_entry smp_trace_irq_work_interrupt(struct pt_regs *regs)
2728
{
2829
ipi_entering_ack_irq();
2930
trace_irq_work_entry(IRQ_WORK_VECTOR);

arch/x86/kernel/setup.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,9 @@ static void __init reserve_crashkernel(void)
575575
/* 0 means: find the address automatically */
576576
if (crash_base <= 0) {
577577
/*
578-
* kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
578+
* Set CRASH_ADDR_LOW_MAX upper bound for crash memory,
579+
* as old kexec-tools loads bzImage below that, unless
580+
* "crashkernel=size[KMG],high" is specified.
579581
*/
580582
crash_base = memblock_find_in_range(CRASH_ALIGN,
581583
high ? CRASH_ADDR_HIGH_MAX

arch/x86/kernel/smp.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ static inline void __smp_reschedule_interrupt(void)
259259
scheduler_ipi();
260260
}
261261

262-
__visible void smp_reschedule_interrupt(struct pt_regs *regs)
262+
__visible void __irq_entry smp_reschedule_interrupt(struct pt_regs *regs)
263263
{
264264
ack_APIC_irq();
265265
__smp_reschedule_interrupt();
@@ -268,7 +268,7 @@ __visible void smp_reschedule_interrupt(struct pt_regs *regs)
268268
*/
269269
}
270270

271-
__visible void smp_trace_reschedule_interrupt(struct pt_regs *regs)
271+
__visible void __irq_entry smp_trace_reschedule_interrupt(struct pt_regs *regs)
272272
{
273273
/*
274274
* Need to call irq_enter() before calling the trace point.
@@ -292,14 +292,15 @@ static inline void __smp_call_function_interrupt(void)
292292
inc_irq_stat(irq_call_count);
293293
}
294294

295-
__visible void smp_call_function_interrupt(struct pt_regs *regs)
295+
__visible void __irq_entry smp_call_function_interrupt(struct pt_regs *regs)
296296
{
297297
ipi_entering_ack_irq();
298298
__smp_call_function_interrupt();
299299
exiting_irq();
300300
}
301301

302-
__visible void smp_trace_call_function_interrupt(struct pt_regs *regs)
302+
__visible void __irq_entry
303+
smp_trace_call_function_interrupt(struct pt_regs *regs)
303304
{
304305
ipi_entering_ack_irq();
305306
trace_call_function_entry(CALL_FUNCTION_VECTOR);
@@ -314,14 +315,16 @@ static inline void __smp_call_function_single_interrupt(void)
314315
inc_irq_stat(irq_call_count);
315316
}
316317

317-
__visible void smp_call_function_single_interrupt(struct pt_regs *regs)
318+
__visible void __irq_entry
319+
smp_call_function_single_interrupt(struct pt_regs *regs)
318320
{
319321
ipi_entering_ack_irq();
320322
__smp_call_function_single_interrupt();
321323
exiting_irq();
322324
}
323325

324-
__visible void smp_trace_call_function_single_interrupt(struct pt_regs *regs)
326+
__visible void __irq_entry
327+
smp_trace_call_function_single_interrupt(struct pt_regs *regs)
325328
{
326329
ipi_entering_ack_irq();
327330
trace_call_function_single_entry(CALL_FUNCTION_SINGLE_VECTOR);

0 commit comments

Comments
 (0)