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>
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index 5a17806..67bcc1c 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -39,7 +39,7 @@
 {
 	int i;
 
-	for_each_online_cpu(i) {
+	for_each_possible_cpu(i) {
 		vfree(per_cpu(cpu_buffer, i).buffer);
 		per_cpu(cpu_buffer, i).buffer = NULL;
 	}
@@ -51,7 +51,7 @@
 
 	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);
 
 		b->buffer = vmalloc_node(sizeof(struct op_sample) * buffer_size,
@@ -350,6 +350,11 @@
 	if (b->cpu != smp_processor_id()) {
 		printk(KERN_DEBUG "WQ on CPU%d, prefer CPU%d\n",
 		       smp_processor_id(), b->cpu);
+
+		if (!cpu_online(b->cpu)) {
+			cancel_delayed_work(&b->work);
+			return;
+		}
 	}
 	sync_buffer(b->cpu);