linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 00/11] Hot-plug and Online/Offline framework
@ 2012-12-12 23:17 Toshi Kani
  2012-12-12 23:17 ` [RFC PATCH 01/11] Add hotplug.h for hotplug framework Toshi Kani
                   ` (11 more replies)
  0 siblings, 12 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-12 23:17 UTC (permalink / raw)
  To: rjw, lenb, gregkh, akpm
  Cc: linux-acpi, linux-kernel, linux-mm, bhelgaas, isimatu.yasuaki,
	jiang.liu, wency, guohanjun, yinghai, srivatsa.bhat, Toshi Kani

This patchset is an initial prototype of proposed hot-plug framework
for design review.  The hot-plug framework is designed to provide 
the common framework for hot-plugging and online/offline operations
of system devices, such as CPU, Memory and Node.  While this patchset
only supports ACPI-based hot-plug operations, the framework itself is
designed to be platform-neural and can support other FW architectures
as necessary.

The patchset has not been fully tested yet, esp. for memory hot-plug.
Any help for testing will be very appreciated since my test setup
is limited.

The patchset is based on the linux-next branch of linux-pm.git tree.

Overview of the Framework
=========================
High-level overview of the framework is shown below.  Hot-plug and
online/offline operations are supported by two types of modules - 
FW-dependent modules and resource management modules.  The FW-dependent
modules are FW architecture-specific, such as ACPI, and enumerate HW
devices for hot-plug operations.  The resource management modules,
such as CPU and memory management, generally have platform-neutral
entry points and online or offline the enumerated HW resources for
both online/offline and hot-plug operations.

              -----------> sysfs online
              <----------- sysfs offline
  -----------------------> hot-add
  <----------------------- hot-delete, sysfs eject

  FW-dep      Resource Mgmt
  (HW enum)   (online/offline)
  +-----------+-----------+
  |   ACPI    |   CPU     |
  |-----------|   Memory  |
  | Other FW  |   etc.    |
  +-----------+-----------+

The framework calls the FW-dependent and resource management modules
in pre-defined order, which is analogous to the boot-up sequence,
during the operations.  The ordering of the modules is symmetric
between online/hot-add operations and offline/hot-remove operations.
The modules may not call other modules directly to exceed their role.
Therefore, the role of the modules during the operations remains
consistent with their role at the boot-up sequence.  For instance,
the ACPI module may not initiate online or offline of enumerated
devices.

Hot-plug Operation
==================

Serialized Startup
------------------
The framework provides an interface (hp_submit_req) to request a 
hot-plug or online/offline operation.  All requests are queued to
and run on a single work queue.  The framework assures that there is
only a single hot-plug or online/offline operation running at a time.
A single request may however target to multiple devices. 

Phased Execution
----------------
The framework proceeds hot-plug and online/offline operations in
the following three phases.  The modules can register their handlers
to each phase.  The framework also initiates a roll-back operation
if any hander failed in the validate or execute phase.

1) Validate Phase - Handlers validate if they support a given request
without making any changes to target device(s).  Any known restrictions
and/or prerequisite conditions are checked in this phase, so that an
unsupported request can be failed before making any changes.  For
instance, the memory module may check if a hot-remove request is
targeted to movable ranges.

2) Execute Phase - Handlers make requested changes within the scope
that roll-back is possible in case of a failure.  Execute handlers
must implement their roll-back procedures.

3) Commit Phase - Handlers make the final changes that cannot be
rolled-back.  For instance, the ACPI module invokes _EJ0 for a 
hot-remove operation.

Resource Management Modules
===========================

CPU Handlers
------------
CPU handlers are provided by the CPU driver in drivers/base/cpu.c,
and perform CPU online/offline procedures when CPU device(s) is added
or deleted during an operation.

Memory Handlers
---------------
Memory handlers are provided by the memory module in mm/memory_hotplug.c,
and perform Memory online/offline procedure when memory device(s) is
added or deleted during an operation.

FW-dependent Modules
====================

ACPI Bus Handlers
-----------------
ACPI bus handlers are provided by the ACPI core in drivers/acpi/bus.c,
and construct/destruct acpi_device object(s) during a hot-plug operation.

ACPI Resource Handlers
----------------------
ACPI resource handlers are provided by the ACPI core in
drivers/acpi/hp_resource.c, and set device resource information to a
request during a hot-plug operation.  This device resource information
is then consumed by the resource management modules for their online/
offline procedure.

ACPI Drivers
------------
ACPI drivers are called from the ACPI core during a hot-plug operation
through the following interfaces.  ACPI drivers are not called from the
framework directly, and remain internal to the ACPI core.  ACPI drivers
may not initiate online/offline of a device.

.add - Construct device-specific information to a given acpi_device.
Called at boot, hot-add and sysfs bind.

.remove - Destruct device-specific information to a given acpi_device.
Called at hot-remove and sysfs unbind.

.resource - Set device-specific resource information to a given hot-pug
request.  Called at hot-add and hot-remove.

---
Toshi Kani (11):
 Add hotplug.h for hotplug framework
 drivers/base: Add hotplug framework code
 cpu: Add cpu hotplug handlers
 mm: Add memory hotplug handlers
 ACPI: Add ACPI bus hotplug handlers
 ACPI: Add ACPI resource hotplug handler
 ACPI: Update processor driver for hotplug framework
 ACPI: Update memory driver for hotplug framework
 ACPI: Update container driver for hotplug framework
 cpu: Update sysfs cpu/online for hotplug framework
 ACPI: Update sysfs eject for hotplug framework

---
 drivers/acpi/Makefile           |   1 +
 drivers/acpi/acpi_memhotplug.c  | 290 +++++++++++++---------------------------
 drivers/acpi/bus.c              | 134 +++++++++++++++++++
 drivers/acpi/container.c        |  95 +++++--------
 drivers/acpi/hp_resource.c      |  86 ++++++++++++
 drivers/acpi/internal.h         |   1 +
 drivers/acpi/processor_driver.c | 150 ++++++++++-----------
 drivers/acpi/scan.c             | 122 +++--------------
 drivers/base/Makefile           |   1 +
 drivers/base/cpu.c              | 135 +++++++++++++++++--
 drivers/base/hotplug.c          | 283 +++++++++++++++++++++++++++++++++++++++
 include/acpi/acpi_bus.h         |   8 +-
 include/linux/hotplug.h         | 187 ++++++++++++++++++++++++++
 mm/memory_hotplug.c             |  97 ++++++++++++++
 14 files changed, 1137 insertions(+), 453 deletions(-)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFC PATCH 01/11] Add hotplug.h for hotplug framework
  2012-12-12 23:17 [RFC PATCH 00/11] Hot-plug and Online/Offline framework Toshi Kani
@ 2012-12-12 23:17 ` Toshi Kani
  2012-12-12 23:53   ` Greg KH
  2012-12-12 23:17 ` [RFC PATCH 02/11] drivers/base: Add hotplug framework code Toshi Kani
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 30+ messages in thread
From: Toshi Kani @ 2012-12-12 23:17 UTC (permalink / raw)
  To: rjw, lenb, gregkh, akpm
  Cc: linux-acpi, linux-kernel, linux-mm, bhelgaas, isimatu.yasuaki,
	jiang.liu, wency, guohanjun, yinghai, srivatsa.bhat, Toshi Kani

Added include/linux/hotplug.h, which defines the hotplug framework
interfaces used by the framework itself and handlers.

The order values define the calling sequence of handlers.  For add
execute, the ordering is ACPI->MEM->CPU.  Memory is onlined before
CPU so that threads on new CPUs can start using their local memory.
The ordering of the delete execute is symmetric to the add execute.

struct hp_request defines a hot-plug request information.  The
device resource information is managed with a list so that a single
request may target to multiple devices.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
---
 include/linux/hotplug.h | 187 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 187 insertions(+)
 create mode 100644 include/linux/hotplug.h

diff --git a/include/linux/hotplug.h b/include/linux/hotplug.h
new file mode 100644
index 0000000..b64f91b
--- /dev/null
+++ b/include/linux/hotplug.h
@@ -0,0 +1,187 @@
+/*
+ * hotplug.h - Hot-plug framework for system devices
+ *
+ * Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
+ *	Toshi Kani <toshi.kani@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _LINUX_HOTPLUG_H
+#define _LINUX_HOTPLUG_H
+
+#include <linux/list.h>
+#include <linux/device.h>
+
+/*
+ * A hot-plug operation proceeds in the following order.
+ *   Validate phase -> Execute phase -> Commit phase
+ *
+ * The order values below define the calling sequence of each phase
+ * in ascending order.
+ */
+
+/* All order values must be smaller than this value */
+#define HP_ORDER_MAX				0xffffff
+
+/* Add Validate order values */
+#define HP_ACPI_BUS_ADD_VALIDATE_ORDER		0	/* must be first */
+
+/* Add Execute order values */
+#define HP_ACPI_BUS_ADD_EXECUTE_ORDER		10
+#define HP_ACPI_RES_ADD_EXECUTE_ORDER		20
+#define HP_MEM_ADD_EXECUTE_ORDER		30
+#define HP_CPU_ADD_EXECUTE_ORDER		40
+
+/* Add Commit order values */
+#define HP_ACPI_BUS_ADD_COMMIT_ORDER		10
+
+/* Delete Validate order values */
+#define HP_ACPI_BUS_DEL_VALIDATE_ORDER		0	/* must be first */
+#define HP_ACPI_RES_DEL_VALIDATE_ORDER		10
+#define HP_CPU_DEL_VALIDATE_ORDER		20
+#define HP_MEM_DEL_VALIDATE_ORDER		30
+
+/* Delete Execute order values */
+#define HP_CPU_DEL_EXECUTE_ORDER		10
+#define HP_MEM_DEL_EXECUTE_ORDER		20
+#define HP_ACPI_BUS_DEL_EXECUTE_ORDER		30
+
+/* Delete Commit order values */
+#define HP_ACPI_BUS_DEL_COMMIT_ORDER		10
+
+/*
+ * Hot-plug request types
+ */
+#define HP_REQ_ADD		0x000000
+#define HP_REQ_DELETE		0x000001
+#define HP_REQ_MASK		0x0000ff
+
+/*
+ * Hot-plug phase types
+ */
+#define HP_PH_VALIDATE		0x000000
+#define HP_PH_EXECUTE		0x000100
+#define HP_PH_COMMIT		0x000200
+#define HP_PH_MASK		0x00ff00
+
+/*
+ * Hot-plug operation types
+ */
+#define HP_OP_HOTPLUG		0x000000
+#define HP_OP_ONLINE		0x010000
+#define HP_OP_MASK		0xff0000
+
+/*
+ * Hot-plug phases
+ */
+enum hp_phase {
+	HP_ADD_VALIDATE	= (HP_REQ_ADD|HP_PH_VALIDATE),
+	HP_ADD_EXECUTE	= (HP_REQ_ADD|HP_PH_EXECUTE),
+	HP_ADD_COMMIT	= (HP_REQ_ADD|HP_PH_COMMIT),
+	HP_DEL_VALIDATE	= (HP_REQ_DELETE|HP_PH_VALIDATE),
+	HP_DEL_EXECUTE	= (HP_REQ_DELETE|HP_PH_EXECUTE),
+	HP_DEL_COMMIT	= (HP_REQ_DELETE|HP_PH_COMMIT)
+};
+
+/*
+ * Hot-plug operations
+ */
+enum hp_operation {
+	HP_HOTPLUG_ADD = (HP_OP_HOTPLUG|HP_REQ_ADD),
+	HP_HOTPLUG_DEL = (HP_OP_HOTPLUG|HP_REQ_DELETE),
+	HP_ONLINE_ADD  = (HP_OP_ONLINE|HP_REQ_ADD),
+	HP_ONLINE_DEL  = (HP_OP_ONLINE|HP_REQ_DELETE)
+};
+
+/*
+ * Hot-plug device classes
+ */
+enum hp_class {
+	HP_CLS_INVALID		= 0,
+	HP_CLS_CPU		= 1,
+	HP_CLS_MEMORY		= 2,
+	HP_CLS_HOSTBRIDGE	= 3,
+	HP_CLS_CONTAINER	= 4,
+};
+
+/*
+ * Hot-plug device information
+ */
+union hp_dev_info {
+	struct hp_cpu {
+		u32		cpu_id;
+	} cpu;
+
+	struct hp_memory {
+		int		node;
+		u64		start_addr;
+		u64		length;
+	} mem;
+
+	struct hp_hostbridge {
+	} hb;
+
+	struct hp_container {
+	} con;
+};
+
+struct hp_device {
+	struct list_head	list;
+	struct device		*device;
+	enum hp_class		class;
+	union hp_dev_info	data;
+};
+
+/*
+ * Hot-plug request
+ */
+struct hp_request {
+	/* common info */
+	enum hp_operation	operation;	/* operation */
+
+	/* hot-plug event info: only valid for hot-plug operations */
+	void			*handle;	/* FW handle */
+	u32			event;		/* FW event */
+
+	/* device resource info */
+	struct list_head	dev_list;	/* hp_device list */
+};
+
+/*
+ * Inline Utility Functions
+ */
+static inline bool hp_is_hotplug_op(enum hp_operation operation)
+{
+	return (operation & HP_OP_MASK) == HP_OP_HOTPLUG;
+}
+
+static inline bool hp_is_online_op(enum hp_operation operation)
+{
+	return (operation & HP_OP_MASK) == HP_OP_ONLINE;
+}
+
+static inline bool hp_is_add_op(enum hp_operation operation)
+{
+	return (operation & HP_REQ_MASK) == HP_REQ_ADD;
+}
+
+static inline bool hp_is_add_phase(enum hp_phase phase)
+{
+	return (phase & HP_REQ_MASK) == HP_REQ_ADD;
+}
+
+/*
+ * Externs
+ */
+typedef int (*hp_func)(struct hp_request *req, int rollback);
+extern int hp_register_handler(enum hp_phase phase, hp_func func, u32 order);
+extern int hp_unregister_handler(enum hp_phase phase, hp_func func);
+extern int hp_submit_req(struct hp_request *req);
+extern struct hp_request *hp_alloc_request(enum hp_operation operation);
+extern void hp_add_dev_info(struct hp_request *hp_req,
+		struct hp_device *hp_dev);
+
+#endif	/* _LINUX_HOTPLUG_H */
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH 02/11] drivers/base: Add hotplug framework code
  2012-12-12 23:17 [RFC PATCH 00/11] Hot-plug and Online/Offline framework Toshi Kani
  2012-12-12 23:17 ` [RFC PATCH 01/11] Add hotplug.h for hotplug framework Toshi Kani
@ 2012-12-12 23:17 ` Toshi Kani
  2012-12-12 23:54   ` Greg KH
  2012-12-12 23:55   ` Greg KH
  2012-12-12 23:17 ` [RFC PATCH 03/11] cpu: Add cpu hotplug handlers Toshi Kani
                   ` (9 subsequent siblings)
  11 siblings, 2 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-12 23:17 UTC (permalink / raw)
  To: rjw, lenb, gregkh, akpm
  Cc: linux-acpi, linux-kernel, linux-mm, bhelgaas, isimatu.yasuaki,
	jiang.liu, wency, guohanjun, yinghai, srivatsa.bhat, Toshi Kani

Added hotplug.c, which is the hotplug framework code.

hp_register_handler() allows modules to register their hotplug handlers
to the framework.  hp_submit_req() provides the interface to submit
a hotplug or online/offline request.  The request is then put into
hp_workqueue.  hp_start_req() calls all registered handlers in ascending
order for each phase.  If any handler failed in validate or execute phase,
hp_start_req() initiates the rollback procedure.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
---
 drivers/base/Makefile  |   1 +
 drivers/base/hotplug.c | 283 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 284 insertions(+)
 create mode 100644 drivers/base/hotplug.c

diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 5aa2d70..af2e013 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -21,6 +21,7 @@ endif
 obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
 obj-$(CONFIG_REGMAP)	+= regmap/
 obj-$(CONFIG_SOC_BUS) += soc.o
+obj-$(CONFIG_HOTPLUG)	+= hotplug.o
 
 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
 
diff --git a/drivers/base/hotplug.c b/drivers/base/hotplug.c
new file mode 100644
index 0000000..9e85e25
--- /dev/null
+++ b/drivers/base/hotplug.c
@@ -0,0 +1,283 @@
+/*
+ * hotplug.c - Hot-plug framework for system devices
+ *
+ * Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
+ *	Toshi Kani <toshi.kani@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/workqueue.h>
+#include <linux/hotplug.h>
+#include <linux/kallsyms.h>
+
+/*
+ * Hot-plug handler list
+ */
+struct hp_handler {
+	struct list_head	hp_list;
+	int			hp_order;
+	hp_func			hp_func;
+};
+
+LIST_HEAD(hp_add_list_head);
+LIST_HEAD(hp_del_list_head);
+
+#define HP_VALIDATE_ORDER_BASE		(HP_ORDER_MAX+1)
+#define HP_EXECUTE_ORDER_BASE		((HP_ORDER_MAX+1) << 1)
+#define HP_COMMIT_ORDER_BASE		((HP_ORDER_MAX+1) << 2)
+
+/*
+ * Hot-plug request work queue
+ */
+struct hp_work {
+	struct hp_request	*request;
+	struct work_struct	work;
+};
+
+static struct workqueue_struct *hp_workqueue;
+
+/* trace messages */
+static int hp_trace = 1;
+static char hp_ksym_buf[KSYM_NAME_LEN];
+
+static char *hp_operation_string(enum hp_operation operation)
+{
+	switch (operation) {
+	case HP_HOTPLUG_ADD:
+		return "Hot-Add";
+	case HP_HOTPLUG_DEL:
+		return "Hot-Delete";
+	case HP_ONLINE_ADD:
+		return "Online";
+	case HP_ONLINE_DEL:
+		return "Offline";
+	}
+
+	return "n/a";
+}
+
+static u32 hp_get_order_base(enum hp_phase phase)
+{
+	switch (phase) {
+	case HP_ADD_VALIDATE:
+	case HP_DEL_VALIDATE:
+		return HP_VALIDATE_ORDER_BASE;
+	case HP_ADD_EXECUTE:
+	case HP_DEL_EXECUTE:
+		return HP_EXECUTE_ORDER_BASE;
+	case HP_ADD_COMMIT:
+	case HP_DEL_COMMIT:
+		return HP_COMMIT_ORDER_BASE;
+	}
+
+	return 0;
+}
+
+/**
+ * hp_register_handler - register a hot-plug handler to the framework
+ * @phase: hot-plug phase
+ * @func: Hot-plug function
+ * @order: Pre-defined order value
+ */
+int hp_register_handler(enum hp_phase phase, hp_func func, u32 order)
+{
+	struct list_head *head;
+	struct hp_handler *hdr, *cur;
+	u32 order_base;
+	int insert = 0;
+
+	if (!func || order > HP_ORDER_MAX)
+		return -EINVAL;
+
+	if (hp_is_add_phase(phase))
+		head = &hp_add_list_head;
+	else
+		head = &hp_del_list_head;
+
+	order_base = hp_get_order_base(phase);
+
+	hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
+	if (!hdr)
+		return -ENOMEM;
+
+	hdr->hp_order = order + order_base;
+	hdr->hp_func = func;
+
+	/*
+	 * Add this handler to the list in ascending order
+	 */
+	if (list_empty(head)) {
+		list_add(&hdr->hp_list, head);
+	} else {
+		list_for_each_entry(cur, head, hp_list)
+			if (cur->hp_order > hdr->hp_order) {
+				insert = 1;
+				break;
+			}
+
+		if (insert)
+			__list_add(&hdr->hp_list,
+				cur->hp_list.prev, &cur->hp_list);
+		else
+			list_add_tail(&hdr->hp_list, head);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(hp_register_handler);
+
+/**
+ * hp_unregister_handler - unregister a hot-plug handler from the framework
+ * @phase: hot-plug phase
+ * @func: Hot-plug function
+ */
+int hp_unregister_handler(enum hp_phase phase, hp_func func)
+{
+	/* REVISIT: implement later */
+	return 0;
+}
+EXPORT_SYMBOL(hp_unregister_handler);
+
+static void hp_start_req(struct work_struct *work)
+{
+	struct hp_work *hp_work = container_of(work, struct hp_work, work);
+	struct hp_request *req = hp_work->request;
+	struct hp_handler *hdr;
+	struct hp_device *hp_dev, *tmp;
+	struct list_head *head;
+	int rollback = 0;
+	int ret;
+
+	if (hp_is_add_op(req->operation))
+		head = &hp_add_list_head;
+	else
+		head = &hp_del_list_head;
+
+	if (hp_trace)
+		pr_info("Starting %s Operation\n",
+				hp_operation_string(req->operation));
+
+	/*
+	 * Call hot-plug handlers in the list
+	 */
+	list_for_each_entry(hdr, head, hp_list) {
+		if (hp_trace)
+			pr_info("-> %s\n",
+				kallsyms_lookup((unsigned long)hdr->hp_func,
+					NULL, NULL, NULL, hp_ksym_buf));
+
+		ret = hdr->hp_func(req, 0);
+		if (ret) {
+			if (hdr->hp_order < HP_COMMIT_ORDER_BASE) {
+				if (hp_trace)
+					pr_info("Initiating Rollback\n");
+				rollback = 1;
+				break;
+			} else {
+				pr_err("Commit handler failed: continuing\n");
+				continue;
+			}
+		}
+	}
+
+	/*
+	 * If rollback is requested, call hot-plug handlers in the reversed
+	 * order from the failed handler.  The failed handler is not called
+	 * again.
+	 */
+	if (rollback) {
+		list_for_each_entry_continue_reverse(hdr, head, hp_list) {
+			if (hp_trace)
+				pr_info("RB-> %s\n",
+					kallsyms_lookup(
+					   (unsigned long)hdr->hp_func,
+					   NULL, NULL, NULL, hp_ksym_buf));
+
+			ret = hdr->hp_func(req, 1);
+			if (ret)
+				pr_err("Rollback handler failed: continuing\n");
+		}
+	}
+
+	/* free up the hot-plug request information */
+	list_for_each_entry_safe(hp_dev, tmp, &req->dev_list, list) {
+		list_del(&hp_dev->list);
+		kfree(hp_dev);
+	}
+	kfree(req);
+	kfree(hp_work);
+}
+
+/**
+ * hp_submit_req - submit a hot-plug request
+ * @req: Hot-plug request pointer
+ */
+int hp_submit_req(struct hp_request *req)
+{
+	struct hp_work *hp_work;
+
+	hp_work = kzalloc(sizeof(*hp_work), GFP_KERNEL);
+	if (!hp_work)
+		return -ENOMEM;
+
+	hp_work->request = req;
+	INIT_WORK(&hp_work->work, hp_start_req);
+
+	if (!queue_work(hp_workqueue, &hp_work->work)) {
+		kfree(hp_work);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(hp_submit_req);
+
+/**
+ * hp_alloc_request - allocate a hot-plug request
+ * @operation: Hot-plug operation
+ */
+struct hp_request *hp_alloc_request(enum hp_operation operation)
+{
+	struct hp_request *hp_req;
+
+	hp_req = kzalloc(sizeof(*hp_req), GFP_KERNEL);
+	if (!hp_req)
+		return NULL;
+
+	hp_req->operation = operation;
+	INIT_LIST_HEAD(&hp_req->dev_list);
+
+	return hp_req;
+}
+EXPORT_SYMBOL(hp_alloc_request);
+
+/**
+ * hp_add_dev_info - add hp_device to the hotplug request
+ * @hp_req: hot-plug request pointer
+ * @hp_dev: hot-plug device info pointer
+ */
+void hp_add_dev_info(struct hp_request *hp_req, struct hp_device *hp_dev)
+{
+	list_add_tail(&hp_dev->list, &hp_req->dev_list);
+}
+EXPORT_SYMBOL(hp_add_dev_info);
+
+static int __init hp_init(void)
+{
+	/*
+	 * Allocate hp_workqueue with max_active set to 1.  This serializes
+	 * hot-plug and online/offline operations on the workqueue.
+	 */
+	hp_workqueue = alloc_workqueue("hotplug", 0, 1);
+
+	return 0;
+}
+device_initcall(hp_init);
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH 03/11] cpu: Add cpu hotplug handlers
  2012-12-12 23:17 [RFC PATCH 00/11] Hot-plug and Online/Offline framework Toshi Kani
  2012-12-12 23:17 ` [RFC PATCH 01/11] Add hotplug.h for hotplug framework Toshi Kani
  2012-12-12 23:17 ` [RFC PATCH 02/11] drivers/base: Add hotplug framework code Toshi Kani
@ 2012-12-12 23:17 ` Toshi Kani
  2012-12-12 23:17 ` [RFC PATCH 04/11] mm: Add memory " Toshi Kani
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-12 23:17 UTC (permalink / raw)
  To: rjw, lenb, gregkh, akpm
  Cc: linux-acpi, linux-kernel, linux-mm, bhelgaas, isimatu.yasuaki,
	jiang.liu, wency, guohanjun, yinghai, srivatsa.bhat, Toshi Kani

Added cpu hotplug handlers.  cpu_add_execute() onlines requested
cpus for hot-add and online operations, and cpu_del_execute() 
offlines them for hot-delete and offline operations.  They are
also used for rollback as well.

cpu_del_validate() fails a request if cpu0 is requested to delete.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
---
 drivers/base/cpu.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 6345294..3870231 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -13,6 +13,8 @@
 #include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/percpu.h>
+#include <linux/list.h>
+#include <linux/hotplug.h>
 
 #include "base.h"
 
@@ -324,10 +326,103 @@ static void __init cpu_dev_register_generic(void)
 #endif
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static int cpu_del_execute(struct hp_request *req, int rollback);
+
+static int cpu_add_execute(struct hp_request *req, int rollback)
+{
+	struct hp_device *hp_dev;
+	u32 cpu;
+	int ret;
+
+	if (rollback)
+		return cpu_del_execute(req, 0);
+
+	list_for_each_entry(hp_dev, &req->dev_list, list) {
+		if (hp_dev->class != HP_CLS_CPU)
+			continue;
+
+		cpu = hp_dev->data.cpu.cpu_id;
+
+		if (cpu_online(cpu))
+			continue;
+
+		ret = cpu_up(cpu);
+		/* REVISIT: need a way to set a cpu dev for hot-plug op */
+		if (!ret && hp_is_online_op(req->operation))
+			kobject_uevent(&hp_dev->device->kobj, KOBJ_ONLINE);
+	}
+
+	return 0;
+}
+
+static int cpu_del_validate(struct hp_request *req, int rollback)
+{
+	struct hp_device *hp_dev;
+
+	if (rollback)
+		return 0;
+
+	list_for_each_entry(hp_dev, &req->dev_list, list) {
+		if (hp_dev->class != HP_CLS_CPU)
+			continue;
+
+		/*
+		 * cpu 0 cannot be offlined.  This check can be removed when
+		 * cpu 0 offline is supported.
+		 */
+		if (hp_dev->data.cpu.cpu_id == 0)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int cpu_del_execute(struct hp_request *req, int rollback)
+{
+	struct hp_device *hp_dev;
+	u32 cpu;
+	int ret;
+
+	if (rollback)
+		return cpu_add_execute(req, 0);
+
+	list_for_each_entry(hp_dev, &req->dev_list, list) {
+		if (hp_dev->class != HP_CLS_CPU)
+			continue;
+
+		cpu = hp_dev->data.cpu.cpu_id;
+
+		if (!cpu_online(cpu))
+			continue;
+
+		ret = cpu_down(cpu);
+		/* REVISIT: need a way to set a cpu dev for hot-plug op */
+		if (!ret && hp_is_online_op(req->operation))
+			kobject_uevent(&hp_dev->device->kobj, KOBJ_OFFLINE);
+	}
+
+	return 0;
+}
+
+static void __init cpu_hp_init(void)
+{
+	hp_register_handler(HP_ADD_EXECUTE, cpu_add_execute,
+				HP_CPU_ADD_EXECUTE_ORDER);
+	hp_register_handler(HP_DEL_VALIDATE, cpu_del_validate,
+				HP_CPU_DEL_VALIDATE_ORDER);
+	hp_register_handler(HP_DEL_EXECUTE, cpu_del_execute,
+				HP_CPU_DEL_EXECUTE_ORDER);
+}
+#endif	/* CONFIG_HOTPLUG_CPU */
+
 void __init cpu_dev_init(void)
 {
 	if (subsys_system_register(&cpu_subsys, cpu_root_attr_groups))
 		panic("Failed to register CPU subsystem");
 
 	cpu_dev_register_generic();
+#ifdef CONFIG_HOTPLUG_CPU
+	cpu_hp_init();
+#endif
 }
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH 04/11] mm: Add memory hotplug handlers
  2012-12-12 23:17 [RFC PATCH 00/11] Hot-plug and Online/Offline framework Toshi Kani
                   ` (2 preceding siblings ...)
  2012-12-12 23:17 ` [RFC PATCH 03/11] cpu: Add cpu hotplug handlers Toshi Kani
@ 2012-12-12 23:17 ` Toshi Kani
  2012-12-12 23:17 ` [RFC PATCH 05/11] ACPI: Add ACPI bus " Toshi Kani
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-12 23:17 UTC (permalink / raw)
  To: rjw, lenb, gregkh, akpm
  Cc: linux-acpi, linux-kernel, linux-mm, bhelgaas, isimatu.yasuaki,
	jiang.liu, wency, guohanjun, yinghai, srivatsa.bhat, Toshi Kani

Added memory hotplug handlers.  mm_add_execute() onlines requested
memory ranges for hot-add and online operations, and mm_del_execute()
offlines them for hot-delete and offline operations.  They are also
used for rollback as well.

mm_del_validate() fails a request if a requested memory range is
non-movable for delete.  This check can be removed if we should
attempt to delete such range anyway (but can cause a rollback).

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
---
 mm/memory_hotplug.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index e4eeaca..107a39d 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -29,6 +29,7 @@
 #include <linux/suspend.h>
 #include <linux/mm_inline.h>
 #include <linux/firmware-map.h>
+#include <linux/hotplug.h>
 
 #include <asm/tlbflush.h>
 
@@ -45,6 +46,9 @@ static void generic_online_page(struct page *page);
 
 static online_page_callback_t online_page_callback = generic_online_page;
 
+static int mm_add_execute(struct hp_request *req, int rollback);
+static int mm_del_execute(struct hp_request *req, int rollback);
+
 DEFINE_MUTEX(mem_hotplug_mutex);
 
 void lock_memory_hotplug(void)
@@ -1055,3 +1059,96 @@ int remove_memory(u64 start, u64 size)
 }
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 EXPORT_SYMBOL_GPL(remove_memory);
+
+static int mm_add_execute(struct hp_request *req, int rollback)
+{
+	struct hp_device *hp_dev;
+	struct hp_memory *hp_mem;
+	int ret;
+
+	if (rollback)
+		return mm_del_execute(req, 0);
+
+	list_for_each_entry(hp_dev, &req->dev_list, list) {
+		if (hp_dev->class != HP_CLS_MEMORY)
+			continue;
+
+		hp_mem = &hp_dev->data.mem;
+
+		ret = add_memory(hp_mem->node,
+				hp_mem->start_addr, hp_mem->length);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int mm_del_validate(struct hp_request *req, int rollback)
+{
+	struct hp_device *hp_dev;
+	struct hp_memory *hp_mem;
+	unsigned long start_pfn, nr_pages;
+
+	if (rollback)
+		return 0;
+
+	list_for_each_entry(hp_dev, &req->dev_list, list) {
+		if (hp_dev->class != HP_CLS_MEMORY)
+			continue;
+
+		hp_mem = &hp_dev->data.mem;
+		start_pfn = hp_mem->start_addr >> PAGE_SHIFT;
+		nr_pages = PAGE_ALIGN(hp_mem->length) >> PAGE_SHIFT;
+
+		/*
+		 * Check if this memory range is removable.  This check can
+		 * be removed if we should attempt to delete a non-movable
+		 * range.
+		 */
+		if (is_mem_section_removable(start_pfn, nr_pages)) {
+			pr_info("Memory [%#010llx-%#010llx] not removable\n",
+				hp_mem->start_addr,
+				hp_mem->start_addr + hp_mem->length-1);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int mm_del_execute(struct hp_request *req, int rollback)
+{
+	struct hp_device *hp_dev;
+	struct hp_memory *hp_mem;
+	int ret;
+
+	if (rollback)
+		return mm_add_execute(req, 0);
+
+	list_for_each_entry(hp_dev, &req->dev_list, list) {
+		if (hp_dev->class != HP_CLS_MEMORY)
+			continue;
+
+		hp_mem = &hp_dev->data.mem;
+
+		ret = remove_memory(hp_mem->start_addr, hp_mem->length);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int __init mm_hp_init(void)
+{
+	hp_register_handler(HP_ADD_EXECUTE, mm_add_execute,
+				HP_MEM_ADD_EXECUTE_ORDER);
+	hp_register_handler(HP_DEL_VALIDATE, mm_del_validate,
+				HP_MEM_DEL_VALIDATE_ORDER);
+	hp_register_handler(HP_DEL_EXECUTE, mm_del_execute,
+				HP_MEM_DEL_EXECUTE_ORDER);
+
+	return 0;
+}
+module_init(mm_hp_init);
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH 05/11] ACPI: Add ACPI bus hotplug handlers
  2012-12-12 23:17 [RFC PATCH 00/11] Hot-plug and Online/Offline framework Toshi Kani
                   ` (3 preceding siblings ...)
  2012-12-12 23:17 ` [RFC PATCH 04/11] mm: Add memory " Toshi Kani
@ 2012-12-12 23:17 ` Toshi Kani
  2012-12-12 23:17 ` [RFC PATCH 06/11] ACPI: Add ACPI resource hotplug handler Toshi Kani
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-12 23:17 UTC (permalink / raw)
  To: rjw, lenb, gregkh, akpm
  Cc: linux-acpi, linux-kernel, linux-mm, bhelgaas, isimatu.yasuaki,
	jiang.liu, wency, guohanjun, yinghai, srivatsa.bhat, Toshi Kani

Added ACPI bus hotplug handlers.  acpi_add_execute() calls
acpi_bus_add() to construct new acpi_device objects for hot-add
operation, and acpi_del_execute() calls acpi_bus_trim() to destruct
them for hot-delete operation.  They are also used for rollback
as well.

acpi_del_commit() calls _EJ0 to eject a target object for hot-delete.

acpi_rollback_ost() calls _OST to inform FW that a hot-plug operation
completed with error in case of failure.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
---
 drivers/acpi/bus.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 133 insertions(+)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 1f0d457..341db34 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -42,6 +42,7 @@
 #include <acpi/apei.h>
 #include <linux/dmi.h>
 #include <linux/suspend.h>
+#include <linux/hotplug.h>
 
 #include "internal.h"
 
@@ -52,6 +53,9 @@ struct acpi_device *acpi_root;
 struct proc_dir_entry *acpi_root_dir;
 EXPORT_SYMBOL(acpi_root_dir);
 
+static int acpi_add_execute(struct hp_request *req, int rollback);
+static int acpi_del_execute(struct hp_request *req, int rollback);
+
 #define STRUCT_TO_INT(s)	(*((int*)&s))
 
 
@@ -859,6 +863,134 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
 }
 
 /* --------------------------------------------------------------------------
+			Hot-plug Handling
+   -------------------------------------------------------------------------- */
+
+static int acpi_rollback_ost(struct hp_request *req, int rollback)
+{
+	/* If hotplug request failed, inform firmware with error */
+	if (rollback && hp_is_hotplug_op(req->operation))
+		(void) acpi_evaluate_hotplug_ost(req->handle, req->event,
+				ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL);
+
+	return 0;
+}
+
+static int acpi_add_execute(struct hp_request *req, int rollback)
+{
+	acpi_handle handle = (acpi_handle) req->handle;
+	acpi_handle phandle;
+	struct acpi_device *device = NULL;
+	struct acpi_device *pdev;
+	int ret;
+
+	if (rollback)
+		return acpi_del_execute(req, 0);
+
+	/* only handle hot-plug operation */
+	if (!hp_is_hotplug_op(req->operation))
+		return 0;
+
+	if (acpi_get_parent(handle, &phandle))
+		return -ENODEV;
+
+	if (acpi_bus_get_device(phandle, &pdev))
+		return -ENODEV;
+
+	ret = acpi_bus_add(&device, pdev, handle, ACPI_BUS_TYPE_DEVICE);
+
+	return ret;
+}
+
+static int acpi_add_commit(struct hp_request *req, int rollback)
+{
+	/* Inform firmware that the hotplug operation has completed */
+	(void) acpi_evaluate_hotplug_ost(req->handle, req->event,
+					ACPI_OST_SC_SUCCESS, NULL);
+
+	return 0;
+}
+
+static int acpi_del_execute(struct hp_request *req, int rollback)
+{
+	acpi_handle handle = (acpi_handle) req->handle;
+	struct acpi_device *device;
+
+	if (rollback)
+		return acpi_add_execute(req, 0);
+
+	/* only handle hot-plug operation */
+	if (!hp_is_hotplug_op(req->operation))
+		return 0;
+
+	if (acpi_bus_get_device(handle, &device)) {
+		acpi_handle_err(handle, "Failed to obtain device\n");
+		return -EINVAL;
+	}
+
+	if (acpi_bus_trim(device, 1)) {
+		dev_err(&device->dev, "Removing device failed\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int acpi_del_commit(struct hp_request *req, int rollback)
+{
+	acpi_handle handle = (acpi_handle) req->handle;
+	acpi_handle temp;
+	struct acpi_object_list arg_list;
+	union acpi_object arg;
+	acpi_status status;
+
+	/* only handle hot-plug operation */
+	if (!hp_is_hotplug_op(req->operation))
+		return 0;
+
+	/* power off device */
+	status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
+	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
+		acpi_handle_warn(handle, "Power-off device failed\n");
+
+	if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) {
+		arg_list.count = 1;
+		arg_list.pointer = &arg;
+		arg.type = ACPI_TYPE_INTEGER;
+		arg.integer.value = 0;
+		acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
+	}
+
+	arg_list.count = 1;
+	arg_list.pointer = &arg;
+	arg.type = ACPI_TYPE_INTEGER;
+	arg.integer.value = 1;
+
+	status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
+	if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND))
+			acpi_handle_warn(handle, "Eject device failed\n");
+
+	return 0;
+}
+
+static void __init acpi_hp_init(void)
+{
+	hp_register_handler(HP_ADD_VALIDATE, acpi_rollback_ost,
+				HP_ACPI_BUS_ADD_VALIDATE_ORDER);
+	hp_register_handler(HP_ADD_EXECUTE, acpi_add_execute,
+				HP_ACPI_BUS_ADD_EXECUTE_ORDER);
+	hp_register_handler(HP_ADD_COMMIT, acpi_add_commit,
+				HP_ACPI_BUS_ADD_COMMIT_ORDER);
+
+	hp_register_handler(HP_DEL_VALIDATE, acpi_rollback_ost,
+				HP_ACPI_BUS_DEL_VALIDATE_ORDER);
+	hp_register_handler(HP_DEL_EXECUTE, acpi_del_execute,
+				HP_ACPI_BUS_DEL_EXECUTE_ORDER);
+	hp_register_handler(HP_DEL_COMMIT, acpi_del_commit,
+				HP_ACPI_BUS_DEL_COMMIT_ORDER);
+}
+
+/* --------------------------------------------------------------------------
                              Initialization/Cleanup
    -------------------------------------------------------------------------- */
 
@@ -1103,6 +1235,7 @@ static int __init acpi_init(void)
 	acpi_debugfs_init();
 	acpi_sleep_proc_init();
 	acpi_wakeup_device_init();
+	acpi_hp_init();
 	return 0;
 }
 
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH 06/11] ACPI: Add ACPI resource hotplug handler
  2012-12-12 23:17 [RFC PATCH 00/11] Hot-plug and Online/Offline framework Toshi Kani
                   ` (4 preceding siblings ...)
  2012-12-12 23:17 ` [RFC PATCH 05/11] ACPI: Add ACPI bus " Toshi Kani
@ 2012-12-12 23:17 ` Toshi Kani
  2012-12-12 23:17 ` [RFC PATCH 07/11] ACPI: Update processor driver for hotplug framework Toshi Kani
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-12 23:17 UTC (permalink / raw)
  To: rjw, lenb, gregkh, akpm
  Cc: linux-acpi, linux-kernel, linux-mm, bhelgaas, isimatu.yasuaki,
	jiang.liu, wency, guohanjun, yinghai, srivatsa.bhat, Toshi Kani

Added ACPI resource handler for hotplug operations.  The handler,
acpi_set_hp_device(), sets device resource information to a hotplug
request, which is then used by the CPU and memory handlers.
For setting the device resource information, acpi_scan_hp_devices()
walks the acpi_device tree from a target device, and calls .resource
of ACPI drivers.

For hot-add, acpi_set_hp_device() is called right after the ACPI bus
handler so that it can walk through new acpi_device objects.  For 
hot-delete, it is called at the begging of the validate phase so that
other validate handlers can use the device resource information for
their validations.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
---
 drivers/acpi/Makefile      |  1 +
 drivers/acpi/bus.c         |  1 +
 drivers/acpi/hp_resource.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/internal.h    |  1 +
 include/acpi/acpi_bus.h    |  4 +++
 5 files changed, 93 insertions(+)
 create mode 100644 drivers/acpi/hp_resource.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 2a4502b..6ef20f1 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -34,6 +34,7 @@ acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o
 acpi-y				+= bus.o glue.o
 acpi-y				+= scan.o
 acpi-y				+= resource.o
+acpi-y				+= hp_resource.o
 acpi-y				+= processor_core.o
 acpi-y				+= ec.o
 acpi-$(CONFIG_ACPI_DOCK)	+= dock.o
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 341db34..808d6e9 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1236,6 +1236,7 @@ static int __init acpi_init(void)
 	acpi_sleep_proc_init();
 	acpi_wakeup_device_init();
 	acpi_hp_init();
+	acpi_hp_res_init();
 	return 0;
 }
 
diff --git a/drivers/acpi/hp_resource.c b/drivers/acpi/hp_resource.c
new file mode 100644
index 0000000..7073feb
--- /dev/null
+++ b/drivers/acpi/hp_resource.c
@@ -0,0 +1,86 @@
+/*
+ * hp_resource.c - Setup hot-plug device resource information
+ *
+ * Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
+ *	Toshi Kani <toshi.kani@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/hotplug.h>
+#include <linux/acpi.h>
+
+#include "internal.h"
+
+static int
+acpi_set_hp_device(struct acpi_device *device, struct hp_request *req)
+{
+	int ret;
+
+	if (!device->driver) {
+		dev_dbg(&device->dev, "driver not bound\n");
+		return 0;
+	}
+
+	if (!device->driver->ops.resource)
+		return 0;
+
+	ret = device->driver->ops.resource(device, req);
+	if (ret) {
+		dev_err(&device->dev, "ops.resource failed (%d)\n", ret);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+acpi_scan_hp_devices(struct acpi_device *device, struct hp_request *req)
+{
+	struct acpi_device *child = NULL;
+
+	if (acpi_set_hp_device(device, req))
+		return 0;
+
+	list_for_each_entry(child, &device->children, node)
+		acpi_scan_hp_devices(child, req);
+
+	return 0;
+}
+
+static int acpi_set_hp_resources(struct hp_request *req, int rollback)
+{
+	acpi_handle handle = (acpi_handle) req->handle;
+	struct acpi_device *device = NULL;
+
+	if (rollback)
+		return 0;
+
+	/* only handle hot-plug operation */
+	if (!hp_is_hotplug_op(req->operation))
+		return 0;
+
+	if (acpi_bus_get_device(handle, &device)) {
+		acpi_handle_err(handle, "acpi_bus_get_device failed\n");
+		return -EINVAL;
+	}
+
+	acpi_scan_hp_devices(device, req);
+
+	return 0;
+}
+
+void __init acpi_hp_res_init(void)
+{
+	hp_register_handler(HP_ADD_EXECUTE, acpi_set_hp_resources,
+				HP_ACPI_RES_ADD_EXECUTE_ORDER);
+	hp_register_handler(HP_DEL_VALIDATE, acpi_set_hp_resources,
+				HP_ACPI_RES_DEL_VALIDATE_ORDER);
+}
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 3c407cd..7aff137 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -26,6 +26,7 @@
 int init_acpi_device_notify(void);
 int acpi_scan_init(void);
 int acpi_sysfs_init(void);
+void acpi_hp_res_init(void);
 
 #ifdef CONFIG_DEBUG_FS
 extern struct dentry *acpi_debugfs_dir;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 7ced5dc..10031a8 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -27,6 +27,7 @@
 #define __ACPI_BUS_H__
 
 #include <linux/device.h>
+#include <linux/hotplug.h>
 
 #include <acpi/acpi.h>
 
@@ -94,6 +95,8 @@ typedef int (*acpi_op_start) (struct acpi_device * device);
 typedef int (*acpi_op_bind) (struct acpi_device * device);
 typedef int (*acpi_op_unbind) (struct acpi_device * device);
 typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event);
+typedef int (*acpi_op_resource) (struct acpi_device *device,
+			struct hp_request *hp_req);
 
 struct acpi_bus_ops {
 	u32 acpi_op_add:1;
@@ -107,6 +110,7 @@ struct acpi_device_ops {
 	acpi_op_bind bind;
 	acpi_op_unbind unbind;
 	acpi_op_notify notify;
+	acpi_op_resource resource;
 };
 
 #define ACPI_DRIVER_ALL_NOTIFY_EVENTS	0x1	/* system AND device events */
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH 07/11] ACPI: Update processor driver for hotplug framework
  2012-12-12 23:17 [RFC PATCH 00/11] Hot-plug and Online/Offline framework Toshi Kani
                   ` (5 preceding siblings ...)
  2012-12-12 23:17 ` [RFC PATCH 06/11] ACPI: Add ACPI resource hotplug handler Toshi Kani
@ 2012-12-12 23:17 ` Toshi Kani
  2012-12-12 23:17 ` [RFC PATCH 08/11] ACPI: Update memory " Toshi Kani
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-12 23:17 UTC (permalink / raw)
  To: rjw, lenb, gregkh, akpm
  Cc: linux-acpi, linux-kernel, linux-mm, bhelgaas, isimatu.yasuaki,
	jiang.liu, wency, guohanjun, yinghai, srivatsa.bhat, Toshi Kani

Added acpi_processor_resource() for the .resource interface,
which sets CPU information to a hotplug request.

Changed acpi_processor_hotplug_notify() to request a hotplug
operation by calling hp_submit_req().  It no longer initiates
hot-add or hot-delete operation by calling acpi_bus_add() or
acpi_bus_hot_remove_device() directly.

acpi_processor_handle_eject() is changed not to call cpu_down()
since .add / .remove may not online / offline a device.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
---
 drivers/acpi/processor_driver.c | 150 +++++++++++++++++++---------------------
 1 file changed, 70 insertions(+), 80 deletions(-)

diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index e83311b..4b2b7cf 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -45,6 +45,7 @@
 #include <linux/cpuidle.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
+#include <linux/hotplug.h>
 
 #include <asm/io.h>
 #include <asm/cpu.h>
@@ -83,6 +84,8 @@ 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 int acpi_processor_resource(struct acpi_device *device,
+		struct hp_request *hp_req);
 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);
@@ -105,6 +108,7 @@ static struct acpi_driver acpi_processor_driver = {
 		.add = acpi_processor_add,
 		.remove = acpi_processor_remove,
 		.notify = acpi_processor_notify,
+		.resource = acpi_processor_resource,
 		},
 	.drv.pm = &acpi_processor_pm,
 };
@@ -649,6 +653,33 @@ free:
 	return 0;
 }
 
+static int
+acpi_processor_resource(struct acpi_device *device, struct hp_request *hp_req)
+{
+	struct acpi_processor *pr;
+	struct hp_device *hp_dev;
+
+	pr = acpi_driver_data(device);
+	if (!pr) {
+		dev_err(&device->dev, "Driver data missing\n");
+		return -EINVAL;
+	}
+
+	hp_dev = kzalloc(sizeof(*hp_dev), GFP_KERNEL);
+	if (!hp_dev) {
+		dev_err(&device->dev, "Failed to allocate hp_dev\n");
+		return -EINVAL;
+	}
+
+	hp_dev->device = &device->dev;
+	hp_dev->class = HP_CLS_CPU;
+	hp_dev->data.cpu.cpu_id = pr->id;
+
+	hp_add_dev_info(hp_req, hp_dev);
+
+	return 0;
+}
+
 #ifdef CONFIG_ACPI_HOTPLUG_CPU
 /****************************************************************************
  * 	Acpi processor hotplug support 				       	    *
@@ -677,97 +708,68 @@ static int is_processor_present(acpi_handle handle)
 	return 0;
 }
 
-static
-int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
-{
-	acpi_handle phandle;
-	struct acpi_device *pdev;
-
-
-	if (acpi_get_parent(handle, &phandle)) {
-		return -ENODEV;
-	}
-
-	if (acpi_bus_get_device(phandle, &pdev)) {
-		return -ENODEV;
-	}
-
-	if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
 static void acpi_processor_hotplug_notify(acpi_handle handle,
 					  u32 event, void *data)
 {
 	struct acpi_device *device = NULL;
-	struct acpi_eject_event *ej_event = NULL;
+	struct hp_request *hp_req;
+	enum hp_operation hp_op;
 	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
-	int result;
 
 	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;
+		if (!is_processor_present(handle)) {
+			acpi_handle_err(handle, "Device not enabled\n");
+			goto err;
+		}
 
-		result = acpi_processor_device_add(handle, &device);
-		if (result) {
-			acpi_handle_err(handle, "Unable to add the device\n");
-			break;
+		if (!acpi_bus_get_device(handle, &device)) {
+			acpi_handle_err(handle, "Device added already\n");
+			goto err;
 		}
 
-		ost_code = ACPI_OST_SC_SUCCESS;
+		hp_op = HP_HOTPLUG_ADD;
 		break;
 
 	case ACPI_NOTIFY_EJECT_REQUEST:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "received ACPI_NOTIFY_EJECT_REQUEST\n"));
-
 		if (acpi_bus_get_device(handle, &device)) {
-			acpi_handle_err(handle,
-				"Device don't exist, dropping EJECT\n");
-			break;
+			acpi_handle_err(handle, "Device not added yet\n");
+			goto err;
 		}
 		if (!acpi_driver_data(device)) {
-			acpi_handle_err(handle,
-				"Driver data is NULL, dropping EJECT\n");
-			break;
+			acpi_handle_err(handle, "Driver data missing\n");
+			goto err;
 		}
 
-		ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
-		if (!ej_event) {
-			acpi_handle_err(handle, "No memory, dropping EJECT\n");
-			break;
-		}
-
-		ej_event->handle = handle;
-		ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
-		acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
-					(void *)ej_event);
-
-		/* eject is performed asynchronously */
-		return;
+		hp_op = HP_HOTPLUG_DEL;
+		break;
 
 	default:
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Unsupported event [0x%x]\n", event));
-
-		/* non-hotplug event; possibly handled by other handler */
 		return;
 	}
 
-	/* Inform firmware that the hotplug operation has completed */
+	hp_req = hp_alloc_request(hp_op);
+	if (!hp_req) {
+		acpi_handle_err(handle, "No memory to request hotplug\n");
+		goto err;
+	}
+
+	hp_req->handle = (void *)handle;
+	hp_req->event = event;
+
+	if (hp_submit_req(hp_req)) {
+		acpi_handle_err(handle, "Failed to request hotplug\n");
+		kfree(hp_req);
+		goto err;
+	}
+
+	return;
+
+err:
+	/* Inform firmware that the hotplug operation completed w/ error */
 	(void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
 	return;
 }
@@ -865,25 +867,13 @@ static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
 
 static int acpi_processor_handle_eject(struct acpi_processor *pr)
 {
-	if (cpu_online(pr->id))
-		cpu_down(pr->id);
-
-	get_online_cpus();
-	/*
-	 * The cpu might become online again at this point. So we check whether
-	 * the cpu has been onlined or not. If the cpu became online, it means
-	 * that someone wants to use the cpu. So acpi_processor_handle_eject()
-	 * returns -EAGAIN.
-	 */
-	if (unlikely(cpu_online(pr->id))) {
-		put_online_cpus();
-		pr_warn("Failed to remove CPU %d, because other task "
-			"brought the CPU back online\n", pr->id);
-		return -EAGAIN;
+	if (cpu_online(pr->id)) {
+		pr_err("ACPI: cpu %d not off-lined\n", pr->id);
+		return -EINVAL;
 	}
+
 	arch_unregister_cpu(pr->id);
 	acpi_unmap_lsapic(pr->id);
-	put_online_cpus();
 	return (0);
 }
 #else
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH 08/11] ACPI: Update memory driver for hotplug framework
  2012-12-12 23:17 [RFC PATCH 00/11] Hot-plug and Online/Offline framework Toshi Kani
                   ` (6 preceding siblings ...)
  2012-12-12 23:17 ` [RFC PATCH 07/11] ACPI: Update processor driver for hotplug framework Toshi Kani
@ 2012-12-12 23:17 ` Toshi Kani
  2012-12-12 23:17 ` [RFC PATCH 09/11] ACPI: Update container " Toshi Kani
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-12 23:17 UTC (permalink / raw)
  To: rjw, lenb, gregkh, akpm
  Cc: linux-acpi, linux-kernel, linux-mm, bhelgaas, isimatu.yasuaki,
	jiang.liu, wency, guohanjun, yinghai, srivatsa.bhat, Toshi Kani

Changed acpi_memory_device_notify() to request a hotplug operation
by calling hp_submit_req().  It no longer initiates hot-add or
hot-delete operation by calling add_memory() or remove_memory()
directly.

Changed acpi_memory_device_add() to not call add_memory() to online
a memory device.  Similarly, changed acpi_memory_device_remove()
to not call remove_memory() to offline a memory device.

Added acpi_memory_resource() to set memory information to a hotplug
request.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
---
 drivers/acpi/acpi_memhotplug.c | 290 +++++++++++++----------------------------
 1 file changed, 90 insertions(+), 200 deletions(-)

diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index eb30e5a..3409264 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -32,6 +32,7 @@
 #include <linux/memory_hotplug.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
+#include <linux/hotplug.h>
 #include <acpi/acpi_drivers.h>
 
 #define ACPI_MEMORY_DEVICE_CLASS		"memory"
@@ -55,6 +56,8 @@ MODULE_LICENSE("GPL");
 
 static int acpi_memory_device_add(struct acpi_device *device);
 static int acpi_memory_device_remove(struct acpi_device *device, int type);
+static int acpi_memory_device_resource(struct acpi_device *device,
+		struct hp_request *hp_req);
 
 static const struct acpi_device_id memory_device_ids[] = {
 	{ACPI_MEMORY_DEVICE_HID, 0},
@@ -69,6 +72,7 @@ static struct acpi_driver acpi_memory_device_driver = {
 	.ops = {
 		.add = acpi_memory_device_add,
 		.remove = acpi_memory_device_remove,
+		.resource = acpi_memory_device_resource,
 		},
 };
 
@@ -153,59 +157,12 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
 	return 0;
 }
 
-static int
-acpi_memory_get_device(acpi_handle handle,
-		       struct acpi_memory_device **mem_device)
-{
-	acpi_status status;
-	acpi_handle phandle;
-	struct acpi_device *device = NULL;
-	struct acpi_device *pdevice = NULL;
-	int result;
-
-
-	if (!acpi_bus_get_device(handle, &device) && device)
-		goto end;
-
-	status = acpi_get_parent(handle, &phandle);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Cannot find acpi parent"));
-		return -EINVAL;
-	}
-
-	/* Get the parent device */
-	result = acpi_bus_get_device(phandle, &pdevice);
-	if (result) {
-		acpi_handle_warn(phandle, "Cannot get acpi bus device\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * Now add the notified device.  This creates the acpi_device
-	 * and invokes .add function
-	 */
-	result = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE);
-	if (result) {
-		acpi_handle_warn(handle, "Cannot add acpi bus\n");
-		return -EINVAL;
-	}
-
-      end:
-	*mem_device = acpi_driver_data(device);
-	if (!(*mem_device)) {
-		dev_err(&device->dev, "driver data not found\n");
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
+static int acpi_memory_check_device(acpi_handle handle)
 {
 	unsigned long long current_status;
 
 	/* Get device present/absent information from the _STA */
-	if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, "_STA",
+	if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_STA",
 					       NULL, &current_status)))
 		return -ENODEV;
 	/*
@@ -220,166 +177,46 @@ static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
 	return 0;
 }
 
-static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
-{
-	int result, num_enabled = 0;
-	struct acpi_memory_info *info;
-	int node;
-
-
-	/* Get the range from the _CRS */
-	result = acpi_memory_get_device_resources(mem_device);
-	if (result) {
-		dev_err(&mem_device->device->dev,
-			"get_device_resources failed\n");
-		mem_device->state = MEMORY_INVALID_STATE;
-		return result;
-	}
-
-	node = acpi_get_node(mem_device->device->handle);
-	/*
-	 * Tell the VM there is more memory here...
-	 * Note: Assume that this function returns zero on success
-	 * We don't have memory-hot-add rollback function,now.
-	 * (i.e. memory-hot-remove function)
-	 */
-	list_for_each_entry(info, &mem_device->res_list, list) {
-		if (info->enabled) { /* just sanity check...*/
-			num_enabled++;
-			continue;
-		}
-		/*
-		 * If the memory block size is zero, please ignore it.
-		 * Don't try to do the following memory hotplug flowchart.
-		 */
-		if (!info->length)
-			continue;
-		if (node < 0)
-			node = memory_add_physaddr_to_nid(info->start_addr);
-
-		result = add_memory(node, info->start_addr, info->length);
-
-		/*
-		 * If the memory block has been used by the kernel, add_memory()
-		 * returns -EEXIST. If add_memory() returns the other error, it
-		 * means that this memory block is not used by the kernel.
-		 */
-		if (result && result != -EEXIST) {
-			info->failed = 1;
-			continue;
-		}
-
-		if (!result)
-			info->enabled = 1;
-		/*
-		 * Add num_enable even if add_memory() returns -EEXIST, so the
-		 * device is bound to this driver.
-		 */
-		num_enabled++;
-	}
-	if (!num_enabled) {
-		dev_err(&mem_device->device->dev, "add_memory failed\n");
-		mem_device->state = MEMORY_INVALID_STATE;
-		return -EINVAL;
-	}
-	/*
-	 * Sometimes the memory device will contain several memory blocks.
-	 * When one memory block is hot-added to the system memory, it will
-	 * be regarded as a success.
-	 * Otherwise if the last memory block can't be hot-added to the system
-	 * memory, it will be failure and the memory device can't be bound with
-	 * driver.
-	 */
-	return 0;
-}
-
-static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
-{
-	int result = 0;
-	struct acpi_memory_info *info, *n;
-
-	list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
-		if (info->failed)
-			/* The kernel does not use this memory block */
-			continue;
-
-		if (!info->enabled)
-			/*
-			 * The kernel uses this memory block, but it may be not
-			 * managed by us.
-			 */
-			return -EBUSY;
-
-		result = remove_memory(info->start_addr, info->length);
-		if (result)
-			return result;
-
-		list_del(&info->list);
-		kfree(info);
-	}
-
-	return result;
-}
-
 static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
 {
 	struct acpi_memory_device *mem_device;
 	struct acpi_device *device;
-	struct acpi_eject_event *ej_event = NULL;
+	struct hp_request *hp_req;
+	enum hp_operation hp_op;
 	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
 
 	switch (event) {
 	case ACPI_NOTIFY_BUS_CHECK:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "\nReceived BUS CHECK notification for device\n"));
 		/* Fall Through */
 	case ACPI_NOTIFY_DEVICE_CHECK:
-		if (event == ACPI_NOTIFY_DEVICE_CHECK)
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-					  "\nReceived DEVICE CHECK notification for device\n"));
-		if (acpi_memory_get_device(handle, &mem_device)) {
-			acpi_handle_err(handle, "Cannot find driver data\n");
-			break;
+		if (acpi_memory_check_device(handle)) {
+			acpi_handle_err(handle, "Device not enabled\n");
+			goto err;
 		}
 
-		if (acpi_memory_check_device(mem_device))
-			break;
-
-		if (acpi_memory_enable_device(mem_device)) {
-			acpi_handle_err(handle,"Cannot enable memory device\n");
-			break;
+		if (!acpi_bus_get_device(handle, &device)) {
+			acpi_handle_err(handle, "Device added already\n");
+			goto err;
 		}
 
-		ost_code = ACPI_OST_SC_SUCCESS;
+		hp_op = HP_HOTPLUG_ADD;
 		break;
 
 	case ACPI_NOTIFY_EJECT_REQUEST:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "\nReceived EJECT REQUEST notification for device\n"));
-
 		if (acpi_bus_get_device(handle, &device)) {
-			acpi_handle_err(handle, "Device doesn't exist\n");
-			break;
+			acpi_handle_err(handle, "Device not added yet\n");
+			goto err;
 		}
+
 		mem_device = acpi_driver_data(device);
 		if (!mem_device) {
-			acpi_handle_err(handle, "Driver Data is NULL\n");
-			break;
-		}
-
-		ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
-		if (!ej_event) {
-			pr_err(PREFIX "No memory, dropping EJECT\n");
-			break;
+			acpi_handle_err(handle, "Driver data missing\n");
+			goto err;
 		}
 
-		ej_event->handle = handle;
-		ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
-		acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
-					(void *)ej_event);
+		hp_op = HP_HOTPLUG_DEL;
+		break;
 
-		/* eject is performed asynchronously */
-		return;
 	default:
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Unsupported event [0x%x]\n", event));
@@ -388,7 +225,25 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
 		return;
 	}
 
-	/* Inform firmware that the hotplug operation has completed */
+	hp_req = hp_alloc_request(hp_op);
+	if (!hp_req) {
+		acpi_handle_err(handle, "No memory to request hotplug\n");
+		goto err;
+	}
+
+	hp_req->handle = (void *)handle;
+	hp_req->event = event;
+
+	if (hp_submit_req(hp_req)) {
+		acpi_handle_err(handle, "Failed to request hotplug\n");
+		kfree(hp_req);
+		goto err;
+	}
+
+	return;
+
+err:
+	/* Inform firmware that the hotplug operation completed w/ error */
 	(void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
 	return;
 }
@@ -432,38 +287,73 @@ static int acpi_memory_device_add(struct acpi_device *device)
 	mem_device->state = MEMORY_POWER_ON_STATE;
 
 	pr_debug("%s\n", acpi_device_name(device));
-
-	if (!acpi_memory_check_device(mem_device)) {
-		/* call add_memory func */
-		result = acpi_memory_enable_device(mem_device);
-		if (result) {
-			dev_err(&device->dev,
-				"Error in acpi_memory_enable_device\n");
-			acpi_memory_device_free(mem_device);
-		}
-	}
 	return result;
 }
 
 static int acpi_memory_device_remove(struct acpi_device *device, int type)
 {
 	struct acpi_memory_device *mem_device = NULL;
-	int result;
+	struct acpi_memory_info *info, *n;
 
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
 	mem_device = acpi_driver_data(device);
 
-	result = acpi_memory_remove_memory(mem_device);
-	if (result)
-		return result;
+	/* remove the memory_info list of this mem_device */
+	list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
+		list_del(&info->list);
+		kfree(info);
+	}
 
 	acpi_memory_device_free(mem_device);
 
 	return 0;
 }
 
+static int acpi_memory_device_resource(struct acpi_device *device,
+				struct hp_request *hp_req)
+{
+	struct acpi_memory_device *mem_device = NULL;
+	struct acpi_memory_info *info, *n;
+	struct hp_device *hp_dev;
+	int node;
+
+	mem_device = acpi_driver_data(device);
+	if (!mem_device) {
+		dev_err(&device->dev, "Invalid device\n");
+		return -EINVAL;
+	}
+
+	node = acpi_get_node(mem_device->device->handle);
+
+	/*
+	 * REVISIT: Check if the original info->enabled & info->failed handling
+	 * is still necessary here.
+	 */
+	list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
+
+		if (!info->length)
+			continue;
+
+		hp_dev = kzalloc(sizeof(*hp_dev), GFP_KERNEL);
+		if (!hp_dev) {
+			dev_err(&device->dev, "Failed to allocate hp_dev\n");
+			return -EINVAL;
+		}
+
+		hp_dev->device = &device->dev;
+		hp_dev->class = HP_CLS_MEMORY;
+		hp_dev->data.mem.node = node;
+		hp_dev->data.mem.start_addr = info->start_addr;
+		hp_dev->data.mem.length = info->length;
+
+		hp_add_dev_info(hp_req, hp_dev);
+	}
+
+	return 0;
+}
+
 /*
  * Helper function to check for memory device
  */
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH 09/11] ACPI: Update container driver for hotplug framework
  2012-12-12 23:17 [RFC PATCH 00/11] Hot-plug and Online/Offline framework Toshi Kani
                   ` (7 preceding siblings ...)
  2012-12-12 23:17 ` [RFC PATCH 08/11] ACPI: Update memory " Toshi Kani
@ 2012-12-12 23:17 ` Toshi Kani
  2012-12-12 23:17 ` [RFC PATCH 10/11] cpu: Update sysfs cpu/online " Toshi Kani
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-12 23:17 UTC (permalink / raw)
  To: rjw, lenb, gregkh, akpm
  Cc: linux-acpi, linux-kernel, linux-mm, bhelgaas, isimatu.yasuaki,
	jiang.liu, wency, guohanjun, yinghai, srivatsa.bhat, Toshi Kani

Changed container_notify_cb() to request a hotplug operation by
calling hp_submit_req().  It no longer initiates hot-add by calling
acpi_bus_add().  Also, it no longer sets device->flags.eject_pending
and generates KOBJ_OFFLINE event for hot-delete.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
---
 drivers/acpi/container.c | 95 +++++++++++++++++++-----------------------------
 1 file changed, 37 insertions(+), 58 deletions(-)

diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 811910b..fb9e875 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/hotplug.h>
 #include <linux/acpi.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -135,77 +136,37 @@ static int acpi_container_remove(struct acpi_device *device, int type)
 	return status;
 }
 
-static int container_device_add(struct acpi_device **device, acpi_handle handle)
-{
-	acpi_handle phandle;
-	struct acpi_device *pdev;
-	int result;
-
-
-	if (acpi_get_parent(handle, &phandle)) {
-		return -ENODEV;
-	}
-
-	if (acpi_bus_get_device(phandle, &pdev)) {
-		return -ENODEV;
-	}
-
-	if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_DEVICE)) {
-		return -ENODEV;
-	}
-
-	result = acpi_bus_start(*device);
-
-	return result;
-}
-
-static void container_notify_cb(acpi_handle handle, u32 type, void *context)
+static void container_notify_cb(acpi_handle handle, u32 event, void *context)
 {
 	struct acpi_device *device = NULL;
-	int result;
-	int present;
-	acpi_status status;
+	struct hp_request *hp_req;
+	enum hp_operation hp_op;
 	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
 
-	switch (type) {
+	switch (event) {
 	case ACPI_NOTIFY_BUS_CHECK:
 		/* Fall through */
 	case ACPI_NOTIFY_DEVICE_CHECK:
-		pr_debug("Container driver received %s event\n",
-		       (type == ACPI_NOTIFY_BUS_CHECK) ?
-		       "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK");
-
-		present = is_device_present(handle);
-		status = acpi_bus_get_device(handle, &device);
-		if (!present) {
-			if (ACPI_SUCCESS(status)) {
-				/* device exist and this is a remove request */
-				device->flags.eject_pending = 1;
-				kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
-				return;
-			}
-			break;
+		if (!is_device_present(handle)) {
+			acpi_handle_err(handle, "Device not enabled\n");
+			goto err;
 		}
 
-		if (!ACPI_FAILURE(status) || device)
-			break;
-
-		result = container_device_add(&device, handle);
-		if (result) {
-			acpi_handle_warn(handle, "Failed to add container\n");
-			break;
+		if (!acpi_bus_get_device(handle, &device)) {
+			acpi_handle_err(handle, "Device added already\n");
+			goto err;
 		}
 
-		kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
-		ost_code = ACPI_OST_SC_SUCCESS;
+		hp_op = HP_HOTPLUG_ADD;
 		break;
 
 	case ACPI_NOTIFY_EJECT_REQUEST:
-		if (!acpi_bus_get_device(handle, &device) && device) {
-			device->flags.eject_pending = 1;
-			kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
-			return;
+		if (acpi_bus_get_device(handle, &device)) {
+			acpi_handle_err(handle, "Device not added yet\n");
+			goto err;
 		}
+
+		hp_op = HP_HOTPLUG_DEL;
 		break;
 
 	default:
@@ -213,8 +174,26 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
 		return;
 	}
 
-	/* Inform firmware that the hotplug operation has completed */
-	(void) acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
+	hp_req = hp_alloc_request(hp_op);
+	if (!hp_req) {
+		acpi_handle_err(handle, "No memory to request hotplug\n");
+		goto err;
+	}
+
+	hp_req->handle = (void *)handle;
+	hp_req->event = event;
+
+	if (hp_submit_req(hp_req)) {
+		acpi_handle_err(handle, "Failed to request hotplug\n");
+		kfree(hp_req);
+		goto err;
+	}
+
+	return;
+
+err:
+	/* Inform firmware that the hotplug operation completed w/ error */
+	(void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
 	return;
 }
 
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH 10/11] cpu: Update sysfs cpu/online for hotplug framework
  2012-12-12 23:17 [RFC PATCH 00/11] Hot-plug and Online/Offline framework Toshi Kani
                   ` (8 preceding siblings ...)
  2012-12-12 23:17 ` [RFC PATCH 09/11] ACPI: Update container " Toshi Kani
@ 2012-12-12 23:17 ` Toshi Kani
  2012-12-12 23:17 ` [RFC PATCH 11/11] ACPI: Update sysfs eject " Toshi Kani
  2012-12-12 23:56 ` [RFC PATCH 00/11] Hot-plug and Online/Offline framework Greg KH
  11 siblings, 0 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-12 23:17 UTC (permalink / raw)
  To: rjw, lenb, gregkh, akpm
  Cc: linux-acpi, linux-kernel, linux-mm, bhelgaas, isimatu.yasuaki,
	jiang.liu, wency, guohanjun, yinghai, srivatsa.bhat, Toshi Kani

Changed store_online() to request a cpu online or offline
operation by calling hp_submit_req().  It sets a target cpu
device information with hp_add_dev_info() before making the
request.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
---
 drivers/base/cpu.c | 40 ++++++++++++++++++++++++++++------------
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 3870231..dc50d17 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -41,27 +41,43 @@ static ssize_t __ref store_online(struct device *dev,
 				  const char *buf, size_t count)
 {
 	struct cpu *cpu = container_of(dev, struct cpu, dev);
-	ssize_t ret;
+	struct hp_request *hp_req;
+	struct hp_device *hp_dev;
+	enum hp_operation operation;
+	ssize_t ret = count;
 
-	cpu_hotplug_driver_lock();
 	switch (buf[0]) {
 	case '0':
-		ret = cpu_down(cpu->dev.id);
-		if (!ret)
-			kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
+		operation = HP_ONLINE_DEL;
 		break;
 	case '1':
-		ret = cpu_up(cpu->dev.id);
-		if (!ret)
-			kobject_uevent(&dev->kobj, KOBJ_ONLINE);
+		operation = HP_ONLINE_ADD;
 		break;
 	default:
-		ret = -EINVAL;
+		return -EINVAL;
+	}
+
+	hp_req = hp_alloc_request(operation);
+	if (!hp_req)
+		return -ENOMEM;
+
+	hp_dev = kzalloc(sizeof(*hp_dev), GFP_KERNEL);
+	if (!hp_dev) {
+		kfree(hp_req);
+		return -ENOMEM;
+	}
+
+	hp_dev->device = dev;
+	hp_dev->class = HP_CLS_CPU;
+	hp_dev->data.cpu.cpu_id = cpu->dev.id;
+	hp_add_dev_info(hp_req, hp_dev);
+
+	if (hp_submit_req(hp_req)) {
+		kfree(hp_dev);
+		kfree(hp_req);
+		return -EINVAL;
 	}
-	cpu_hotplug_driver_unlock();
 
-	if (ret >= 0)
-		ret = count;
 	return ret;
 }
 static DEVICE_ATTR(online, 0644, show_online, store_online);
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH 11/11] ACPI: Update sysfs eject for hotplug framework
  2012-12-12 23:17 [RFC PATCH 00/11] Hot-plug and Online/Offline framework Toshi Kani
                   ` (9 preceding siblings ...)
  2012-12-12 23:17 ` [RFC PATCH 10/11] cpu: Update sysfs cpu/online " Toshi Kani
@ 2012-12-12 23:17 ` Toshi Kani
  2012-12-12 23:56 ` [RFC PATCH 00/11] Hot-plug and Online/Offline framework Greg KH
  11 siblings, 0 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-12 23:17 UTC (permalink / raw)
  To: rjw, lenb, gregkh, akpm
  Cc: linux-acpi, linux-kernel, linux-mm, bhelgaas, isimatu.yasuaki,
	jiang.liu, wency, guohanjun, yinghai, srivatsa.bhat, Toshi Kani

Changed acpi_eject_store() to request a hot-delete operation by
calling hp_submit_req().  It no longer initiates a hot-delete
operation by calling acpi_bus_hot_remove_device().

Deleted acpi_bus_hot_remove_device() since it no longer has any
caller and should not be called for hot-delete.

Deleted eject_pending bit from acpi_device_flags since the ACPI
container driver no longer sets it for hot-delete, and sysfs
eject no longer checks it in acpi_bus_hot_remove_device().

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
---
 drivers/acpi/scan.c     | 122 +++++++++---------------------------------------
 include/acpi/acpi_bus.h |   4 +-
 2 files changed, 23 insertions(+), 103 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 53502d1..a8f6803 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -11,6 +11,7 @@
 #include <linux/kthread.h>
 #include <linux/dmi.h>
 #include <linux/nls.h>
+#include <linux/hotplug.h>
 
 #include <acpi/acpi_drivers.h>
 
@@ -105,85 +106,6 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha
 }
 static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
 
-/**
- * acpi_bus_hot_remove_device: hot-remove a device and its children
- * @context: struct acpi_eject_event pointer (freed in this func)
- *
- * Hot-remove a device and its children. This function frees up the
- * memory space passed by arg context, so that the caller may call
- * this function asynchronously through acpi_os_hotplug_execute().
- */
-void acpi_bus_hot_remove_device(void *context)
-{
-	struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context;
-	struct acpi_device *device;
-	acpi_handle handle = ej_event->handle;
-	acpi_handle temp;
-	struct acpi_object_list arg_list;
-	union acpi_object arg;
-	acpi_status status = AE_OK;
-	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
-
-	if (acpi_bus_get_device(handle, &device))
-		goto err_out;
-
-	if (!device)
-		goto err_out;
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-		"Hot-removing device %s...\n", dev_name(&device->dev)));
-
-	if (acpi_bus_trim(device, 1)) {
-		printk(KERN_ERR PREFIX
-				"Removing device failed\n");
-		goto err_out;
-	}
-
-	/* device has been freed */
-	device = NULL;
-
-	/* power off device */
-	status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
-	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
-		printk(KERN_WARNING PREFIX
-				"Power-off device failed\n");
-
-	if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) {
-		arg_list.count = 1;
-		arg_list.pointer = &arg;
-		arg.type = ACPI_TYPE_INTEGER;
-		arg.integer.value = 0;
-		acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
-	}
-
-	arg_list.count = 1;
-	arg_list.pointer = &arg;
-	arg.type = ACPI_TYPE_INTEGER;
-	arg.integer.value = 1;
-
-	/*
-	 * TBD: _EJD support.
-	 */
-	status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
-	if (ACPI_FAILURE(status)) {
-		if (status != AE_NOT_FOUND)
-			printk(KERN_WARNING PREFIX
-					"Eject device failed\n");
-		goto err_out;
-	}
-
-	kfree(context);
-	return;
-
-err_out:
-	/* Inform firmware the hot-remove operation has completed w/ error */
-	(void) acpi_evaluate_hotplug_ost(handle,
-				ej_event->event, ost_code, NULL);
-	kfree(context);
-	return;
-}
-EXPORT_SYMBOL(acpi_bus_hot_remove_device);
-
 static ssize_t
 acpi_eject_store(struct device *d, struct device_attribute *attr,
 		const char *buf, size_t count)
@@ -192,44 +114,44 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
 	acpi_status status;
 	acpi_object_type type = 0;
 	struct acpi_device *acpi_device = to_acpi_device(d);
-	struct acpi_eject_event *ej_event;
+	struct hp_request *hp_req;
 
 	if ((!count) || (buf[0] != '1')) {
 		return -EINVAL;
 	}
 #ifndef FORCE_EJECT
 	if (acpi_device->driver == NULL) {
-		ret = -ENODEV;
-		goto err;
+		return -ENODEV;
 	}
 #endif
 	status = acpi_get_type(acpi_device->handle, &type);
 	if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) {
-		ret = -ENODEV;
-		goto err;
+		return -ENODEV;
 	}
 
-	ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
-	if (!ej_event) {
-		ret = -ENOMEM;
+	hp_req = hp_alloc_request(HP_HOTPLUG_DEL);
+	if (!hp_req)
+		return -ENOMEM;
+
+	hp_req->handle = (void *) acpi_device->handle;
+
+	/* event originated from user */
+	hp_req->event = ACPI_OST_EC_OSPM_EJECT;
+	(void) acpi_evaluate_hotplug_ost(hp_req->handle,
+			hp_req->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
+
+	if (hp_submit_req(hp_req)) {
+		kfree(hp_req);
 		goto err;
 	}
 
-	ej_event->handle = acpi_device->handle;
-	if (acpi_device->flags.eject_pending) {
-		/* event originated from ACPI eject notification */
-		ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
-		acpi_device->flags.eject_pending = 0;
-	} else {
-		/* event originated from user */
-		ej_event->event = ACPI_OST_EC_OSPM_EJECT;
-		(void) acpi_evaluate_hotplug_ost(ej_event->handle,
-			ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
-	}
+	return ret;
 
-	acpi_os_hotplug_execute(acpi_bus_hot_remove_device, (void *)ej_event);
 err:
-	return ret;
+	/* Inform firmware that the hotplug operation completed w/ error */
+	(void) acpi_evaluate_hotplug_ost(hp_req->handle,
+			hp_req->event, ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL);
+	return -EINVAL;
 }
 
 static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 10031a8..1ef71eb 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -151,8 +151,7 @@ struct acpi_device_flags {
 	u32 suprise_removal_ok:1;
 	u32 power_manageable:1;
 	u32 performance_manageable:1;
-	u32 eject_pending:1;
-	u32 reserved:24;
+	u32 reserved:25;
 };
 
 /* File System */
@@ -362,7 +361,6 @@ int acpi_bus_register_driver(struct acpi_driver *driver);
 void acpi_bus_unregister_driver(struct acpi_driver *driver);
 int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent,
 		 acpi_handle handle, int type);
-void acpi_bus_hot_remove_device(void *context);
 int acpi_bus_trim(struct acpi_device *start, int rmdevice);
 int acpi_bus_start(struct acpi_device *device);
 acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 01/11] Add hotplug.h for hotplug framework
  2012-12-12 23:17 ` [RFC PATCH 01/11] Add hotplug.h for hotplug framework Toshi Kani
@ 2012-12-12 23:53   ` Greg KH
  2012-12-13  3:56     ` Toshi Kani
  0 siblings, 1 reply; 30+ messages in thread
From: Greg KH @ 2012-12-12 23:53 UTC (permalink / raw)
  To: Toshi Kani
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Wed, Dec 12, 2012 at 04:17:13PM -0700, Toshi Kani wrote:
> Added include/linux/hotplug.h, which defines the hotplug framework
> interfaces used by the framework itself and handlers.

No, please name this properly, _everything_ is hotpluggable these days,
and unless you want the whole kernel and all busses and devices to use
this, then it needs to be named much better than this, sorry.

We went through this same issue over 10 years ago, please, let's learn
from our mistakes and not do it again.

> +/* Add Validate order values */
> +#define HP_ACPI_BUS_ADD_VALIDATE_ORDER		0	/* must be first */

This is really ACPI specific, so why not just put it under include/acpi/
instead?

And note, PPC and other arches probably do this already (s390?) so to
exclude them from the beginning would not be a good idea.

greg k-h

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 02/11] drivers/base: Add hotplug framework code
  2012-12-12 23:17 ` [RFC PATCH 02/11] drivers/base: Add hotplug framework code Toshi Kani
@ 2012-12-12 23:54   ` Greg KH
  2012-12-13  4:02     ` Toshi Kani
  2012-12-12 23:55   ` Greg KH
  1 sibling, 1 reply; 30+ messages in thread
From: Greg KH @ 2012-12-12 23:54 UTC (permalink / raw)
  To: Toshi Kani
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Wed, Dec 12, 2012 at 04:17:14PM -0700, Toshi Kani wrote:
> Added hotplug.c, which is the hotplug framework code.

Again, better naming please.

greg k-h

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 02/11] drivers/base: Add hotplug framework code
  2012-12-12 23:17 ` [RFC PATCH 02/11] drivers/base: Add hotplug framework code Toshi Kani
  2012-12-12 23:54   ` Greg KH
@ 2012-12-12 23:55   ` Greg KH
  2012-12-13  3:58     ` Toshi Kani
  1 sibling, 1 reply; 30+ messages in thread
From: Greg KH @ 2012-12-12 23:55 UTC (permalink / raw)
  To: Toshi Kani
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Wed, Dec 12, 2012 at 04:17:14PM -0700, Toshi Kani wrote:
> --- a/drivers/base/Makefile
> +++ b/drivers/base/Makefile
> @@ -21,6 +21,7 @@ endif
>  obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
>  obj-$(CONFIG_REGMAP)	+= regmap/
>  obj-$(CONFIG_SOC_BUS) += soc.o
> +obj-$(CONFIG_HOTPLUG)	+= hotplug.o

CONFIG_HOTPLUG just got always enabled in the kernel, and I'm about to
delete it around the 3.8-rc2 timeframe, so please don't add new usages
of it to the kernel.

greg k-h

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 00/11] Hot-plug and Online/Offline framework
  2012-12-12 23:17 [RFC PATCH 00/11] Hot-plug and Online/Offline framework Toshi Kani
                   ` (10 preceding siblings ...)
  2012-12-12 23:17 ` [RFC PATCH 11/11] ACPI: Update sysfs eject " Toshi Kani
@ 2012-12-12 23:56 ` Greg KH
  2012-12-13  0:39   ` Toshi Kani
  11 siblings, 1 reply; 30+ messages in thread
From: Greg KH @ 2012-12-12 23:56 UTC (permalink / raw)
  To: Toshi Kani
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Wed, Dec 12, 2012 at 04:17:12PM -0700, Toshi Kani wrote:
> This patchset is an initial prototype of proposed hot-plug framework
> for design review.  The hot-plug framework is designed to provide 
> the common framework for hot-plugging and online/offline operations
> of system devices, such as CPU, Memory and Node.  While this patchset
> only supports ACPI-based hot-plug operations, the framework itself is
> designed to be platform-neural and can support other FW architectures
> as necessary.
> 
> The patchset has not been fully tested yet, esp. for memory hot-plug.
> Any help for testing will be very appreciated since my test setup
> is limited.
> 
> The patchset is based on the linux-next branch of linux-pm.git tree.
> 
> Overview of the Framework
> =========================

<snip>

Why all the new framework, doesn't the existing bus infrastructure
provide everything you need here?  Shouldn't you just be putting your
cpus and memory sticks on a bus and handle stuff that way?  What makes
these types of devices so unique from all other devices that Linux has
been handling in a dynamic manner (i.e. hotplugging them) for many many
years?

Why are you reinventing the wheel?

confused,

greg k-h

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 00/11] Hot-plug and Online/Offline framework
  2012-12-12 23:56 ` [RFC PATCH 00/11] Hot-plug and Online/Offline framework Greg KH
@ 2012-12-13  0:39   ` Toshi Kani
  2012-12-13  0:55     ` Greg KH
  0 siblings, 1 reply; 30+ messages in thread
From: Toshi Kani @ 2012-12-13  0:39 UTC (permalink / raw)
  To: Greg KH
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Wed, 2012-12-12 at 15:56 -0800, Greg KH wrote:
> On Wed, Dec 12, 2012 at 04:17:12PM -0700, Toshi Kani wrote:
> > This patchset is an initial prototype of proposed hot-plug framework
> > for design review.  The hot-plug framework is designed to provide 
> > the common framework for hot-plugging and online/offline operations
> > of system devices, such as CPU, Memory and Node.  While this patchset
> > only supports ACPI-based hot-plug operations, the framework itself is
> > designed to be platform-neural and can support other FW architectures
> > as necessary.
> > 
> > The patchset has not been fully tested yet, esp. for memory hot-plug.
> > Any help for testing will be very appreciated since my test setup
> > is limited.
> > 
> > The patchset is based on the linux-next branch of linux-pm.git tree.
> > 
> > Overview of the Framework
> > =========================
> 
> <snip>
> 
> Why all the new framework, doesn't the existing bus infrastructure
> provide everything you need here?  Shouldn't you just be putting your
> cpus and memory sticks on a bus and handle stuff that way?  What makes
> these types of devices so unique from all other devices that Linux has
> been handling in a dynamic manner (i.e. hotplugging them) for many many
> years?
> 
> Why are you reinventing the wheel?

Good question.  Yes, USB and PCI hotplug operate based on their bus
structures.  USB and PCI cards only work under USB and PCI bus
controllers.  So, their framework can be composed within the bus
structures as you pointed out.

However, system devices such CPU and memory do not have their standard
bus.  ACPI allows these system devices to be enumerated, but it does not
make ACPI as the HW bus hierarchy for CPU and memory, unlike PCI and
USB.  Therefore, CPU and memory modules manage CPU and memory outside of
ACPI.  This makes sense because CPU and memory can be used without ACPI.

This leads us an issue when we try to manage system device hotplug
within ACPI, because ACPI does not control everything.  This patchset
provides a common hotplug framework for system devices, which both ACPI
and non-ACPI modules (i.e. CPU and memory modules) can participate and
are coordinated for their hotplug operations.  This is analogous to the
boot-up sequence, which ACPI and non-ACPI modules can participate to
enable CPU and memory.

Thanks,
-Toshi


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 00/11] Hot-plug and Online/Offline framework
  2012-12-13  0:39   ` Toshi Kani
@ 2012-12-13  0:55     ` Greg KH
  2012-12-13  3:37       ` Toshi Kani
  0 siblings, 1 reply; 30+ messages in thread
From: Greg KH @ 2012-12-13  0:55 UTC (permalink / raw)
  To: Toshi Kani
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Wed, Dec 12, 2012 at 05:39:36PM -0700, Toshi Kani wrote:
> On Wed, 2012-12-12 at 15:56 -0800, Greg KH wrote:
> > On Wed, Dec 12, 2012 at 04:17:12PM -0700, Toshi Kani wrote:
> > > This patchset is an initial prototype of proposed hot-plug framework
> > > for design review.  The hot-plug framework is designed to provide 
> > > the common framework for hot-plugging and online/offline operations
> > > of system devices, such as CPU, Memory and Node.  While this patchset
> > > only supports ACPI-based hot-plug operations, the framework itself is
> > > designed to be platform-neural and can support other FW architectures
> > > as necessary.
> > > 
> > > The patchset has not been fully tested yet, esp. for memory hot-plug.
> > > Any help for testing will be very appreciated since my test setup
> > > is limited.
> > > 
> > > The patchset is based on the linux-next branch of linux-pm.git tree.
> > > 
> > > Overview of the Framework
> > > =========================
> > 
> > <snip>
> > 
> > Why all the new framework, doesn't the existing bus infrastructure
> > provide everything you need here?  Shouldn't you just be putting your
> > cpus and memory sticks on a bus and handle stuff that way?  What makes
> > these types of devices so unique from all other devices that Linux has
> > been handling in a dynamic manner (i.e. hotplugging them) for many many
> > years?
> > 
> > Why are you reinventing the wheel?
> 
> Good question.  Yes, USB and PCI hotplug operate based on their bus
> structures.  USB and PCI cards only work under USB and PCI bus
> controllers.  So, their framework can be composed within the bus
> structures as you pointed out.
> 
> However, system devices such CPU and memory do not have their standard
> bus.  ACPI allows these system devices to be enumerated, but it does not
> make ACPI as the HW bus hierarchy for CPU and memory, unlike PCI and
> USB.  Therefore, CPU and memory modules manage CPU and memory outside of
> ACPI.  This makes sense because CPU and memory can be used without ACPI.
> 
> This leads us an issue when we try to manage system device hotplug
> within ACPI, because ACPI does not control everything.  This patchset
> provides a common hotplug framework for system devices, which both ACPI
> and non-ACPI modules (i.e. CPU and memory modules) can participate and
> are coordinated for their hotplug operations.  This is analogous to the
> boot-up sequence, which ACPI and non-ACPI modules can participate to
> enable CPU and memory.

Then create a "virtual" bus and put the devices you wish to control on
that.  That is what the "system bus" devices were supposed to be, it's
about time someone took that code and got it all working properly in
this way, that is why it was created oh so long ago.

greg k-h

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 00/11] Hot-plug and Online/Offline framework
  2012-12-13  0:55     ` Greg KH
@ 2012-12-13  3:37       ` Toshi Kani
  2012-12-13  4:16         ` Greg KH
  0 siblings, 1 reply; 30+ messages in thread
From: Toshi Kani @ 2012-12-13  3:37 UTC (permalink / raw)
  To: Greg KH
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Wed, 2012-12-12 at 16:55 -0800, Greg KH wrote:
> On Wed, Dec 12, 2012 at 05:39:36PM -0700, Toshi Kani wrote:
> > On Wed, 2012-12-12 at 15:56 -0800, Greg KH wrote:
> > > On Wed, Dec 12, 2012 at 04:17:12PM -0700, Toshi Kani wrote:
> > > > This patchset is an initial prototype of proposed hot-plug framework
> > > > for design review.  The hot-plug framework is designed to provide 
> > > > the common framework for hot-plugging and online/offline operations
> > > > of system devices, such as CPU, Memory and Node.  While this patchset
> > > > only supports ACPI-based hot-plug operations, the framework itself is
> > > > designed to be platform-neural and can support other FW architectures
> > > > as necessary.
> > > > 
> > > > The patchset has not been fully tested yet, esp. for memory hot-plug.
> > > > Any help for testing will be very appreciated since my test setup
> > > > is limited.
> > > > 
> > > > The patchset is based on the linux-next branch of linux-pm.git tree.
> > > > 
> > > > Overview of the Framework
> > > > =========================
> > > 
> > > <snip>
> > > 
> > > Why all the new framework, doesn't the existing bus infrastructure
> > > provide everything you need here?  Shouldn't you just be putting your
> > > cpus and memory sticks on a bus and handle stuff that way?  What makes
> > > these types of devices so unique from all other devices that Linux has
> > > been handling in a dynamic manner (i.e. hotplugging them) for many many
> > > years?
> > > 
> > > Why are you reinventing the wheel?
> > 
> > Good question.  Yes, USB and PCI hotplug operate based on their bus
> > structures.  USB and PCI cards only work under USB and PCI bus
> > controllers.  So, their framework can be composed within the bus
> > structures as you pointed out.
> > 
> > However, system devices such CPU and memory do not have their standard
> > bus.  ACPI allows these system devices to be enumerated, but it does not
> > make ACPI as the HW bus hierarchy for CPU and memory, unlike PCI and
> > USB.  Therefore, CPU and memory modules manage CPU and memory outside of
> > ACPI.  This makes sense because CPU and memory can be used without ACPI.
> > 
> > This leads us an issue when we try to manage system device hotplug
> > within ACPI, because ACPI does not control everything.  This patchset
> > provides a common hotplug framework for system devices, which both ACPI
> > and non-ACPI modules (i.e. CPU and memory modules) can participate and
> > are coordinated for their hotplug operations.  This is analogous to the
> > boot-up sequence, which ACPI and non-ACPI modules can participate to
> > enable CPU and memory.
> 
> Then create a "virtual" bus and put the devices you wish to control on
> that.  That is what the "system bus" devices were supposed to be, it's
> about time someone took that code and got it all working properly in
> this way, that is why it was created oh so long ago.

It may be the ideal, but it will take us great effort to make such
things to happen based on where we are now.  It is going to be a long
way.  I believe the first step is to make the boot-up flow and hot-plug
flow consistent for system devices.  This is what this patchset is
trying to do.

Thanks,
-Toshi



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 01/11] Add hotplug.h for hotplug framework
  2012-12-12 23:53   ` Greg KH
@ 2012-12-13  3:56     ` Toshi Kani
  0 siblings, 0 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-13  3:56 UTC (permalink / raw)
  To: Greg KH
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Wed, 2012-12-12 at 15:53 -0800, Greg KH wrote:
> On Wed, Dec 12, 2012 at 04:17:13PM -0700, Toshi Kani wrote:
> > Added include/linux/hotplug.h, which defines the hotplug framework
> > interfaces used by the framework itself and handlers.
> 
> No, please name this properly, _everything_ is hotpluggable these days,
> and unless you want the whole kernel and all busses and devices to use
> this, then it needs to be named much better than this, sorry.
> 
> We went through this same issue over 10 years ago, please, let's learn
> from our mistakes and not do it again.

Agreed.  I will come up with a better name to avoid the confusion.

> > +/* Add Validate order values */
> > +#define HP_ACPI_BUS_ADD_VALIDATE_ORDER		0	/* must be first */
> 
> This is really ACPI specific, so why not just put it under include/acpi/
> instead?

Yes, this needs to be revisited.  For now, it is defined in the same
file since it helps to manage the ordering when all values are defined
in a same place.  We may need the ordering values defined in each arch
when this framework is used by multiple architectures. 

> And note, PPC and other arches probably do this already (s390?) so to
> exclude them from the beginning would not be a good idea.

Thanks for the suggestion.  I will check other architectures and bring
them to the discussions. 

-Toshi



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 02/11] drivers/base: Add hotplug framework code
  2012-12-12 23:55   ` Greg KH
@ 2012-12-13  3:58     ` Toshi Kani
  0 siblings, 0 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-13  3:58 UTC (permalink / raw)
  To: Greg KH
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Wed, 2012-12-12 at 15:55 -0800, Greg KH wrote:
> On Wed, Dec 12, 2012 at 04:17:14PM -0700, Toshi Kani wrote:
> > --- a/drivers/base/Makefile
> > +++ b/drivers/base/Makefile
> > @@ -21,6 +21,7 @@ endif
> >  obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
> >  obj-$(CONFIG_REGMAP)	+= regmap/
> >  obj-$(CONFIG_SOC_BUS) += soc.o
> > +obj-$(CONFIG_HOTPLUG)	+= hotplug.o
> 
> CONFIG_HOTPLUG just got always enabled in the kernel, and I'm about to
> delete it around the 3.8-rc2 timeframe, so please don't add new usages
> of it to the kernel.

Sounds good.  I will simply change it obj-y then.

Thanks,
-Toshi


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 02/11] drivers/base: Add hotplug framework code
  2012-12-12 23:54   ` Greg KH
@ 2012-12-13  4:02     ` Toshi Kani
  2012-12-13  4:24       ` Greg KH
  0 siblings, 1 reply; 30+ messages in thread
From: Toshi Kani @ 2012-12-13  4:02 UTC (permalink / raw)
  To: Greg KH
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Wed, 2012-12-12 at 15:54 -0800, Greg KH wrote:
> On Wed, Dec 12, 2012 at 04:17:14PM -0700, Toshi Kani wrote:
> > Added hotplug.c, which is the hotplug framework code.
> 
> Again, better naming please.

Yes, I will change it to be more specific, something like
"sys_hotplug.c".

Thanks,
-Toshi


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 00/11] Hot-plug and Online/Offline framework
  2012-12-13  3:37       ` Toshi Kani
@ 2012-12-13  4:16         ` Greg KH
  2012-12-13 16:03           ` Toshi Kani
  0 siblings, 1 reply; 30+ messages in thread
From: Greg KH @ 2012-12-13  4:16 UTC (permalink / raw)
  To: Toshi Kani
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Wed, Dec 12, 2012 at 08:37:44PM -0700, Toshi Kani wrote:
> On Wed, 2012-12-12 at 16:55 -0800, Greg KH wrote:
> > On Wed, Dec 12, 2012 at 05:39:36PM -0700, Toshi Kani wrote:
> > > On Wed, 2012-12-12 at 15:56 -0800, Greg KH wrote:
> > > > On Wed, Dec 12, 2012 at 04:17:12PM -0700, Toshi Kani wrote:
> > > > > This patchset is an initial prototype of proposed hot-plug framework
> > > > > for design review.  The hot-plug framework is designed to provide 
> > > > > the common framework for hot-plugging and online/offline operations
> > > > > of system devices, such as CPU, Memory and Node.  While this patchset
> > > > > only supports ACPI-based hot-plug operations, the framework itself is
> > > > > designed to be platform-neural and can support other FW architectures
> > > > > as necessary.
> > > > > 
> > > > > The patchset has not been fully tested yet, esp. for memory hot-plug.
> > > > > Any help for testing will be very appreciated since my test setup
> > > > > is limited.
> > > > > 
> > > > > The patchset is based on the linux-next branch of linux-pm.git tree.
> > > > > 
> > > > > Overview of the Framework
> > > > > =========================
> > > > 
> > > > <snip>
> > > > 
> > > > Why all the new framework, doesn't the existing bus infrastructure
> > > > provide everything you need here?  Shouldn't you just be putting your
> > > > cpus and memory sticks on a bus and handle stuff that way?  What makes
> > > > these types of devices so unique from all other devices that Linux has
> > > > been handling in a dynamic manner (i.e. hotplugging them) for many many
> > > > years?
> > > > 
> > > > Why are you reinventing the wheel?
> > > 
> > > Good question.  Yes, USB and PCI hotplug operate based on their bus
> > > structures.  USB and PCI cards only work under USB and PCI bus
> > > controllers.  So, their framework can be composed within the bus
> > > structures as you pointed out.
> > > 
> > > However, system devices such CPU and memory do not have their standard
> > > bus.  ACPI allows these system devices to be enumerated, but it does not
> > > make ACPI as the HW bus hierarchy for CPU and memory, unlike PCI and
> > > USB.  Therefore, CPU and memory modules manage CPU and memory outside of
> > > ACPI.  This makes sense because CPU and memory can be used without ACPI.
> > > 
> > > This leads us an issue when we try to manage system device hotplug
> > > within ACPI, because ACPI does not control everything.  This patchset
> > > provides a common hotplug framework for system devices, which both ACPI
> > > and non-ACPI modules (i.e. CPU and memory modules) can participate and
> > > are coordinated for their hotplug operations.  This is analogous to the
> > > boot-up sequence, which ACPI and non-ACPI modules can participate to
> > > enable CPU and memory.
> > 
> > Then create a "virtual" bus and put the devices you wish to control on
> > that.  That is what the "system bus" devices were supposed to be, it's
> > about time someone took that code and got it all working properly in
> > this way, that is why it was created oh so long ago.
> 
> It may be the ideal, but it will take us great effort to make such
> things to happen based on where we are now.  It is going to be a long
> way.  I believe the first step is to make the boot-up flow and hot-plug
> flow consistent for system devices.  This is what this patchset is
> trying to do.

If you use the system "bus" for this, the "flow" will be identical, that
is what the driver core provides for you.  I don't see why you need to
implement something that sits next to it and not just use what we
already have here.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 02/11] drivers/base: Add hotplug framework code
  2012-12-13  4:02     ` Toshi Kani
@ 2012-12-13  4:24       ` Greg KH
  2012-12-13 16:30         ` Toshi Kani
  0 siblings, 1 reply; 30+ messages in thread
From: Greg KH @ 2012-12-13  4:24 UTC (permalink / raw)
  To: Toshi Kani
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Wed, Dec 12, 2012 at 09:02:45PM -0700, Toshi Kani wrote:
> On Wed, 2012-12-12 at 15:54 -0800, Greg KH wrote:
> > On Wed, Dec 12, 2012 at 04:17:14PM -0700, Toshi Kani wrote:
> > > Added hotplug.c, which is the hotplug framework code.
> > 
> > Again, better naming please.
> 
> Yes, I will change it to be more specific, something like
> "sys_hotplug.c".

Ugh, what's wrong with just a simple "system_bus.c" or something like
that, and then put all of the needed system bus logic in there and tie
the cpus and other sysdev code into that?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 00/11] Hot-plug and Online/Offline framework
  2012-12-13  4:16         ` Greg KH
@ 2012-12-13 16:03           ` Toshi Kani
  2012-12-13 18:30             ` Greg KH
  0 siblings, 1 reply; 30+ messages in thread
From: Toshi Kani @ 2012-12-13 16:03 UTC (permalink / raw)
  To: Greg KH
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Thu, 2012-12-13 at 04:16 +0000, Greg KH wrote:
> On Wed, Dec 12, 2012 at 08:37:44PM -0700, Toshi Kani wrote:
> > On Wed, 2012-12-12 at 16:55 -0800, Greg KH wrote:
> > > On Wed, Dec 12, 2012 at 05:39:36PM -0700, Toshi Kani wrote:
> > > > On Wed, 2012-12-12 at 15:56 -0800, Greg KH wrote:
> > > > > On Wed, Dec 12, 2012 at 04:17:12PM -0700, Toshi Kani wrote:
> > > > > > This patchset is an initial prototype of proposed hot-plug framework
> > > > > > for design review.  The hot-plug framework is designed to provide 
> > > > > > the common framework for hot-plugging and online/offline operations
> > > > > > of system devices, such as CPU, Memory and Node.  While this patchset
> > > > > > only supports ACPI-based hot-plug operations, the framework itself is
> > > > > > designed to be platform-neural and can support other FW architectures
> > > > > > as necessary.
> > > > > > 
> > > > > > The patchset has not been fully tested yet, esp. for memory hot-plug.
> > > > > > Any help for testing will be very appreciated since my test setup
> > > > > > is limited.
> > > > > > 
> > > > > > The patchset is based on the linux-next branch of linux-pm.git tree.
> > > > > > 
> > > > > > Overview of the Framework
> > > > > > =========================
> > > > > 
> > > > > <snip>
> > > > > 
> > > > > Why all the new framework, doesn't the existing bus infrastructure
> > > > > provide everything you need here?  Shouldn't you just be putting your
> > > > > cpus and memory sticks on a bus and handle stuff that way?  What makes
> > > > > these types of devices so unique from all other devices that Linux has
> > > > > been handling in a dynamic manner (i.e. hotplugging them) for many many
> > > > > years?
> > > > > 
> > > > > Why are you reinventing the wheel?
> > > > 
> > > > Good question.  Yes, USB and PCI hotplug operate based on their bus
> > > > structures.  USB and PCI cards only work under USB and PCI bus
> > > > controllers.  So, their framework can be composed within the bus
> > > > structures as you pointed out.
> > > > 
> > > > However, system devices such CPU and memory do not have their standard
> > > > bus.  ACPI allows these system devices to be enumerated, but it does not
> > > > make ACPI as the HW bus hierarchy for CPU and memory, unlike PCI and
> > > > USB.  Therefore, CPU and memory modules manage CPU and memory outside of
> > > > ACPI.  This makes sense because CPU and memory can be used without ACPI.
> > > > 
> > > > This leads us an issue when we try to manage system device hotplug
> > > > within ACPI, because ACPI does not control everything.  This patchset
> > > > provides a common hotplug framework for system devices, which both ACPI
> > > > and non-ACPI modules (i.e. CPU and memory modules) can participate and
> > > > are coordinated for their hotplug operations.  This is analogous to the
> > > > boot-up sequence, which ACPI and non-ACPI modules can participate to
> > > > enable CPU and memory.
> > > 
> > > Then create a "virtual" bus and put the devices you wish to control on
> > > that.  That is what the "system bus" devices were supposed to be, it's
> > > about time someone took that code and got it all working properly in
> > > this way, that is why it was created oh so long ago.
> > 
> > It may be the ideal, but it will take us great effort to make such
> > things to happen based on where we are now.  It is going to be a long
> > way.  I believe the first step is to make the boot-up flow and hot-plug
> > flow consistent for system devices.  This is what this patchset is
> > trying to do.
> 
> If you use the system "bus" for this, the "flow" will be identical, that
> is what the driver core provides for you.  I don't see why you need to
> implement something that sits next to it and not just use what we
> already have here.

Here is very brief boot-up flow.  

start_kernel()
  boot_cpu_init()         // init cpu0
  setup_arch()
    x86_init.paging.pagetable_init() // init mem pagetable
  :
kernel_init()
  kernel_init_freeable()
    smp_init()            // init other CPUs
      :
    do_basic_setup()
      driver_init()
        cpu_dev_init()    // build system/cpu tree
        memory_dev_init() // build system/memory tree
      do_initcalls()
        acpi_init()       // build ACPI device tree

CPU and memory are initialized at early boot.  The system device tree is
built at the last step of the boot sequence and is only used for
providing sysfs interfaces.  That is, the system bus structure has
nothing to do with the actual CPU and memory initialization at boot.
Similarly, ACPI drivers do not initialize actual CPU and memory at boot
as they are also called at the last step.  Further, the ACPI device tree
and system bus tree are separate entities.  Hotplug events are sent to
ACPI.

In order to keep the boot flow and hotplug flow consistent, I believe
the first step is to keep the role of modules consistent between boot
and hotplug.  For instance, acpi_init() only builds ACPI tree at boot,
so ACPI should only build ACPI tree at hot-add as well.  This keeps ACPI
drivers to do the same for both boot and hot-add.  The framework is
designed to provide the consistency along with other high-availability
features such as rollback.

Thanks,
-Toshi


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 02/11] drivers/base: Add hotplug framework code
  2012-12-13  4:24       ` Greg KH
@ 2012-12-13 16:30         ` Toshi Kani
  2012-12-13 18:24           ` Greg KH
  0 siblings, 1 reply; 30+ messages in thread
From: Toshi Kani @ 2012-12-13 16:30 UTC (permalink / raw)
  To: Greg KH
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Thu, 2012-12-13 at 04:24 +0000, Greg KH wrote:
> On Wed, Dec 12, 2012 at 09:02:45PM -0700, Toshi Kani wrote:
> > On Wed, 2012-12-12 at 15:54 -0800, Greg KH wrote:
> > > On Wed, Dec 12, 2012 at 04:17:14PM -0700, Toshi Kani wrote:
> > > > Added hotplug.c, which is the hotplug framework code.
> > > 
> > > Again, better naming please.
> > 
> > Yes, I will change it to be more specific, something like
> > "sys_hotplug.c".
> 
> Ugh, what's wrong with just a simple "system_bus.c" or something like
> that, and then put all of the needed system bus logic in there and tie
> the cpus and other sysdev code into that?

The issue is that the framework does not provide the system bus
structure.  This is because the system bus structure is not used for CPU
and memory initialization at boot (as I explained in my other email).
The framework manages the calling sequence of hotplug operations, which
is similar to the boot sequence managed by start_kernel(),
kernel_init(), do_initcalls(), etc.  In such sense, this file might not
be a good fit for drivers/base, but I could not find a better place for
it.

Thanks,
-Toshi



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 02/11] drivers/base: Add hotplug framework code
  2012-12-13 16:30         ` Toshi Kani
@ 2012-12-13 18:24           ` Greg KH
  2012-12-14  1:59             ` Toshi Kani
  0 siblings, 1 reply; 30+ messages in thread
From: Greg KH @ 2012-12-13 18:24 UTC (permalink / raw)
  To: Toshi Kani
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Thu, Dec 13, 2012 at 09:30:51AM -0700, Toshi Kani wrote:
> On Thu, 2012-12-13 at 04:24 +0000, Greg KH wrote:
> > On Wed, Dec 12, 2012 at 09:02:45PM -0700, Toshi Kani wrote:
> > > On Wed, 2012-12-12 at 15:54 -0800, Greg KH wrote:
> > > > On Wed, Dec 12, 2012 at 04:17:14PM -0700, Toshi Kani wrote:
> > > > > Added hotplug.c, which is the hotplug framework code.
> > > > 
> > > > Again, better naming please.
> > > 
> > > Yes, I will change it to be more specific, something like
> > > "sys_hotplug.c".
> > 
> > Ugh, what's wrong with just a simple "system_bus.c" or something like
> > that, and then put all of the needed system bus logic in there and tie
> > the cpus and other sysdev code into that?
> 
> The issue is that the framework does not provide the system bus
> structure.  This is because the system bus structure is not used for CPU
> and memory initialization at boot (as I explained in my other email).

I understand, please fix that and then you will not have these issues :)

> The framework manages the calling sequence of hotplug operations, which
> is similar to the boot sequence managed by start_kernel(),
> kernel_init(), do_initcalls(), etc.  In such sense, this file might not
> be a good fit for drivers/base, but I could not find a better place for
> it.

Having "similar but slightly different" isn't a good way to do things,
and I think you are trying to solve that problem here, so converting
everything to use the driver model properly will solve these issues for
you, right?

I _really_ don't want to see yet-another-way-to-do-things be created at
all, unless it really really really is special and different for some
reason.  So far, I have yet to be convinced, especially given that your
reasoning for doing this seems to be "to do it correctly would be too
much work so I created another interface".  That isn't going to fly,
sorry.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 00/11] Hot-plug and Online/Offline framework
  2012-12-13 16:03           ` Toshi Kani
@ 2012-12-13 18:30             ` Greg KH
  2012-12-14  1:51               ` Toshi Kani
  0 siblings, 1 reply; 30+ messages in thread
From: Greg KH @ 2012-12-13 18:30 UTC (permalink / raw)
  To: Toshi Kani
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Thu, Dec 13, 2012 at 09:03:54AM -0700, Toshi Kani wrote:
> On Thu, 2012-12-13 at 04:16 +0000, Greg KH wrote:
> > On Wed, Dec 12, 2012 at 08:37:44PM -0700, Toshi Kani wrote:
> > > On Wed, 2012-12-12 at 16:55 -0800, Greg KH wrote:
> > > > On Wed, Dec 12, 2012 at 05:39:36PM -0700, Toshi Kani wrote:
> > > > > On Wed, 2012-12-12 at 15:56 -0800, Greg KH wrote:
> > > > > > On Wed, Dec 12, 2012 at 04:17:12PM -0700, Toshi Kani wrote:
> > > > > > > This patchset is an initial prototype of proposed hot-plug framework
> > > > > > > for design review.  The hot-plug framework is designed to provide 
> > > > > > > the common framework for hot-plugging and online/offline operations
> > > > > > > of system devices, such as CPU, Memory and Node.  While this patchset
> > > > > > > only supports ACPI-based hot-plug operations, the framework itself is
> > > > > > > designed to be platform-neural and can support other FW architectures
> > > > > > > as necessary.
> > > > > > > 
> > > > > > > The patchset has not been fully tested yet, esp. for memory hot-plug.
> > > > > > > Any help for testing will be very appreciated since my test setup
> > > > > > > is limited.
> > > > > > > 
> > > > > > > The patchset is based on the linux-next branch of linux-pm.git tree.
> > > > > > > 
> > > > > > > Overview of the Framework
> > > > > > > =========================
> > > > > > 
> > > > > > <snip>
> > > > > > 
> > > > > > Why all the new framework, doesn't the existing bus infrastructure
> > > > > > provide everything you need here?  Shouldn't you just be putting your
> > > > > > cpus and memory sticks on a bus and handle stuff that way?  What makes
> > > > > > these types of devices so unique from all other devices that Linux has
> > > > > > been handling in a dynamic manner (i.e. hotplugging them) for many many
> > > > > > years?
> > > > > > 
> > > > > > Why are you reinventing the wheel?
> > > > > 
> > > > > Good question.  Yes, USB and PCI hotplug operate based on their bus
> > > > > structures.  USB and PCI cards only work under USB and PCI bus
> > > > > controllers.  So, their framework can be composed within the bus
> > > > > structures as you pointed out.
> > > > > 
> > > > > However, system devices such CPU and memory do not have their standard
> > > > > bus.  ACPI allows these system devices to be enumerated, but it does not
> > > > > make ACPI as the HW bus hierarchy for CPU and memory, unlike PCI and
> > > > > USB.  Therefore, CPU and memory modules manage CPU and memory outside of
> > > > > ACPI.  This makes sense because CPU and memory can be used without ACPI.
> > > > > 
> > > > > This leads us an issue when we try to manage system device hotplug
> > > > > within ACPI, because ACPI does not control everything.  This patchset
> > > > > provides a common hotplug framework for system devices, which both ACPI
> > > > > and non-ACPI modules (i.e. CPU and memory modules) can participate and
> > > > > are coordinated for their hotplug operations.  This is analogous to the
> > > > > boot-up sequence, which ACPI and non-ACPI modules can participate to
> > > > > enable CPU and memory.
> > > > 
> > > > Then create a "virtual" bus and put the devices you wish to control on
> > > > that.  That is what the "system bus" devices were supposed to be, it's
> > > > about time someone took that code and got it all working properly in
> > > > this way, that is why it was created oh so long ago.
> > > 
> > > It may be the ideal, but it will take us great effort to make such
> > > things to happen based on where we are now.  It is going to be a long
> > > way.  I believe the first step is to make the boot-up flow and hot-plug
> > > flow consistent for system devices.  This is what this patchset is
> > > trying to do.
> > 
> > If you use the system "bus" for this, the "flow" will be identical, that
> > is what the driver core provides for you.  I don't see why you need to
> > implement something that sits next to it and not just use what we
> > already have here.
> 
> Here is very brief boot-up flow.  
> 
> start_kernel()
>   boot_cpu_init()         // init cpu0
>   setup_arch()
>     x86_init.paging.pagetable_init() // init mem pagetable
>   :
> kernel_init()
>   kernel_init_freeable()
>     smp_init()            // init other CPUs
>       :
>     do_basic_setup()
>       driver_init()
>         cpu_dev_init()    // build system/cpu tree
>         memory_dev_init() // build system/memory tree
>       do_initcalls()
>         acpi_init()       // build ACPI device tree
> 
> CPU and memory are initialized at early boot.  The system device tree is
> built at the last step of the boot sequence and is only used for
> providing sysfs interfaces.

Then fix that and create the system device tree earlier.

> That is, the system bus structure has nothing to do with the actual
> CPU and memory initialization at boot.

Then that should be fixed, right?

> Similarly, ACPI drivers do not initialize actual CPU and memory at boot
> as they are also called at the last step.

That should also probably be fixed, right?

> Further, the ACPI device tree and system bus tree are separate
> entities.

That's because ACPI seems to be getting crazy these days, and creating
lots of different devices and tieing it back into the existing device
trees.  Which is fine, see how it's being done with USB for one example
of how this can be done correctly, _if_ you want to keep them separate
(doing so is your own choice, nothing that I'm saying is necessary.)

> Hotplug events are sent to ACPI.

Your hotplug events are being sent there, that's your decision to do so,
it doesn't happen that way with other subsystems that get hotplug events
from ACPI (i.e. PCI hotplug, right?)

> In order to keep the boot flow and hotplug flow consistent, I believe
> the first step is to keep the role of modules consistent between boot
> and hotplug.

I agree, see above for how to resolve that :)

> For instance, acpi_init() only builds ACPI tree at boot, so ACPI
> should only build ACPI tree at hot-add as well.  This keeps ACPI
> drivers to do the same for both boot and hot-add.

Agreed.

> The framework is designed to provide the consistency along with other
> high-availability features such as rollback.

I want my tiny, USB-powered device to have "high-availability", don't
think of that type of functionality as somehow being special, it's what
we have been doing with other subsystems for _years_ now.

Again, I think if you properly tie the system bus code into the CPU work
at the correct location, you can achieve everything you need.  I base
this on the fact that this is what other subsystems and architectures
have been doing for years.  Just because this is ACPI is no reason to
think that it needs to be done differently.

Odds are, s390 has been doing this for 10+ years and none of us realize
this, they are usually that far ahead of the curve if history is any
lesson.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 00/11] Hot-plug and Online/Offline framework
  2012-12-13 18:30             ` Greg KH
@ 2012-12-14  1:51               ` Toshi Kani
  0 siblings, 0 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-14  1:51 UTC (permalink / raw)
  To: Greg KH
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat, linux-s390, linuxppc-dev

On Thu, 2012-12-13 at 10:30 -0800, Greg KH wrote:
> On Thu, Dec 13, 2012 at 09:03:54AM -0700, Toshi Kani wrote:
> > On Thu, 2012-12-13 at 04:16 +0000, Greg KH wrote:
> > > On Wed, Dec 12, 2012 at 08:37:44PM -0700, Toshi Kani wrote:
> > > > On Wed, 2012-12-12 at 16:55 -0800, Greg KH wrote:
> > > > > On Wed, Dec 12, 2012 at 05:39:36PM -0700, Toshi Kani wrote:
> > > > > > On Wed, 2012-12-12 at 15:56 -0800, Greg KH wrote:
> > > > > > > On Wed, Dec 12, 2012 at 04:17:12PM -0700, Toshi Kani wrote:
> > > > > > > > This patchset is an initial prototype of proposed hot-plug framework
> > > > > > > > for design review.  The hot-plug framework is designed to provide 
> > > > > > > > the common framework for hot-plugging and online/offline operations
> > > > > > > > of system devices, such as CPU, Memory and Node.  While this patchset
> > > > > > > > only supports ACPI-based hot-plug operations, the framework itself is
> > > > > > > > designed to be platform-neural and can support other FW architectures
> > > > > > > > as necessary.
> > > > > > > > 
> > > > > > > > The patchset has not been fully tested yet, esp. for memory hot-plug.
> > > > > > > > Any help for testing will be very appreciated since my test setup
> > > > > > > > is limited.
> > > > > > > > 
> > > > > > > > The patchset is based on the linux-next branch of linux-pm.git tree.
> > > > > > > > 
> > > > > > > > Overview of the Framework
> > > > > > > > =========================
> > > > > > > 
> > > > > > > <snip>
> > > > > > > 
> > > > > > > Why all the new framework, doesn't the existing bus infrastructure
> > > > > > > provide everything you need here?  Shouldn't you just be putting your
> > > > > > > cpus and memory sticks on a bus and handle stuff that way?  What makes
> > > > > > > these types of devices so unique from all other devices that Linux has
> > > > > > > been handling in a dynamic manner (i.e. hotplugging them) for many many
> > > > > > > years?
> > > > > > > 
> > > > > > > Why are you reinventing the wheel?
> > > > > > 
> > > > > > Good question.  Yes, USB and PCI hotplug operate based on their bus
> > > > > > structures.  USB and PCI cards only work under USB and PCI bus
> > > > > > controllers.  So, their framework can be composed within the bus
> > > > > > structures as you pointed out.
> > > > > > 
> > > > > > However, system devices such CPU and memory do not have their standard
> > > > > > bus.  ACPI allows these system devices to be enumerated, but it does not
> > > > > > make ACPI as the HW bus hierarchy for CPU and memory, unlike PCI and
> > > > > > USB.  Therefore, CPU and memory modules manage CPU and memory outside of
> > > > > > ACPI.  This makes sense because CPU and memory can be used without ACPI.
> > > > > > 
> > > > > > This leads us an issue when we try to manage system device hotplug
> > > > > > within ACPI, because ACPI does not control everything.  This patchset
> > > > > > provides a common hotplug framework for system devices, which both ACPI
> > > > > > and non-ACPI modules (i.e. CPU and memory modules) can participate and
> > > > > > are coordinated for their hotplug operations.  This is analogous to the
> > > > > > boot-up sequence, which ACPI and non-ACPI modules can participate to
> > > > > > enable CPU and memory.
> > > > > 
> > > > > Then create a "virtual" bus and put the devices you wish to control on
> > > > > that.  That is what the "system bus" devices were supposed to be, it's
> > > > > about time someone took that code and got it all working properly in
> > > > > this way, that is why it was created oh so long ago.
> > > > 
> > > > It may be the ideal, but it will take us great effort to make such
> > > > things to happen based on where we are now.  It is going to be a long
> > > > way.  I believe the first step is to make the boot-up flow and hot-plug
> > > > flow consistent for system devices.  This is what this patchset is
> > > > trying to do.
> > > 
> > > If you use the system "bus" for this, the "flow" will be identical, that
> > > is what the driver core provides for you.  I don't see why you need to
> > > implement something that sits next to it and not just use what we
> > > already have here.
> > 
> > Here is very brief boot-up flow.  
> > 
> > start_kernel()
> >   boot_cpu_init()         // init cpu0
> >   setup_arch()
> >     x86_init.paging.pagetable_init() // init mem pagetable
> >   :
> > kernel_init()
> >   kernel_init_freeable()
> >     smp_init()            // init other CPUs
> >       :
> >     do_basic_setup()
> >       driver_init()
> >         cpu_dev_init()    // build system/cpu tree
> >         memory_dev_init() // build system/memory tree
> >       do_initcalls()
> >         acpi_init()       // build ACPI device tree
> > 
> > CPU and memory are initialized at early boot.  The system device tree is
> > built at the last step of the boot sequence and is only used for
> > providing sysfs interfaces.
> 
> Then fix that and create the system device tree earlier.

# I added ppc and s390 to the list as you suggested... and because
# I may be wrong in my code reading...  This thread is:
# https://lkml.org/lkml/2012/12/13/452

I looked at s390 and powerpc hotplug code.  Their boot flow is
consistent as above since most of the funcs above are actually common.

For hotplug, pSeries (powerpc) supports CPU, Memory and I/O hotplug.
s390 seems to support less capability, so I looked at pSeries mostly.

pSeries supports DLPAR, and all hotplug code is put under
pSeries-specific code, such as arch/powerpc/platforms/pseries/dlpar.c.
The code is implemented outside of the OF module.  Therefore, I think
the OF module itself works consistently at boot and hot-add.  It has its
own hotplug framework with pSeries_reconfig_chain, which calls all
registered handlers for reconfig events.

So, it looks to me that pSeries has somewhat a similar framework, but
put everything under pSeries specific code.  pSeries and s390 hotplug
implementations do not use the bus structure you suggested, either.


> > That is, the system bus structure has nothing to do with the actual
> > CPU and memory initialization at boot.
> 
> Then that should be fixed, right?

The boot-up sequence is shared by all architectures, and it is nearly
impossible to make such changes to work on all architectures.


> > Similarly, ACPI drivers do not initialize actual CPU and memory at boot
> > as they are also called at the last step.
> 
> That should also probably be fixed, right?

Since the boot flow is consistent for all architectures, I do not think
other FW modules initialize CPU and memory, either.


> > Further, the ACPI device tree and system bus tree are separate
> > entities.
> 
> That's because ACPI seems to be getting crazy these days, and creating
> lots of different devices and tieing it back into the existing device
> trees.  Which is fine, see how it's being done with USB for one example
> of how this can be done correctly, _if_ you want to keep them separate
> (doing so is your own choice, nothing that I'm saying is necessary.)
> 
> > Hotplug events are sent to ACPI.
> 
> Your hotplug events are being sent there, that's your decision to do so,
> it doesn't happen that way with other subsystems that get hotplug events
> from ACPI (i.e. PCI hotplug, right?)

ACPICA sends a notification to an ACPI notify handler, so it has to go
with ACPI.  The "system/cpu" and "system/memory" sysfs drivers are
platform neutral and do not depend on ACPI.  PCIe hotplug is based on
PCIe spec, and does not use ACPI.  ACPI PCI hotplug (for PCIx) uses ACPI
and its notification is sent to an ACPI notify handler. 


> > In order to keep the boot flow and hotplug flow consistent, I believe
> > the first step is to keep the role of modules consistent between boot
> > and hotplug.
> 
> I agree, see above for how to resolve that :)
>
> > For instance, acpi_init() only builds ACPI tree at boot, so ACPI
> > should only build ACPI tree at hot-add as well.  This keeps ACPI
> > drivers to do the same for both boot and hot-add.
> 
> Agreed.

Great!  Yes, we just need to agree on a solution. :)


> > The framework is designed to provide the consistency along with other
> > high-availability features such as rollback.
> 
> I want my tiny, USB-powered device to have "high-availability", don't
> think of that type of functionality as somehow being special, it's what
> we have been doing with other subsystems for _years_ now.
> 
> Again, I think if you properly tie the system bus code into the CPU work
> at the correct location, you can achieve everything you need.  I base
> this on the fact that this is what other subsystems and architectures
> have been doing for years.  Just because this is ACPI is no reason to
> think that it needs to be done differently.
> 
> Odds are, s390 has been doing this for 10+ years and none of us realize
> this, they are usually that far ahead of the curve if history is any
> lesson.

I looked at pSeries and s390, and they have their own framework.  Their
cases are also unique because their implementations are tied with
specific platforms / products.  In high-level, however, their approach
is similar to mine.  I have also worked on hotplug for years on other
OS, so I am not coming from nowhere, either. :)

If your concern is having a common hotplug framework, I can try to
address it by putting this framework under ACPI.  This makes it less
capable/cleaner, but it keeps it within ACPI.  That makes it more
similar to how pSeries and s390 did.

Thanks,
-Toshi



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH 02/11] drivers/base: Add hotplug framework code
  2012-12-13 18:24           ` Greg KH
@ 2012-12-14  1:59             ` Toshi Kani
  0 siblings, 0 replies; 30+ messages in thread
From: Toshi Kani @ 2012-12-14  1:59 UTC (permalink / raw)
  To: Greg KH
  Cc: rjw, lenb, akpm, linux-acpi, linux-kernel, linux-mm, bhelgaas,
	isimatu.yasuaki, jiang.liu, wency, guohanjun, yinghai,
	srivatsa.bhat

On Thu, 2012-12-13 at 10:24 -0800, Greg KH wrote:
> On Thu, Dec 13, 2012 at 09:30:51AM -0700, Toshi Kani wrote:
> > On Thu, 2012-12-13 at 04:24 +0000, Greg KH wrote:
> > > On Wed, Dec 12, 2012 at 09:02:45PM -0700, Toshi Kani wrote:
> > > > On Wed, 2012-12-12 at 15:54 -0800, Greg KH wrote:
> > > > > On Wed, Dec 12, 2012 at 04:17:14PM -0700, Toshi Kani wrote:
> > > > > > Added hotplug.c, which is the hotplug framework code.
> > > > > 
> > > > > Again, better naming please.
> > > > 
> > > > Yes, I will change it to be more specific, something like
> > > > "sys_hotplug.c".
> > > 
> > > Ugh, what's wrong with just a simple "system_bus.c" or something like
> > > that, and then put all of the needed system bus logic in there and tie
> > > the cpus and other sysdev code into that?
> > 
> > The issue is that the framework does not provide the system bus
> > structure.  This is because the system bus structure is not used for CPU
> > and memory initialization at boot (as I explained in my other email).
> 
> I understand, please fix that and then you will not have these issues :)
> 
> > The framework manages the calling sequence of hotplug operations, which
> > is similar to the boot sequence managed by start_kernel(),
> > kernel_init(), do_initcalls(), etc.  In such sense, this file might not
> > be a good fit for drivers/base, but I could not find a better place for
> > it.
> 
> Having "similar but slightly different" isn't a good way to do things,
> and I think you are trying to solve that problem here, so converting
> everything to use the driver model properly will solve these issues for
> you, right?
> 
> I _really_ don't want to see yet-another-way-to-do-things be created at
> all, unless it really really really is special and different for some
> reason.  So far, I have yet to be convinced, especially given that your
> reasoning for doing this seems to be "to do it correctly would be too
> much work so I created another interface".  That isn't going to fly,
> sorry.

Let's continue to discuss on other thread since I copied s390 and ppc
folks on that one.

Thanks,
-Toshi


^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2012-12-14  2:08 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-12 23:17 [RFC PATCH 00/11] Hot-plug and Online/Offline framework Toshi Kani
2012-12-12 23:17 ` [RFC PATCH 01/11] Add hotplug.h for hotplug framework Toshi Kani
2012-12-12 23:53   ` Greg KH
2012-12-13  3:56     ` Toshi Kani
2012-12-12 23:17 ` [RFC PATCH 02/11] drivers/base: Add hotplug framework code Toshi Kani
2012-12-12 23:54   ` Greg KH
2012-12-13  4:02     ` Toshi Kani
2012-12-13  4:24       ` Greg KH
2012-12-13 16:30         ` Toshi Kani
2012-12-13 18:24           ` Greg KH
2012-12-14  1:59             ` Toshi Kani
2012-12-12 23:55   ` Greg KH
2012-12-13  3:58     ` Toshi Kani
2012-12-12 23:17 ` [RFC PATCH 03/11] cpu: Add cpu hotplug handlers Toshi Kani
2012-12-12 23:17 ` [RFC PATCH 04/11] mm: Add memory " Toshi Kani
2012-12-12 23:17 ` [RFC PATCH 05/11] ACPI: Add ACPI bus " Toshi Kani
2012-12-12 23:17 ` [RFC PATCH 06/11] ACPI: Add ACPI resource hotplug handler Toshi Kani
2012-12-12 23:17 ` [RFC PATCH 07/11] ACPI: Update processor driver for hotplug framework Toshi Kani
2012-12-12 23:17 ` [RFC PATCH 08/11] ACPI: Update memory " Toshi Kani
2012-12-12 23:17 ` [RFC PATCH 09/11] ACPI: Update container " Toshi Kani
2012-12-12 23:17 ` [RFC PATCH 10/11] cpu: Update sysfs cpu/online " Toshi Kani
2012-12-12 23:17 ` [RFC PATCH 11/11] ACPI: Update sysfs eject " Toshi Kani
2012-12-12 23:56 ` [RFC PATCH 00/11] Hot-plug and Online/Offline framework Greg KH
2012-12-13  0:39   ` Toshi Kani
2012-12-13  0:55     ` Greg KH
2012-12-13  3:37       ` Toshi Kani
2012-12-13  4:16         ` Greg KH
2012-12-13 16:03           ` Toshi Kani
2012-12-13 18:30             ` Greg KH
2012-12-14  1:51               ` Toshi Kani

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).