Skip to content

Commit 47935a7

Browse files
committed
Merge branches 'x86-alternatives-for-linus', 'x86-fpu-for-linus', 'x86-hwmon-for-linus', 'x86-paravirt-for-linus', 'core-locking-for-linus' and 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-alternatives-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86, suspend: Avoid unnecessary smp alternatives switch during suspend/resume * 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86-64, asm: Use fxsaveq/fxrestorq in more places * 'x86-hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86, hwmon: Add core threshold notification to therm_throt.c * 'x86-paravirt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86, paravirt: Use native_halt on a halt, not native_safe_halt * 'core-locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: locking, lockdep: Convert sprintf_symbol to %pS * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: irq: Better struct irqaction layout
7 parents 77a0dd5 + 3fb82d5 + fd35fbc + 9e76a97 + c8217b8 + 3cf9b85 + f6cd247 commit 47935a7

File tree

11 files changed

+117
-15
lines changed

11 files changed

+117
-15
lines changed

arch/x86/include/asm/alternative.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ extern void alternatives_smp_module_add(struct module *mod, char *name,
6666
extern void alternatives_smp_module_del(struct module *mod);
6767
extern void alternatives_smp_switch(int smp);
6868
extern int alternatives_text_reserved(void *start, void *end);
69+
extern bool skip_smp_alternatives;
6970
#else
7071
static inline void alternatives_smp_module_add(struct module *mod, char *name,
7172
void *locks, void *locks_end,

arch/x86/include/asm/i387.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
9393
int err;
9494

9595
/* See comment in fxsave() below. */
96+
#ifdef CONFIG_AS_FXSAVEQ
97+
asm volatile("1: fxrstorq %[fx]\n\t"
98+
"2:\n"
99+
".section .fixup,\"ax\"\n"
100+
"3: movl $-1,%[err]\n"
101+
" jmp 2b\n"
102+
".previous\n"
103+
_ASM_EXTABLE(1b, 3b)
104+
: [err] "=r" (err)
105+
: [fx] "m" (*fx), "0" (0));
106+
#else
96107
asm volatile("1: rex64/fxrstor (%[fx])\n\t"
97108
"2:\n"
98109
".section .fixup,\"ax\"\n"
@@ -102,6 +113,7 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
102113
_ASM_EXTABLE(1b, 3b)
103114
: [err] "=r" (err)
104115
: [fx] "R" (fx), "m" (*fx), "0" (0));
116+
#endif
105117
return err;
106118
}
107119

@@ -119,6 +131,17 @@ static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
119131
return -EFAULT;
120132

121133
/* See comment in fxsave() below. */
134+
#ifdef CONFIG_AS_FXSAVEQ
135+
asm volatile("1: fxsaveq %[fx]\n\t"
136+
"2:\n"
137+
".section .fixup,\"ax\"\n"
138+
"3: movl $-1,%[err]\n"
139+
" jmp 2b\n"
140+
".previous\n"
141+
_ASM_EXTABLE(1b, 3b)
142+
: [err] "=r" (err), [fx] "=m" (*fx)
143+
: "0" (0));
144+
#else
122145
asm volatile("1: rex64/fxsave (%[fx])\n\t"
123146
"2:\n"
124147
".section .fixup,\"ax\"\n"
@@ -128,6 +151,7 @@ static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
128151
_ASM_EXTABLE(1b, 3b)
129152
: [err] "=r" (err), "=m" (*fx)
130153
: [fx] "R" (fx), "0" (0));
154+
#endif
131155
if (unlikely(err) &&
132156
__clear_user(fx, sizeof(struct i387_fxsave_struct)))
133157
err = -EFAULT;

arch/x86/include/asm/mce.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ void intel_init_thermal(struct cpuinfo_x86 *c);
223223

224224
void mce_log_therm_throt_event(__u64 status);
225225

226+
/* Interrupt Handler for core thermal thresholds */
227+
extern int (*platform_thermal_notify)(__u64 msr_val);
228+
226229
#ifdef CONFIG_X86_THERMAL_VECTOR
227230
extern void mcheck_intel_therm_init(void);
228231
#else

arch/x86/include/asm/msr-index.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,18 @@
257257
#define PACKAGE_THERM_INT_LOW_ENABLE (1 << 1)
258258
#define PACKAGE_THERM_INT_PLN_ENABLE (1 << 24)
259259

260+
/* Thermal Thresholds Support */
261+
#define THERM_INT_THRESHOLD0_ENABLE (1 << 15)
262+
#define THERM_SHIFT_THRESHOLD0 8
263+
#define THERM_MASK_THRESHOLD0 (0x7f << THERM_SHIFT_THRESHOLD0)
264+
#define THERM_INT_THRESHOLD1_ENABLE (1 << 23)
265+
#define THERM_SHIFT_THRESHOLD1 16
266+
#define THERM_MASK_THRESHOLD1 (0x7f << THERM_SHIFT_THRESHOLD1)
267+
#define THERM_STATUS_THRESHOLD0 (1 << 6)
268+
#define THERM_LOG_THRESHOLD0 (1 << 7)
269+
#define THERM_STATUS_THRESHOLD1 (1 << 8)
270+
#define THERM_LOG_THRESHOLD1 (1 << 9)
271+
260272
/* MISC_ENABLE bits: architectural */
261273
#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0)
262274
#define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1)

arch/x86/include/asm/paravirt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static inline void arch_safe_halt(void)
112112

113113
static inline void halt(void)
114114
{
115-
PVOP_VCALL0(pv_irq_ops.safe_halt);
115+
PVOP_VCALL0(pv_irq_ops.halt);
116116
}
117117

118118
static inline void wbinvd(void)

arch/x86/kernel/alternative.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ void __init_or_module alternatives_smp_module_del(struct module *mod)
353353
mutex_unlock(&smp_alt);
354354
}
355355

356+
bool skip_smp_alternatives;
356357
void alternatives_smp_switch(int smp)
357358
{
358359
struct smp_alt_module *mod;
@@ -368,7 +369,7 @@ void alternatives_smp_switch(int smp)
368369
printk("lockdep: fixing up alternatives.\n");
369370
#endif
370371

371-
if (noreplace_smp || smp_alt_once)
372+
if (noreplace_smp || smp_alt_once || skip_smp_alternatives)
372373
return;
373374
BUG_ON(!smp && (num_online_cpus() > 1));
374375

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,13 @@ struct thermal_state {
5353
struct _thermal_state core_power_limit;
5454
struct _thermal_state package_throttle;
5555
struct _thermal_state package_power_limit;
56+
struct _thermal_state core_thresh0;
57+
struct _thermal_state core_thresh1;
5658
};
5759

60+
/* Callback to handle core threshold interrupts */
61+
int (*platform_thermal_notify)(__u64 msr_val);
62+
5863
static DEFINE_PER_CPU(struct thermal_state, thermal_state);
5964

6065
static atomic_t therm_throt_en = ATOMIC_INIT(0);
@@ -200,6 +205,22 @@ static int therm_throt_process(bool new_event, int event, int level)
200205
return 0;
201206
}
202207

208+
static int thresh_event_valid(int event)
209+
{
210+
struct _thermal_state *state;
211+
unsigned int this_cpu = smp_processor_id();
212+
struct thermal_state *pstate = &per_cpu(thermal_state, this_cpu);
213+
u64 now = get_jiffies_64();
214+
215+
state = (event == 0) ? &pstate->core_thresh0 : &pstate->core_thresh1;
216+
217+
if (time_before64(now, state->next_check))
218+
return 0;
219+
220+
state->next_check = now + CHECK_INTERVAL;
221+
return 1;
222+
}
223+
203224
#ifdef CONFIG_SYSFS
204225
/* Add/Remove thermal_throttle interface for CPU device: */
205226
static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev,
@@ -313,6 +334,22 @@ device_initcall(thermal_throttle_init_device);
313334
#define PACKAGE_THROTTLED ((__u64)2 << 62)
314335
#define PACKAGE_POWER_LIMIT ((__u64)3 << 62)
315336

337+
static void notify_thresholds(__u64 msr_val)
338+
{
339+
/* check whether the interrupt handler is defined;
340+
* otherwise simply return
341+
*/
342+
if (!platform_thermal_notify)
343+
return;
344+
345+
/* lower threshold reached */
346+
if ((msr_val & THERM_LOG_THRESHOLD0) && thresh_event_valid(0))
347+
platform_thermal_notify(msr_val);
348+
/* higher threshold reached */
349+
if ((msr_val & THERM_LOG_THRESHOLD1) && thresh_event_valid(1))
350+
platform_thermal_notify(msr_val);
351+
}
352+
316353
/* Thermal transition interrupt handler */
317354
static void intel_thermal_interrupt(void)
318355
{
@@ -321,6 +358,9 @@ static void intel_thermal_interrupt(void)
321358

322359
rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
323360

361+
/* Check for violation of core thermal thresholds*/
362+
notify_thresholds(msr_val);
363+
324364
if (therm_throt_process(msr_val & THERM_STATUS_PROCHOT,
325365
THERMAL_THROTTLING_EVENT,
326366
CORE_LEVEL) != 0)

arch/x86/kernel/smpboot.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,20 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
11611161
preempt_enable();
11621162
}
11631163

1164+
void arch_disable_nonboot_cpus_begin(void)
1165+
{
1166+
/*
1167+
* Avoid the smp alternatives switch during the disable_nonboot_cpus().
1168+
* In the suspend path, we will be back in the SMP mode shortly anyways.
1169+
*/
1170+
skip_smp_alternatives = true;
1171+
}
1172+
1173+
void arch_disable_nonboot_cpus_end(void)
1174+
{
1175+
skip_smp_alternatives = false;
1176+
}
1177+
11641178
void arch_enable_nonboot_cpus_begin(void)
11651179
{
11661180
set_mtrr_aps_delayed_init();

include/linux/interrupt.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,15 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);
114114
struct irqaction {
115115
irq_handler_t handler;
116116
unsigned long flags;
117-
const char *name;
118117
void *dev_id;
119118
struct irqaction *next;
120119
int irq;
121-
struct proc_dir_entry *dir;
122120
irq_handler_t thread_fn;
123121
struct task_struct *thread;
124122
unsigned long thread_flags;
125-
};
123+
const char *name;
124+
struct proc_dir_entry *dir;
125+
} ____cacheline_internodealigned_in_smp;
126126

127127
extern irqreturn_t no_action(int cpl, void *dev_id);
128128

kernel/cpu.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,14 @@ int __cpuinit cpu_up(unsigned int cpu)
384384
#ifdef CONFIG_PM_SLEEP_SMP
385385
static cpumask_var_t frozen_cpus;
386386

387+
void __weak arch_disable_nonboot_cpus_begin(void)
388+
{
389+
}
390+
391+
void __weak arch_disable_nonboot_cpus_end(void)
392+
{
393+
}
394+
387395
int disable_nonboot_cpus(void)
388396
{
389397
int cpu, first_cpu, error = 0;
@@ -395,6 +403,7 @@ int disable_nonboot_cpus(void)
395403
* with the userspace trying to use the CPU hotplug at the same time
396404
*/
397405
cpumask_clear(frozen_cpus);
406+
arch_disable_nonboot_cpus_begin();
398407

399408
printk("Disabling non-boot CPUs ...\n");
400409
for_each_online_cpu(cpu) {
@@ -410,6 +419,8 @@ int disable_nonboot_cpus(void)
410419
}
411420
}
412421

422+
arch_disable_nonboot_cpus_end();
423+
413424
if (!error) {
414425
BUG_ON(num_online_cpus() > 1);
415426
/* Make sure the CPUs won't be enabled by someone else */

kernel/lockdep_proc.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,6 @@ static void seq_stats(struct seq_file *m, struct lock_stat_data *data)
494494
namelen += 2;
495495

496496
for (i = 0; i < LOCKSTAT_POINTS; i++) {
497-
char sym[KSYM_SYMBOL_LEN];
498497
char ip[32];
499498

500499
if (class->contention_point[i] == 0)
@@ -503,15 +502,13 @@ static void seq_stats(struct seq_file *m, struct lock_stat_data *data)
503502
if (!i)
504503
seq_line(m, '-', 40-namelen, namelen);
505504

506-
sprint_symbol(sym, class->contention_point[i]);
507505
snprintf(ip, sizeof(ip), "[<%p>]",
508506
(void *)class->contention_point[i]);
509-
seq_printf(m, "%40s %14lu %29s %s\n", name,
510-
stats->contention_point[i],
511-
ip, sym);
507+
seq_printf(m, "%40s %14lu %29s %pS\n",
508+
name, stats->contention_point[i],
509+
ip, (void *)class->contention_point[i]);
512510
}
513511
for (i = 0; i < LOCKSTAT_POINTS; i++) {
514-
char sym[KSYM_SYMBOL_LEN];
515512
char ip[32];
516513

517514
if (class->contending_point[i] == 0)
@@ -520,12 +517,11 @@ static void seq_stats(struct seq_file *m, struct lock_stat_data *data)
520517
if (!i)
521518
seq_line(m, '-', 40-namelen, namelen);
522519

523-
sprint_symbol(sym, class->contending_point[i]);
524520
snprintf(ip, sizeof(ip), "[<%p>]",
525521
(void *)class->contending_point[i]);
526-
seq_printf(m, "%40s %14lu %29s %s\n", name,
527-
stats->contending_point[i],
528-
ip, sym);
522+
seq_printf(m, "%40s %14lu %29s %pS\n",
523+
name, stats->contending_point[i],
524+
ip, (void *)class->contending_point[i]);
529525
}
530526
if (i) {
531527
seq_puts(m, "\n");

0 commit comments

Comments
 (0)