Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 86ef5c9a authored by Gautham R Shenoy's avatar Gautham R Shenoy Committed by Ingo Molnar
Browse files

cpu-hotplug: replace lock_cpu_hotplug() with get_online_cpus()



Replace all lock_cpu_hotplug/unlock_cpu_hotplug from the kernel and use
get_online_cpus and put_online_cpus instead as it highlights the
refcount semantics in these operations.

The new API guarantees protection against the cpu-hotplug operation, but
it doesn't guarantee serialized access to any of the local data
structures. Hence the changes needs to be reviewed.

In case of pseries_add_processor/pseries_remove_processor, use
cpu_maps_update_begin()/cpu_maps_update_done() as we're modifying the
cpu_present_map there.

Signed-off-by: default avatarGautham R Shenoy <ego@in.ibm.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent d221938c
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -109,12 +109,13 @@ Never use anything other than cpumask_t to represent bitmap of CPUs.
	for_each_cpu_mask(x,mask) - Iterate over some random collection of cpu mask.

	#include <linux/cpu.h>
	lock_cpu_hotplug() and unlock_cpu_hotplug():
	get_online_cpus() and put_online_cpus():

The above calls are used to inhibit cpu hotplug operations. While holding the
cpucontrol mutex, cpu_online_map will not change. If you merely need to avoid
cpus going away, you could also use preempt_disable() and preempt_enable()
for those sections. Just remember the critical section cannot call any
The above calls are used to inhibit cpu hotplug operations. While the
cpu_hotplug.refcount is non zero, the cpu_online_map will not change.
If you merely need to avoid cpus going away, you could also use
preempt_disable() and preempt_enable() for those sections.
Just remember the critical section cannot call any
function that can sleep or schedule this process away. The preempt_disable()
will work as long as stop_machine_run() is used to take a cpu down.

+5 −5
Original line number Diff line number Diff line
@@ -58,13 +58,13 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
	if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask)))
		return -EFAULT;

	lock_cpu_hotplug();
	get_online_cpus();
	read_lock(&tasklist_lock);

	p = find_process_by_pid(pid);
	if (!p) {
		read_unlock(&tasklist_lock);
		unlock_cpu_hotplug();
		put_online_cpus();
		return -ESRCH;
	}

@@ -106,7 +106,7 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,

out_unlock:
	put_task_struct(p);
	unlock_cpu_hotplug();
	put_online_cpus();
	return retval;
}

@@ -125,7 +125,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
	if (len < real_len)
		return -EINVAL;

	lock_cpu_hotplug();
	get_online_cpus();
	read_lock(&tasklist_lock);

	retval = -ESRCH;
@@ -140,7 +140,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,

out_unlock:
	read_unlock(&tasklist_lock);
	unlock_cpu_hotplug();
	put_online_cpus();
	if (retval)
		return retval;
	if (copy_to_user(user_mask_ptr, &mask, real_len))
+4 −4
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ static int pseries_add_processor(struct device_node *np)
	for (i = 0; i < nthreads; i++)
		cpu_set(i, tmp);

	lock_cpu_hotplug();
	cpu_maps_update_begin();

	BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map));

@@ -190,7 +190,7 @@ static int pseries_add_processor(struct device_node *np)
	}
	err = 0;
out_unlock:
	unlock_cpu_hotplug();
	cpu_maps_update_done();
	return err;
}

@@ -211,7 +211,7 @@ static void pseries_remove_processor(struct device_node *np)

	nthreads = len / sizeof(u32);

	lock_cpu_hotplug();
	cpu_maps_update_begin();
	for (i = 0; i < nthreads; i++) {
		for_each_present_cpu(cpu) {
			if (get_hard_smp_processor_id(cpu) != intserv[i])
@@ -225,7 +225,7 @@ static void pseries_remove_processor(struct device_node *np)
			printk(KERN_WARNING "Could not find cpu to remove "
			       "with physical id 0x%x\n", intserv[i]);
	}
	unlock_cpu_hotplug();
	cpu_maps_update_done();
}

static int pseries_smp_notifier(struct notifier_block *nb,
+4 −4
Original line number Diff line number Diff line
@@ -382,7 +382,7 @@ static void do_event_scan_all_cpus(long delay)
{
	int cpu;

	lock_cpu_hotplug();
	get_online_cpus();
	cpu = first_cpu(cpu_online_map);
	for (;;) {
		set_cpus_allowed(current, cpumask_of_cpu(cpu));
@@ -390,15 +390,15 @@ static void do_event_scan_all_cpus(long delay)
		set_cpus_allowed(current, CPU_MASK_ALL);

		/* Drop hotplug lock, and sleep for the specified delay */
		unlock_cpu_hotplug();
		put_online_cpus();
		msleep_interruptible(delay);
		lock_cpu_hotplug();
		get_online_cpus();

		cpu = next_cpu(cpu, cpu_online_map);
		if (cpu == NR_CPUS)
			break;
	}
	unlock_cpu_hotplug();
	put_online_cpus();
}

static int rtasd(void *unused)
+4 −4
Original line number Diff line number Diff line
@@ -349,7 +349,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
	replace = -1;

	/* No CPU hotplug when we change MTRR entries */
	lock_cpu_hotplug();
	get_online_cpus();
	/*  Search for existing MTRR  */
	mutex_lock(&mtrr_mutex);
	for (i = 0; i < num_var_ranges; ++i) {
@@ -405,7 +405,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
	error = i;
 out:
	mutex_unlock(&mtrr_mutex);
	unlock_cpu_hotplug();
	put_online_cpus();
	return error;
}

@@ -495,7 +495,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)

	max = num_var_ranges;
	/* No CPU hotplug when we change MTRR entries */
	lock_cpu_hotplug();
	get_online_cpus();
	mutex_lock(&mtrr_mutex);
	if (reg < 0) {
		/*  Search for existing MTRR  */
@@ -536,7 +536,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
	error = reg;
 out:
	mutex_unlock(&mtrr_mutex);
	unlock_cpu_hotplug();
	put_online_cpus();
	return error;
}
/**
Loading