From: Jiang Liu <liuj97@gmail.com>
To: Yinghai Lu <yinghai@kernel.org>,
Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>,
Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>,
Wen Congyang <wency@cn.fujitsu.com>,
Tang Chen <tangchen@cn.fujitsu.com>,
Taku Izumi <izumi.taku@jp.fujitsu.com>
Cc: Hanjun Guo <guohanjun@huawei.com>,
Yijing Wang <wangyijing@huawei.com>,
Gong Chen <gong.chen@linux.intel.com>,
Jiang Liu <jiang.liu@huawei.com>, Tony Luck <tony.luck@intel.com>,
Huang Ying <ying.huang@intel.com>,
Bob Moore <robert.moore@intel.com>, Len Brown <lenb@kernel.org>,
"Srivatsa S . Bhat" <srivatsa.bhat@linux.vnet.ibm.com>,
Bjorn Helgaas <bhelgaas@google.com>,
linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org,
linux-pci@vger.kernel.org
Subject: [RFC PATCH v3 23/28] ACPIHP/processor: enhance processor driver to support new hotplug framework
Date: Sat, 6 Oct 2012 23:27:31 +0800 [thread overview]
Message-ID: <1349537256-21670-24-git-send-email-jiang.liu@huawei.com> (raw)
In-Reply-To: <1349537256-21670-1-git-send-email-jiang.liu@huawei.com>
Refine ACPI processor driver to support new ACPI system device hotplug
framework with following changes:
1) Remove code to handle ACPI hotplug events from ACPI processor
driver, now hotplug events will be handled by the framework.
2) Provides callbacks for the framework to add CPU into or remove CPU
from running system.
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Hanjun Guo <guohanjun@huawei.com>
---
drivers/acpi/Kconfig | 11 +-
drivers/acpi/processor_driver.c | 345 +++++++++++++--------------------------
2 files changed, 121 insertions(+), 235 deletions(-)
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 4615108..490b9a4 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -206,12 +206,6 @@ config ACPI_IPMI
To compile this driver as a module, choose M here:
the module will be called as acpi_ipmi.
-config ACPI_HOTPLUG_CPU
- bool
- depends on EXPERIMENTAL && ACPI_PROCESSOR && HOTPLUG_CPU
- select ACPI_CONTAINER
- default y
-
config ACPI_PROCESSOR_AGGREGATOR
tristate "Processor Aggregator"
depends on ACPI_PROCESSOR
@@ -372,6 +366,11 @@ config ACPI_HOTPLUG_DRIVER
To compile this driver as a module, choose M here:
the module will be called acpihp_drv.
+config ACPI_HOTPLUG_CPU
+ bool
+ depends on ACPI_HOTPLUG && ACPI_PROCESSOR && HOTPLUG_CPU
+ default y
+
config ACPI_CONTAINER
tristate "Container and Module Devices (EXPERIMENTAL)"
depends on ACPI_HOTPLUG
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 110c5ac..25079ca 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -56,6 +56,7 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <acpi/processor.h>
+#include <acpi/acpi_hotplug.h>
#define PREFIX "ACPI: "
@@ -76,9 +77,10 @@ MODULE_LICENSE("GPL");
static int acpi_processor_add(struct acpi_device *device);
static int acpi_processor_remove(struct acpi_device *device, int type);
static void acpi_processor_notify(struct acpi_device *device, u32 event);
-static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr);
-static int acpi_processor_handle_eject(struct acpi_processor *pr);
static int acpi_processor_start(struct acpi_processor *pr);
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+static struct acpihp_dev_ops acpi_processor_hp_ops;
+#endif
static const struct acpi_device_id processor_device_ids[] = {
{ACPI_PROCESSOR_OBJECT_HID, 0},
@@ -98,13 +100,13 @@ static struct acpi_driver acpi_processor_driver = {
.add = acpi_processor_add,
.remove = acpi_processor_remove,
.notify = acpi_processor_notify,
- },
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+ .hp_ops = &acpi_processor_hp_ops,
+#endif
+ },
.drv.pm = &acpi_processor_pm,
};
-#define INSTALL_NOTIFY_HANDLER 1
-#define UNINSTALL_NOTIFY_HANDLER 2
-
static DEFINE_PER_CPU(void *, processor_device_array);
DEFINE_PER_CPU(struct acpi_processor *, processors);
@@ -314,15 +316,6 @@ static int acpi_processor_get_info(struct acpi_device *device)
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(acpi_processor_hotadd_init(pr)))
- 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
@@ -649,20 +642,12 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
return -EINVAL;
pr = acpi_driver_data(device);
- if (pr->id >= nr_cpu_ids)
- goto free;
-
- if (type == ACPI_BUS_REMOVAL_EJECT) {
- if (acpi_processor_handle_eject(pr))
- return -EINVAL;
- }
get_online_cpus();
- acpi_processor_stop(pr);
+ acpi_processor_stop(device, pr);
acpi_processor_unlink(device, pr);
put_online_cpus();
-free:
device->driver_data = NULL;
free_cpumask_var(pr->throttling.shared_cpu_map);
kfree(pr);
@@ -675,258 +660,160 @@ free:
* Acpi processor hotplug support *
****************************************************************************/
-static int is_processor_present(acpi_handle handle)
+static void acpi_processor_reset(struct acpi_device *device, struct acpi_processor *pr)
{
- acpi_status status;
- unsigned long long sta = 0;
-
-
- status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
-
- if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
- return 1;
-
- /*
- * _STA is mandatory for a processor that supports hot plug
- */
- if (status == AE_NOT_FOUND)
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Processor does not support hot plug\n"));
- else
- ACPI_EXCEPTION((AE_INFO, status,
- "Processor Device is not present"));
- return 0;
+ get_online_cpus();
+ acpi_processor_unlink(device, pr);
+ put_online_cpus();
+ arch_unregister_cpu(pr->id);
+ acpi_unmap_lsapic(pr->id);
+ pr->id = -1;
}
-static
-int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
+static int acpi_processor_get_dev_info(struct acpi_device *device,
+ struct acpihp_dev_info *info)
{
- acpi_handle phandle;
- struct acpi_device *pdev;
-
-
- if (acpi_get_parent(handle, &phandle)) {
- return -ENODEV;
- }
+ struct acpi_processor *pr;
- if (acpi_bus_get_device(phandle, &pdev)) {
- return -ENODEV;
- }
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+ pr = acpi_driver_data(device);
- if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
- return -ENODEV;
- }
+ info->type = ACPIHP_DEV_TYPE_CPU;
+ if (pr->id >= 0)
+ info->status |= ACPIHP_DEV_STATUS_STARTED;
return 0;
}
-static void acpi_processor_hotplug_notify(acpi_handle handle,
- u32 event, void *data)
+static int acpi_processor_pre_configure(struct acpi_device *device,
+ struct acpihp_cancel_context *ctx)
{
- struct acpi_processor *pr;
- struct acpi_device *device = NULL;
- u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
int result;
+ struct acpi_processor *pr;
- switch (event) {
- case ACPI_NOTIFY_BUS_CHECK:
- case ACPI_NOTIFY_DEVICE_CHECK:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Processor driver received %s event\n",
- (event == ACPI_NOTIFY_BUS_CHECK) ?
- "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));
-
- if (!is_processor_present(handle))
- break;
-
- if (!acpi_bus_get_device(handle, &device))
- break;
-
- result = acpi_processor_device_add(handle, &device);
- if (result) {
- printk(KERN_ERR PREFIX "Unable to add the device\n");
- break;
- }
-
- ost_code = ACPI_OST_SC_SUCCESS;
- break;
-
- case ACPI_NOTIFY_EJECT_REQUEST:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "received ACPI_NOTIFY_EJECT_REQUEST\n"));
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+ pr = acpi_driver_data(device);
- if (acpi_bus_get_device(handle, &device)) {
- printk(KERN_ERR PREFIX
- "Device don't exist, dropping EJECT\n");
- break;
- }
- pr = acpi_driver_data(device);
- if (!pr) {
- printk(KERN_ERR PREFIX
- "Driver data is NULL, dropping EJECT\n");
- break;
- }
+ /* Generate CPUID for hot-added CPUs */
+ if (pr->id == -1) {
+ result = acpi_map_lsapic(device->handle, &pr->id);
+ if (result)
+ goto out_unlock;
+ BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
+ result = arch_register_cpu(pr->id);
+ if (result)
+ goto out_unmap;
- /* REVISIT: update when eject is supported */
- ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
- break;
+ /*
+ * CPU got hot-plugged, but cpu_data is not initialized yet.
+ * Set flag to let acpi_cpu_soft_notify() initialize cpu_data
+ * by calling acpi_processor_start
+ */
+ pr->flags.need_hotplug_init = 1;
+ dev_info(&device->dev, "CPU %d got hotplugged\n", pr->id);
+ }
- default:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
+ return 0;
- /* non-hotplug event; possibly handled by other handler */
- return;
- }
+out_unmap:
+ acpi_unmap_lsapic(pr->id);
+ pr->id = -1;
+out_unlock:
+ put_online_cpus();
- /* Inform firmware that the hotplug operation has completed */
- (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
- return;
+ return result;
}
-static acpi_status is_processor_device(acpi_handle handle)
+static int acpi_processor_configure(struct acpi_device *device,
+ struct acpihp_cancel_context *ctx)
{
- struct acpi_device_info *info;
- char *hid;
- acpi_status status;
-
- status = acpi_get_object_info(handle, &info);
- if (ACPI_FAILURE(status))
- return status;
-
- if (info->type == ACPI_TYPE_PROCESSOR) {
- kfree(info);
- return AE_OK; /* found a processor object */
- }
+ int result;
+ struct acpi_processor *pr;
- if (!(info->valid & ACPI_VALID_HID)) {
- kfree(info);
- return AE_ERROR;
- }
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+ pr = acpi_driver_data(device);
- hid = info->hardware_id.string;
- if ((hid == NULL) || strcmp(hid, ACPI_PROCESSOR_DEVICE_HID)) {
- kfree(info);
- return AE_ERROR;
- }
+ get_online_cpus();
+ result = acpi_processor_link(device, pr);
+ put_online_cpus();
- kfree(info);
- return AE_OK; /* found a processor device object */
+ return result;
}
-static acpi_status
-processor_walk_namespace_cb(acpi_handle handle,
- u32 lvl, void *context, void **rv)
+static void acpi_processor_post_configure(struct acpi_device *device,
+ enum acpihp_dev_post_cmd cmd)
{
- acpi_status status;
- int *action = context;
-
- status = is_processor_device(handle);
- if (ACPI_FAILURE(status))
- return AE_OK; /* not a processor; continue to walk */
-
- switch (*action) {
- case INSTALL_NOTIFY_HANDLER:
- acpi_install_notify_handler(handle,
- ACPI_SYSTEM_NOTIFY,
- acpi_processor_hotplug_notify,
- NULL);
- break;
- case UNINSTALL_NOTIFY_HANDLER:
- acpi_remove_notify_handler(handle,
- ACPI_SYSTEM_NOTIFY,
- acpi_processor_hotplug_notify);
- break;
- default:
- break;
- }
+ struct acpi_processor *pr;
+
+ BUG_ON(!device || !acpi_driver_data(device));
+ pr = acpi_driver_data(device);
- /* found a processor; skip walking underneath */
- return AE_CTRL_DEPTH;
+ if (cmd == ACPIHP_DEV_POST_CMD_COMMIT) {
+ if (!cpu_online(pr->id) && cpu_up(pr->id))
+ dev_warn(&device->dev,
+ "fails to online CPU%d.\n", pr->id);
+ } else if (cmd == ACPIHP_DEV_POST_CMD_ROLLBACK)
+ acpi_processor_reset(device, pr);
}
-static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
+static int acpi_processor_release(struct acpi_device *device,
+ struct acpihp_cancel_context *ctx)
{
- acpi_handle handle = pr->handle;
-
- if (!is_processor_present(handle)) {
- return AE_ERROR;
- }
-
- if (acpi_map_lsapic(handle, &pr->id))
- return AE_ERROR;
+ int result = 0;
+ struct acpi_processor *pr;
- if (arch_register_cpu(pr->id)) {
- acpi_unmap_lsapic(pr->id);
- return AE_ERROR;
- }
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+ pr = acpi_driver_data(device);
- /* CPU got hot-plugged, but cpu_data is not initialized yet
- * Set flag to delay cpu_idle/throttling initialization
- * in:
- * acpi_processor_add()
- * acpi_processor_get_info()
- * and do it when the CPU gets online the first time
- * TBD: Cleanup above functions and try to do this more elegant.
- */
- printk(KERN_INFO "CPU %d got hotplugged\n", pr->id);
- pr->flags.need_hotplug_init = 1;
+ if (cpu_online(pr->id))
+ result = cpu_down(pr->id);
- return AE_OK;
+ return result;
}
-static int acpi_processor_handle_eject(struct acpi_processor *pr)
+static void acpi_processor_post_release(struct acpi_device *device,
+ enum acpihp_dev_post_cmd cmd)
{
- if (cpu_online(pr->id))
- cpu_down(pr->id);
+ struct acpi_processor *pr;
- arch_unregister_cpu(pr->id);
- acpi_unmap_lsapic(pr->id);
- return (0);
-}
-#else
-static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
-{
- return AE_ERROR;
-}
-static int acpi_processor_handle_eject(struct acpi_processor *pr)
-{
- return (-EINVAL);
-}
-#endif
+ BUG_ON(!device || !acpi_driver_data(device));
+ pr = acpi_driver_data(device);
-static
-void acpi_processor_install_hotplug_notify(void)
-{
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
- int action = INSTALL_NOTIFY_HANDLER;
- acpi_walk_namespace(ACPI_TYPE_ANY,
- ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- processor_walk_namespace_cb, NULL, &action, NULL);
-#endif
- register_hotcpu_notifier(&acpi_cpu_notifier);
+ if (cmd == ACPIHP_DEV_POST_CMD_ROLLBACK)
+ if (!cpu_online(pr->id))
+ cpu_up(pr->id);
}
-static
-void acpi_processor_uninstall_hotplug_notify(void)
+static void acpi_processor_unconfigure(struct acpi_device *device)
{
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
- int action = UNINSTALL_NOTIFY_HANDLER;
- acpi_walk_namespace(ACPI_TYPE_ANY,
- ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- processor_walk_namespace_cb, NULL, &action, NULL);
-#endif
- unregister_hotcpu_notifier(&acpi_cpu_notifier);
+ struct acpi_processor *pr;
+
+ BUG_ON(!device || !acpi_driver_data(device));
+ pr = acpi_driver_data(device);
+ acpi_processor_stop(device, pr);
+ acpi_processor_reset(device, pr);
}
+static struct acpihp_dev_ops acpi_processor_hp_ops = {
+ .get_info = &acpi_processor_get_dev_info,
+ .pre_configure = &acpi_processor_pre_configure,
+ .configure = &acpi_processor_configure,
+ .post_configure = &acpi_processor_post_configure,
+ .release = &acpi_processor_release,
+ .post_release = &acpi_processor_post_release,
+ .unconfigure = &acpi_processor_unconfigure,
+};
+#endif /* CONFIG_ACPI_HOTPLUG_CPU */
+
/*
* We keep the driver loaded even when ACPI is not running.
* This is needed for the powernow-k8 driver, that works even without
* ACPI, but needs symbols from this driver
*/
-
static int __init acpi_processor_init(void)
{
int result = 0;
@@ -940,7 +827,7 @@ static int __init acpi_processor_init(void)
if (result < 0)
return result;
- acpi_processor_install_hotplug_notify();
+ register_hotcpu_notifier(&acpi_cpu_notifier);
acpi_thermal_cpufreq_init();
@@ -960,7 +847,7 @@ static void __exit acpi_processor_exit(void)
acpi_thermal_cpufreq_exit();
- acpi_processor_uninstall_hotplug_notify();
+ unregister_hotcpu_notifier(&acpi_cpu_notifier);
acpi_bus_unregister_driver(&acpi_processor_driver);
--
1.7.9.5
next prev parent reply other threads:[~2012-10-06 15:27 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-06 15:27 [RFC PATCH v3 00/28] ACPI based system device hotplug framework Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 01/28] ACPIHP: introduce a framework for ACPI based system device hotplug Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 02/28] ACPIHP: ACPI system device hotplug slot enumerator driver Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 03/28] ACPIHP: detect ACPI hotplug slots by checking ACPI _EJ0 method Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 04/28] ACPIHP: implement a fake ACPI system device hotplug slot enumerator Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 05/28] ACPI: introduce interfaces to manage ACPI device reference count Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 06/28] ACPIHP: introduce interfaces to scan and walk ACPI devices connecting to a slot Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 07/28] ACPIHP: use klist to manage " Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 08/28] ACPIHP: add callbacks into acpi_device_ops to support new hotplug framework Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 09/28] ACPIHP: provide interfaces to associate driver specific data with slots Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 10/28] ACPIHP: implement utility functions to support system device hotplug Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 11/28] ACPIHP: implement skeleton of ACPI system device hotplug driver Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 12/28] ACPIHP: analyse dependencies among ACPI hotplug slots Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 13/28] ACPIHP: provide interface to cancel inprogress hotplug operations Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 14/28] ACPIHP: configure/unconfigure system devices connecting to a hotplug slot Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 15/28] ACPIHP: implement the state machine for ACPI hotplug slots Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 16/28] ACPIHP: implement sysfs interfaces for ACPI system device hotplug Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 17/28] ACPIHP: block ACPI device driver unloading when executing hotplug operations Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 18/28] ACPIHP/container: change ACPI container driver to support new hotplug framework Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 19/28] ACPIHP/container: move container.c into drivers/acpi/hotplug Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 20/28] ACPI/processor: remove dead code from processor_driver.c Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 21/28] ACPIHP/processor: reorganize ACPI processor driver for new hotplug framework Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 22/28] ACPIHP/processor: protect accesses to device->driver_data Jiang Liu
2012-10-06 15:27 ` Jiang Liu [this message]
2012-10-06 15:27 ` [RFC PATCH v3 24/28] CPU: introduce busy flag to temporarily disable CPU online sysfs interface Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 25/28] ACPIHP/processor: reject online/offline requests when doing processor hotplug Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 26/28] ACPI/processor: save parsed APIC ID in processor driver data structure Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 27/28] x86: simplify _acpi_map_lsapic() Jiang Liu
2012-10-06 15:27 ` [RFC PATCH v3 28/28] ACPI/processor: serialize call to acpi_map/unmap_lsapic Jiang Liu
2012-10-07 21:47 ` [RFC PATCH v3 00/28] ACPI based system device hotplug framework Rafael J. Wysocki
2012-10-08 15:45 ` Jiang Liu
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=1349537256-21670-24-git-send-email-jiang.liu@huawei.com \
--to=liuj97@gmail.com \
--cc=bhelgaas@google.com \
--cc=gong.chen@linux.intel.com \
--cc=guohanjun@huawei.com \
--cc=isimatu.yasuaki@jp.fujitsu.com \
--cc=izumi.taku@jp.fujitsu.com \
--cc=jiang.liu@huawei.com \
--cc=kaneshige.kenji@jp.fujitsu.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=robert.moore@intel.com \
--cc=srivatsa.bhat@linux.vnet.ibm.com \
--cc=tangchen@cn.fujitsu.com \
--cc=tony.luck@intel.com \
--cc=wangyijing@huawei.com \
--cc=wency@cn.fujitsu.com \
--cc=ying.huang@intel.com \
--cc=yinghai@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).