Provide static call to control IRQ preemption (called in CONFIG_PREEMPT) so that we can override its behaviour when preempt= is overriden. Since the default behaviour is full preemption, its call is initialized to provide IRQ preemption when preempt= isn't passed.
Unified · Split
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | #ifndef __LINUX_ENTRYCOMMON_H | 2 | #ifndef __LINUX_ENTRYCOMMON_H |
| 3 | #define __LINUX_ENTRYCOMMON_H | 3 | #define __LINUX_ENTRYCOMMON_H |
| 4 | 4 | ||
| 5 | #include <linux/static_call_types.h> | ||
| 5 | #include <linux/tracehook.h> | 6 | #include <linux/tracehook.h> |
| 6 | #include <linux/syscalls.h> | 7 | #include <linux/syscalls.h> |
| 7 | #include <linux/seccomp.h> | 8 | #include <linux/seccomp.h> |
| @@ -454,6 +455,9 @@ irqentry_state_t noinstr irqentry_enter(struct pt_regs *regs); · 446 unmodified lines | |||
| 454 | * Conditional reschedule with additional sanity checks. | 455 | * Conditional reschedule with additional sanity checks. |
| 455 | */ | 456 | */ |
| 456 | void irqentry_exit_cond_resched(void); | 457 | void irqentry_exit_cond_resched(void); |
| 458 | #ifdef CONFIG_PREEMPT_DYNAMIC | ||
| 459 | DECLARE_STATIC_CALL(irqentry_exit_cond_resched, irqentry_exit_cond_resched); | ||
| 460 | #endif | ||
| 457 | 461 | ||
| 458 | /** | 462 | /** |
| 459 | * irqentry_exit - Handle return from exception that used irqentry_enter() | 463 | * irqentry_exit - Handle return from exception that used irqentry_enter() |
| @@ -385,6 +385,9 @@ void irqentry_exit_cond_resched(void) · 384 unmodified lines | |||
| 385 | preempt_schedule_irq(); | 385 | preempt_schedule_irq(); |
| 386 | } | 386 | } |
| 387 | } | 387 | } |
| 388 | #ifdef CONFIG_PREEMPT_DYNAMIC | ||
| 389 | DEFINE_STATIC_CALL(irqentry_exit_cond_resched, irqentry_exit_cond_resched); | ||
| 390 | #endif | ||
| 388 | 391 | ||
| 389 | noinstr void irqentry_exit(struct pt_regs *regs, irqentry_state_t state) | 392 | noinstr void irqentry_exit(struct pt_regs *regs, irqentry_state_t state) |
| 390 | { | 393 | { |
| @@ -411,8 +414,13 @@ noinstr void irqentry_exit(struct pt_regs *regs, irqentry_state_t state) · 20 unmodified lines | |||
| 411 | } | 414 | } |
| 412 | 415 | ||
| 413 | instrumentation_begin(); | 416 | instrumentation_begin(); |
| 414 | if (IS_ENABLED(CONFIG_PREEMPTION)) | 417 | if (IS_ENABLED(CONFIG_PREEMPTION)) { |
| 418 | #ifdef CONFIG_PREEMT_DYNAMIC | ||
| 419 | static_call(irqentry_exit_cond_resched)(); | ||
| 420 | #else | ||
| 415 | irqentry_exit_cond_resched(); | 421 | irqentry_exit_cond_resched(); |
| 422 | #endif | ||
| 423 | } | ||
| 416 | /* Covers both tracing and lockdep */ | 424 | /* Covers both tracing and lockdep */ |
| 417 | trace_hardirqs_on(); | 425 | trace_hardirqs_on(); |
| 418 | instrumentation_end(); | 426 | instrumentation_end(); |