All of lore.kernel.org
 help / color / mirror / Atom feed
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: "Liu, Jinsong" <jinsong.liu@intel.com>
Cc: "xen-devel@lists.xensource.com" <xen-devel@lists.xensource.com>,
	"jeremy.fitzhardinge@citrix.com" <jeremy.fitzhardinge@citrix.com>,
	"Jiang, Yunhong" <yunhong.jiang@intel.com>
Subject: Re: [PATCH 08/10] xen/acpi: add cpu hotadd support
Date: Wed, 3 Oct 2012 09:31:56 -0400	[thread overview]
Message-ID: <20121003133156.GB31173@phenom.dumpdata.com> (raw)
In-Reply-To: <DE8DF0795D48FD4CA783C40EC82923358A81@SHSMSX101.ccr.corp.intel.com>

On Thu, Dec 22, 2011 at 10:08:34AM +0000, Liu, Jinsong wrote:
> >From 282958be3a33b2f2b888e1ed3ac022bf8a199ec9 Mon Sep 17 00:00:00 2001
> From: Liu Jinsong <jinsong.liu@intel.com>
> Date: Wed, 14 Dec 2011 11:38:11 +0800
> Subject: [PATCH 08/10] xen/acpi: add cpu hotadd support
> 
> This patch add cpu hotadd support.
> It keep similar cpu hotadd logic as native, w/ some changes according
> to xen requirement, hypercalling hypervisor related logic to hotadd cpu.

Is this needed anymore? Or is the existing code in the upstream
kernel sufficient enough for this? Or do we need a hotplug CPU notifier
in the xen-acpi-processor?

> 
> Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
> Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
> ---
>  drivers/acpi/processor_driver.c |    4 +-
>  drivers/acpi/processor_xen.c    |  242 ++++++++++++++++++++++++++++++++++++++-
>  include/acpi/processor.h        |    2 +
>  include/xen/pcpu.h              |    2 +
>  4 files changed, 246 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
> index 8a367d7..d473fd5 100644
> --- a/drivers/acpi/processor_driver.c
> +++ b/drivers/acpi/processor_driver.c
> @@ -221,7 +221,7 @@ static int acpi_processor_errata_piix4(struct pci_dev *dev)
>  	return 0;
>  }
>  
> -static int acpi_processor_errata(struct acpi_processor *pr)
> +int acpi_processor_errata(struct acpi_processor *pr)
>  {
>  	int result = 0;
>  	struct pci_dev *dev = NULL;
> @@ -378,7 +378,7 @@ static int acpi_processor_get_info(struct acpi_device *device)
>  	return 0;
>  }
>  
> -static DEFINE_PER_CPU(void *, processor_device_array);
> +DEFINE_PER_CPU(void *, processor_device_array);
>  
>  void acpi_processor_notify(struct acpi_device *device, u32 event)
>  {
> diff --git a/drivers/acpi/processor_xen.c b/drivers/acpi/processor_xen.c
> index 38a1c05..3af1f73 100644
> --- a/drivers/acpi/processor_xen.c
> +++ b/drivers/acpi/processor_xen.c
> @@ -24,6 +24,7 @@
>  #define PREFIX "ACPI: "
>  
>  #define ACPI_PROCESSOR_CLASS            "processor"
> +#define ACPI_PROCESSOR_DEVICE_NAME      "Processor"
>  #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
>  #define ACPI_PROCESSOR_NOTIFY_POWER	0x81
>  #define ACPI_PROCESSOR_NOTIFY_THROTTLING	0x82
> @@ -88,6 +89,8 @@ xen_acpi_processor_hotadd_init(struct acpi_processor *pr, int *p_cpu)
>  				PROCESSOR_HOTPLUG, HOTPLUG_TYPE_ADD))
>  		return AE_ERROR;
>  
> +	*p_cpu = xen_pcpu_index(pr->acpi_id, 1);
> +
>  	return AE_OK;
>  }
>  
> @@ -149,13 +152,248 @@ err_out:
>  }
>  #endif /* CONFIG_CPU_FREQ */
>  
> +static int xen_acpi_processor_get_info(struct acpi_device *device)
> +{
> +	acpi_status status = 0;
> +	union acpi_object object = { 0 };
> +	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
> +	struct acpi_processor *pr;
> +	int cpu_index, device_declaration = 0;
> +	static int cpu0_initialized;
> +
> +	pr = acpi_driver_data(device);
> +	if (!pr)
> +		return -EINVAL;
> +
> +	if (num_online_cpus() > 1)
> +		errata.smp = TRUE;
> +
> +	acpi_processor_errata(pr);
> +
> +	/*
> +	 * Check to see if we have bus mastering arbitration control.  This
> +	 * is required for proper C3 usage (to maintain cache coherency).
> +	 */
> +	if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
> +		pr->flags.bm_control = 1;
> +		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
> +				  "Bus mastering arbitration control present\n"));
> +	} else
> +		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
> +				  "No bus mastering arbitration control\n"));
> +
> +	if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
> +		/* Declared with "Processor" statement; match ProcessorID */
> +		status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
> +		if (ACPI_FAILURE(status)) {
> +			printk(KERN_ERR PREFIX "Evaluating processor object\n");
> +			return -ENODEV;
> +		}
> +
> +		/*
> +		 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
> +		 *      >>> 'acpi_get_processor_id(acpi_id, &id)' in
> +		 *      arch/xxx/acpi.c
> +		 */
> +		pr->acpi_id = object.processor.proc_id;
> +	} else {
> +		/*
> +		 * Declared with "Device" statement; match _UID.
> +		 * Note that we don't handle string _UIDs yet.
> +		 */
> +		unsigned long long value;
> +		status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
> +						NULL, &value);
> +		if (ACPI_FAILURE(status)) {
> +			printk(KERN_ERR PREFIX
> +			    "Evaluating processor _UID [%#x]\n", status);
> +			return -ENODEV;
> +		}
> +		device_declaration = 1;
> +		pr->acpi_id = value;
> +	}
> +
> +	cpu_index = xen_pcpu_index(pr->acpi_id, 1);
> +
> +	/* Handle UP system running SMP kernel, with no LAPIC in MADT */
> +	if (!cpu0_initialized && (cpu_index == -1) &&
> +	    (num_online_cpus() == 1)) {
> +		cpu_index = 0;
> +	}
> +
> +	cpu0_initialized = 1;
> +
> +	pr->id = cpu_index;
> +
> +	/*
> +	 *  Extra Processor objects may be enumerated on MP systems with
> +	 *  less than the max # of CPUs. They should be ignored _iff
> +	 *  they are physically not present.
> +	 */
> +	if (pr->id == -1) {
> +		if (ACPI_FAILURE
> +		    (xen_acpi_processor_hotadd_init(pr, &pr->id))) {
> +			return -ENODEV;
> +		}
> +	}
> +	/*
> +	 * On some boxes several processors use the same processor bus id.
> +	 * But they are located in different scope. For example:
> +	 * \_SB.SCK0.CPU0
> +	 * \_SB.SCK1.CPU0
> +	 * Rename the processor device bus id. And the new bus id will be
> +	 * generated as the following format:
> +	 * CPU+CPU ID.
> +	 */
> +	sprintf(acpi_device_bid(device), "CPU%X", pr->id);
> +	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
> +			  pr->acpi_id));
> +
> +	if (!object.processor.pblk_address)
> +		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
> +	else if (object.processor.pblk_length != 6)
> +		printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n",
> +			    object.processor.pblk_length);
> +	else {
> +		pr->throttling.address = object.processor.pblk_address;
> +		pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
> +		pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
> +
> +		pr->pblk = object.processor.pblk_address;
> +
> +		/*
> +		 * We don't care about error returns - we just try to mark
> +		 * these reserved so that nobody else is confused into thinking
> +		 * that this region might be unused..
> +		 *
> +		 * (In particular, allocating the IO range for Cardbus)
> +		 */
> +		request_region(pr->throttling.address, 6, "ACPI CPU throttle");
> +	}
> +
> +	/*
> +	 * If ACPI describes a slot number for this CPU, we can use it
> +	 * ensure we get the right value in the "physical id" field
> +	 * of /proc/cpuinfo
> +	 */
> +	status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer);
> +	if (ACPI_SUCCESS(status))
> +		arch_fix_phys_package_id(pr->id, object.integer.value);
> +
> +	return 0;
> +}
> +
> +static int __cpuinit __xen_acpi_processor_add(struct acpi_device *device)
> +{
> +	struct acpi_processor *pr = NULL;
> +	int result = 0;
> +	struct sys_device *sysdev;
> +
> +	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
> +	if (!pr)
> +		return -ENOMEM;
> +
> +	if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
> +		kfree(pr);
> +		return -ENOMEM;
> +	}
> +
> +	pr->handle = device->handle;
> +	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
> +	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
> +	device->driver_data = pr;
> +
> +	result = xen_acpi_processor_get_info(device);
> +	if (result) {
> +		/* Processor is physically not present */
> +		return 0;
> +	}
> +
> +#ifdef CONFIG_SMP
> +	if (pr->id >= setup_max_cpus && pr->id != 0)
> +		return 0;
> +#endif
> +
> +	BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
> +
> +	/*
> +	 * Buggy BIOS check
> +	 * ACPI id of processors can be reported wrongly by the BIOS.
> +	 * Don't trust it blindly
> +	 */
> +	if (per_cpu(processor_device_array, pr->id) != NULL &&
> +	    per_cpu(processor_device_array, pr->id) != device) {
> +		printk(KERN_WARNING "BIOS reported wrong ACPI id "
> +			"for the processor\n");
> +		result = -ENODEV;
> +		goto err_free_cpumask;
> +	}
> +	per_cpu(processor_device_array, pr->id) = device;
> +
> +	per_cpu(processors, pr->id) = pr;
> +
> +	sysdev = get_cpu_sysdev(pr->id);
> +	if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
> +		result = -EFAULT;
> +		goto err_free_cpumask;
> +	}
> +
> +#ifdef CONFIG_CPU_FREQ
> +	acpi_processor_ppc_has_changed(pr, 0);
> +#endif
> +	acpi_processor_get_throttling_info(pr);
> +	acpi_processor_get_limit_info(pr);
> +
> +
> +	if (cpuidle_get_driver() == &acpi_idle_driver)
> +		acpi_processor_power_init(pr, device);
> +
> +	pr->cdev = thermal_cooling_device_register("Processor", device,
> +						&processor_cooling_ops);
> +	if (IS_ERR(pr->cdev)) {
> +		result = PTR_ERR(pr->cdev);
> +		goto err_power_exit;
> +	}
> +
> +	dev_dbg(&device->dev, "registered as cooling_device%d\n",
> +		 pr->cdev->id);
> +
> +	result = sysfs_create_link(&device->dev.kobj,
> +				   &pr->cdev->device.kobj,
> +				   "thermal_cooling");
> +	if (result) {
> +		printk(KERN_ERR PREFIX "Create sysfs link\n");
> +		goto err_thermal_unregister;
> +	}
> +	result = sysfs_create_link(&pr->cdev->device.kobj,
> +				   &device->dev.kobj,
> +				   "device");
> +	if (result) {
> +		printk(KERN_ERR PREFIX "Create sysfs link\n");
> +		goto err_remove_sysfs;
> +	}
> +
> +	return 0;
> +
> +err_remove_sysfs:
> +	sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
> +err_thermal_unregister:
> +	thermal_cooling_device_unregister(pr->cdev);
> +err_power_exit:
> +	acpi_processor_power_exit(pr, device);
> +err_free_cpumask:
> +	free_cpumask_var(pr->throttling.shared_cpu_map);
> +
> +	return result;
> +}
> +
>  static int __cpuinit xen_acpi_processor_add(struct acpi_device *device)
>  {
>  	struct acpi_processor *pr = NULL;
>  	int result = 0;
>  
> -	result = acpi_processor_add(device);
> -	if (result < 0)
> +	result = __xen_acpi_processor_add(device);
> +	if (result)
>  		return result;
>  
>  	pr = acpi_driver_data(device);
> diff --git a/include/acpi/processor.h b/include/acpi/processor.h
> index c48e2f9..3a1ee01 100644
> --- a/include/acpi/processor.h
> +++ b/include/acpi/processor.h
> @@ -225,6 +225,8 @@ struct acpi_processor_errata {
>  	} piix4;
>  };
>  
> +extern int acpi_processor_errata(struct acpi_processor *pr);
> +
>  extern int acpi_processor_preregister_performance(struct
>  						  acpi_processor_performance
>  						  __percpu *performance);
> diff --git a/include/xen/pcpu.h b/include/xen/pcpu.h
> index 7e8f9d1..3e99db9 100644
> --- a/include/xen/pcpu.h
> +++ b/include/xen/pcpu.h
> @@ -4,6 +4,8 @@
>  #include <xen/interface/platform.h>
>  #include <linux/sysdev.h>
>  
> +extern DEFINE_PER_CPU(void *, processor_device_array);
> +
>  extern int xen_pcpu_hotplug(int type, uint32_t apic_id);
>  #define XEN_PCPU_ONLINE     0x01
>  #define XEN_PCPU_OFFLINE    0x02
> -- 
> 1.6.5.6

  reply	other threads:[~2012-10-03 13:31 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-22 10:08 [PATCH 08/10] xen/acpi: add cpu hotadd support Liu, Jinsong
2012-10-03 13:31 ` Konrad Rzeszutek Wilk [this message]
  -- strict thread matches above, loose matches on Subject: below --
2011-12-23 10:30 Liu, Jinsong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20121003133156.GB31173@phenom.dumpdata.com \
    --to=konrad.wilk@oracle.com \
    --cc=jeremy.fitzhardinge@citrix.com \
    --cc=jinsong.liu@intel.com \
    --cc=xen-devel@lists.xensource.com \
    --cc=yunhong.jiang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.