Re: [PATCH] ehea: Fix memory hotplug support
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
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
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); -