Re: [PATCH] ehea: Fix memory hotplug support

2008-10-16 Thread Jeff Garzik

Hannes Hering wrote:

This patch implements the memory notifier to update the busmap instantly
instead of rebuilding the whole map. This is necessary because
walk_memory_resource provides different information than required during memory
hotplug.

Signed-off-by: Hannes Hering [EMAIL PROTECTED]
---
This patch is based on the current netdev-2.6-git. It supersedes the previous
post ehea: Fix memory hotplug support.
http://www.spinics.net/lists/netdev/msg75413.html


Due to vacation, netdev-2.6.git is stale.  Please regenerate this patch 
against davem's net-2.6.git.


Jeff



___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


[PATCH] ehea: Fix memory hotplug support

2008-10-16 Thread Hannes Hering
This patch implements the memory notifier to update the busmap instantly
instead of rebuilding the whole map. This is necessary because
walk_memory_resource provides different information than required during memory
hotplug.

Signed-off-by: Hannes Hering [EMAIL PROTECTED]
---
Jeff, as requested, this patch is now based on davem's net-2.6.git.

diff -Nurp -X dontdiff linux-2.6.27/drivers/net/ehea/ehea.h 
patched_kernel/drivers/net/ehea/ehea.h
--- linux-2.6.27/drivers/net/ehea/ehea.h2008-10-16 11:22:15.0 
+0200
+++ patched_kernel/drivers/net/ehea/ehea.h  2008-10-16 11:23:00.646563117 
+0200
@@ -40,7 +40,7 @@
 #include asm/io.h
 
 #define DRV_NAME   ehea
-#define DRV_VERSIONEHEA_0093
+#define DRV_VERSIONEHEA_0094
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
diff -Nurp -X dontdiff linux-2.6.27/drivers/net/ehea/ehea_main.c 
patched_kernel/drivers/net/ehea/ehea_main.c
--- linux-2.6.27/drivers/net/ehea/ehea_main.c   2008-10-16 11:22:15.0 
+0200
+++ patched_kernel/drivers/net/ehea/ehea_main.c 2008-10-16 11:23:00.646563117 
+0200
@@ -2863,7 +2863,7 @@ static void ehea_rereg_mrs(struct work_s
struct ehea_adapter *adapter;
 
mutex_lock(dlpar_mem_lock);
-   ehea_info(LPAR memory enlarged - re-initializing driver);
+   ehea_info(LPAR memory changed - re-initializing driver);
 
list_for_each_entry(adapter, adapter_list, list)
if (adapter-active_ports) {
@@ -2900,13 +2900,6 @@ static void ehea_rereg_mrs(struct work_s
}
}
 
-   ehea_destroy_busmap();
-   ret = ehea_create_busmap();
-   if (ret) {
-   ehea_error(creating ehea busmap failed);
-   goto out;
-   }
-
clear_bit(__EHEA_STOP_XFER, ehea_driver_flags);
 
list_for_each_entry(adapter, adapter_list, list)
@@ -3519,9 +3512,21 @@ void ehea_crash_handler(void)
 static int ehea_mem_notifier(struct notifier_block *nb,
  unsigned long action, void *data)
 {
+   struct memory_notify *arg = data;
switch (action) {
-   case MEM_OFFLINE:
-   ehea_info(memory has been removed);
+   case MEM_CANCEL_OFFLINE:
+   ehea_info(memory offlining canceled);
+   /* Readd canceled memory block */
+   case MEM_ONLINE:
+   ehea_info(memory is going online);
+   if (ehea_add_sect_bmap(arg-start_pfn, arg-nr_pages))
+   return NOTIFY_BAD;
+   ehea_rereg_mrs(NULL);
+   break;
+   case MEM_GOING_OFFLINE:
+   ehea_info(memory is going offline);
+   if (ehea_rem_sect_bmap(arg-start_pfn, arg-nr_pages))
+   return NOTIFY_BAD;
ehea_rereg_mrs(NULL);
break;
default:
diff -Nurp -X dontdiff linux-2.6.27/drivers/net/ehea/ehea_qmr.c 
patched_kernel/drivers/net/ehea/ehea_qmr.c
--- linux-2.6.27/drivers/net/ehea/ehea_qmr.c2008-10-16 11:22:15.0 
+0200
+++ patched_kernel/drivers/net/ehea/ehea_qmr.c  2008-10-16 11:23:00.646563117 
+0200
@@ -567,7 +567,7 @@ static inline int ehea_calc_index(unsign
 static inline int ehea_init_top_bmap(struct ehea_top_bmap *ehea_top_bmap,
 int dir)
 {
-   if(!ehea_top_bmap-dir[dir]) {
+   if (!ehea_top_bmap-dir[dir]) {
ehea_top_bmap-dir[dir] =
kzalloc(sizeof(struct ehea_dir_bmap), GFP_KERNEL);
if (!ehea_top_bmap-dir[dir])
@@ -578,7 +578,7 @@ static inline int ehea_init_top_bmap(str
 
 static inline int ehea_init_bmap(struct ehea_bmap *ehea_bmap, int top, int dir)
 {
-   if(!ehea_bmap-top[top]) {
+   if (!ehea_bmap-top[top]) {
ehea_bmap-top[top] =
kzalloc(sizeof(struct ehea_top_bmap), GFP_KERNEL);
if (!ehea_bmap-top[top])
@@ -587,53 +587,124 @@ static inline int ehea_init_bmap(struct 
return ehea_init_top_bmap(ehea_bmap-top[top], dir);
 }
 
-static int ehea_create_busmap_callback(unsigned long pfn,
-  unsigned long nr_pages, void *arg)
-{
-   unsigned long i, mr_len, start_section, end_section;
-   start_section = (pfn * PAGE_SIZE) / EHEA_SECTSIZE;
-   end_section = start_section + ((nr_pages * PAGE_SIZE) / EHEA_SECTSIZE);
-   mr_len = *(unsigned long *)arg;
+static DEFINE_MUTEX(ehea_busmap_mutex);
+static unsigned long ehea_mr_len;
 
-   if (!ehea_bmap)
-   ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL);
-   if (!ehea_bmap)
-   return -ENOMEM;
+#define EHEA_BUSMAP_ADD_SECT 1
+#define EHEA_BUSMAP_REM_SECT 0
 
-   for (i = start_section; i  end_section; i++) {
-   int ret;
-   int top, dir, idx;
-   u64 vaddr;
+static void ehea_rebuild_busmap(void)
+{
+   u64 vaddr = EHEA_BUSMAP_START;
+   int top, dir, idx;
+
+   for (top 

[PATCH] ehea: Fix memory hotplug support

2008-10-15 Thread Hannes Hering
This patch implements the memory notifier to update the busmap instantly
instead of rebuilding the whole map. This is necessary because
walk_memory_resource provides different information than required during memory
hotplug.

Signed-off-by: Hannes Hering [EMAIL PROTECTED]
---
This patch is based on the current netdev-2.6-git. It supersedes the previous
post ehea: Fix memory hotplug support.
http://www.spinics.net/lists/netdev/msg75413.html

diff -Nurp -X dontdiff linux-2.6.27/drivers/net/ehea/ehea.h 
patched_kernel/drivers/net/ehea/ehea.h
--- linux-2.6.27/drivers/net/ehea/ehea.h2008-10-14 18:26:54.0 
+0200
+++ patched_kernel/drivers/net/ehea/ehea.h  2008-10-15 11:47:23.0 
+0200
@@ -40,13 +40,13 @@
 #include asm/io.h
 
 #define DRV_NAME   ehea
-#define DRV_VERSIONEHEA_0092
+#define DRV_VERSIONEHEA_0094
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
 #define DLPAR_MEM_ADD  2
 #define DLPAR_MEM_REM  4
-#define EHEA_CAPABILITIES  (DLPAR_PORT_ADD_REM | DLPAR_MEM_ADD)
+#define EHEA_CAPABILITIES  (DLPAR_PORT_ADD_REM | DLPAR_MEM_ADD | DLPAR_MEM_REM)
 
 #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
diff -Nurp -X dontdiff linux-2.6.27/drivers/net/ehea/ehea_main.c 
patched_kernel/drivers/net/ehea/ehea_main.c
--- linux-2.6.27/drivers/net/ehea/ehea_main.c   2008-10-14 18:26:54.0 
+0200
+++ patched_kernel/drivers/net/ehea/ehea_main.c 2008-10-15 11:47:23.0 
+0200
@@ -2863,7 +2863,7 @@ static void ehea_rereg_mrs(struct work_s
struct ehea_adapter *adapter;
 
mutex_lock(dlpar_mem_lock);
-   ehea_info(LPAR memory enlarged - re-initializing driver);
+   ehea_info(LPAR memory changed - re-initializing driver);
 
list_for_each_entry(adapter, adapter_list, list)
if (adapter-active_ports) {
@@ -2900,13 +2900,6 @@ static void ehea_rereg_mrs(struct work_s
}
}
 
-   ehea_destroy_busmap();
-   ret = ehea_create_busmap();
-   if (ret) {
-   ehea_error(creating ehea busmap failed);
-   goto out;
-   }
-
clear_bit(__EHEA_STOP_XFER, ehea_driver_flags);
 
list_for_each_entry(adapter, adapter_list, list)
@@ -3519,9 +3512,21 @@ void ehea_crash_handler(void)
 static int ehea_mem_notifier(struct notifier_block *nb,
  unsigned long action, void *data)
 {
+   struct memory_notify *arg = data;
switch (action) {
-   case MEM_OFFLINE:
-   ehea_info(memory has been removed);
+   case MEM_CANCEL_OFFLINE:
+   ehea_info(memory offlining canceled);
+   /* Readd canceled memory block */
+   case MEM_ONLINE:
+   ehea_info(memory is going online);
+   if (ehea_add_sect_bmap(arg-start_pfn, arg-nr_pages))
+   return NOTIFY_BAD;
+   ehea_rereg_mrs(NULL);
+   break;
+   case MEM_GOING_OFFLINE:
+   ehea_info(memory is going offline);
+   if (ehea_rem_sect_bmap(arg-start_pfn, arg-nr_pages))
+   return NOTIFY_BAD;
ehea_rereg_mrs(NULL);
break;
default:
diff -Nurp -X dontdiff linux-2.6.27/drivers/net/ehea/ehea_qmr.c 
patched_kernel/drivers/net/ehea/ehea_qmr.c
--- linux-2.6.27/drivers/net/ehea/ehea_qmr.c2008-10-14 18:26:54.0 
+0200
+++ patched_kernel/drivers/net/ehea/ehea_qmr.c  2008-10-15 11:47:23.0 
+0200
@@ -567,7 +567,7 @@ static inline int ehea_calc_index(unsign
 static inline int ehea_init_top_bmap(struct ehea_top_bmap *ehea_top_bmap,
 int dir)
 {
-   if(!ehea_top_bmap-dir[dir]) {
+   if (!ehea_top_bmap-dir[dir]) {
ehea_top_bmap-dir[dir] =
kzalloc(sizeof(struct ehea_dir_bmap), GFP_KERNEL);
if (!ehea_top_bmap-dir[dir])
@@ -578,7 +578,7 @@ static inline int ehea_init_top_bmap(str
 
 static inline int ehea_init_bmap(struct ehea_bmap *ehea_bmap, int top, int dir)
 {
-   if(!ehea_bmap-top[top]) {
+   if (!ehea_bmap-top[top]) {
ehea_bmap-top[top] =
kzalloc(sizeof(struct ehea_top_bmap), GFP_KERNEL);
if (!ehea_bmap-top[top])
@@ -587,52 +587,124 @@ static inline int ehea_init_bmap(struct 
return ehea_init_top_bmap(ehea_bmap-top[top], dir);
 }
 
-static int ehea_create_busmap_callback(unsigned long pfn,
-  unsigned long nr_pages, void *arg)
-{
-   unsigned long i, mr_len, start_section, end_section;
-   start_section = (pfn * PAGE_SIZE) / EHEA_SECTSIZE;
-   end_section = start_section + ((nr_pages * PAGE_SIZE) / EHEA_SECTSIZE);
-   mr_len = *(unsigned long *)arg;
+static DEFINE_MUTEX(ehea_busmap_mutex);
+static unsigned long ehea_mr_len;
 
-   ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL);
-