浏览代码

oprofile: hotplug cpu fix

This patch addresses problems when hotplugging cpus while
profiling. Instead of allocating only online cpus, all possible cpu
buffers are allocated, which allows cpus to be onlined during
operation. If a cpu is offlined before profiling is shutdown
wq_sync_buffer checks for this condition then cancels this work and
does not sync this buffer.

Signed-off-by: Chris J Arges <arges@linux.vnet.ibm.com>
Signed-off-by: Robert Richter <robert.richter@amd.com>
Chris J Arges 17 年之前
父节点
当前提交
4bd9b9dc97
共有 1 个文件被更改,包括 7 次插入2 次删除
  1. 7 2
      drivers/oprofile/cpu_buffer.c

+ 7 - 2
drivers/oprofile/cpu_buffer.c

@@ -39,7 +39,7 @@ void free_cpu_buffers(void)
 {
 {
 	int i;
 	int i;
 
 
-	for_each_online_cpu(i) {
+	for_each_possible_cpu(i) {
 		vfree(per_cpu(cpu_buffer, i).buffer);
 		vfree(per_cpu(cpu_buffer, i).buffer);
 		per_cpu(cpu_buffer, i).buffer = NULL;
 		per_cpu(cpu_buffer, i).buffer = NULL;
 	}
 	}
@@ -51,7 +51,7 @@ int alloc_cpu_buffers(void)
 
 
 	unsigned long buffer_size = fs_cpu_buffer_size;
 	unsigned long buffer_size = fs_cpu_buffer_size;
 
 
-	for_each_online_cpu(i) {
+	for_each_possible_cpu(i) {
 		struct oprofile_cpu_buffer *b = &per_cpu(cpu_buffer, i);
 		struct oprofile_cpu_buffer *b = &per_cpu(cpu_buffer, i);
 
 
 		b->buffer = vmalloc_node(sizeof(struct op_sample) * buffer_size,
 		b->buffer = vmalloc_node(sizeof(struct op_sample) * buffer_size,
@@ -350,6 +350,11 @@ static void wq_sync_buffer(struct work_struct *work)
 	if (b->cpu != smp_processor_id()) {
 	if (b->cpu != smp_processor_id()) {
 		printk(KERN_DEBUG "WQ on CPU%d, prefer CPU%d\n",
 		printk(KERN_DEBUG "WQ on CPU%d, prefer CPU%d\n",
 		       smp_processor_id(), b->cpu);
 		       smp_processor_id(), b->cpu);
+
+		if (!cpu_online(b->cpu)) {
+			cancel_delayed_work(&b->work);
+			return;
+		}
 	}
 	}
 	sync_buffer(b->cpu);
 	sync_buffer(b->cpu);