On Wed, 8 Oct 2014 16:36:25 +0800 zhanghailiang <zhang.zhanghaili...@huawei.com> wrote:
> On 2014/10/8 15:28, zhanghailiang wrote: > > Hi Igor, > > > > On 2014/9/26 19:53, Igor Mammedov wrote: > >> On Tue, 23 Sep 2014 16:11:25 +0800 > >> zhanghailiang <zhang.zhanghaili...@huawei.com> wrote: > >> > >>> When do memory hotplug, if there is numa node, we should add > >>> the memory size to the corresponding node memory size. > >>> > >>> For now, it mainly affects the result of hmp command "info numa". > >>> > >>> Signed-off-by: zhanghailiang <zhang.zhanghaili...@huawei.com> > >> please make sure that this doesn't breaks other targets. > >> > >> PS: > >> to make test builds you can use travis-ci.org+github service > >> > > > > Sorry for the delayed response.;) > > > > I have test the build as you suggested, and yes, it will break other > > targets. > > > > The main reason here is, there is a compile switch for > > memory hotplug (CONFIG_MEM_HOTPLUG), which is off for other targets, and > > pc-dimm.c is not include when compile. > > > > Here i also use the compile switch to fix this problem, and will send V4. > > > > ): Actually this macro (CONFIG_MEM_HOTPLUG) can't be automatically generated > like CONFIG_KVM in config-target.h, so i can't use this compile macro. > > What's your suggestion? Thanks! typically we add stab function in such cases. However looking at pc_dimm_stat_node_mem() it does nothing that requires access to PCDIMMDevice, i.e. size and node could be accessed as properties of Device/Object. I'd suggest to generalize pc_dimm_stat_node_mem() so it could in future handle other types of memory devices and place it in numa.c, but for now looking only for TYPE_PC_DIMM devices. PS: s/pc_dimm_stat_node_mem/numa_stat_memory_devices/ > > zhanghailiang > > >>> --- > >>> v3: > >>> - cold-plugged memory should not be excluded when stat memory size (Igor > >>> Mammedov) > >>> v2: > >>> - Don't modify the numa_info.node_mem directly when treating hotplug > >>> memory, > >>> fix the "info numa" instead (suggested by Igor Mammedov) > >>> --- > >>> hw/mem/pc-dimm.c | 30 ++++++++++++++++++++++++++++++ > >>> include/hw/mem/pc-dimm.h | 2 ++ > >>> include/sysemu/sysemu.h | 1 + > >>> monitor.c | 6 +++++- > >>> numa.c | 15 +++++++++++++++ > >>> 5 files changed, 53 insertions(+), 1 deletion(-) > >>> > >>> diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c > >>> index 5bfc5b7..8e80d74 100644 > >>> --- a/hw/mem/pc-dimm.c > >>> +++ b/hw/mem/pc-dimm.c > >>> @@ -195,6 +195,36 @@ out: > >>> return ret; > >>> } > >>> > >>> +static int pc_dimm_stat_mem_size(Object *obj, void *opaque) > >>> +{ > >>> + uint64_t *node_mem = opaque; > >>> + int ret; > >>> + > >>> + if (object_dynamic_cast(obj, TYPE_PC_DIMM)) { > >>> + DeviceState *dev = DEVICE(obj); > >>> + > >>> + if (dev->realized) { > >>> + PCDIMMDevice *dimm = PC_DIMM(obj); > >>> + int size; > >>> + > >>> + size = object_property_get_int(OBJECT(dimm), > >>> PC_DIMM_SIZE_PROP, > >>> + NULL); > >>> + if (size < 0) { > >>> + return -1; > >>> + } > >>> + node_mem[dimm->node] += size; > >>> + } > >>> + } > >>> + > >>> + ret = object_child_foreach(obj, pc_dimm_stat_mem_size, opaque); > >>> + return ret; > >>> +} > >>> + > >>> +void pc_dimm_stat_node_mem(uint64_t *node_mem) > >>> +{ > >>> + object_child_foreach(qdev_get_machine(), pc_dimm_stat_mem_size, > >>> node_mem); > >>> +} > >>> + > >>> static Property pc_dimm_properties[] = { > >>> DEFINE_PROP_UINT64(PC_DIMM_ADDR_PROP, PCDIMMDevice, addr, 0), > >>> DEFINE_PROP_UINT32(PC_DIMM_NODE_PROP, PCDIMMDevice, node, 0), > >>> diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h > >>> index 761eeef..0c9a8eb 100644 > >>> --- a/include/hw/mem/pc-dimm.h > >>> +++ b/include/hw/mem/pc-dimm.h > >>> @@ -78,4 +78,6 @@ uint64_t pc_dimm_get_free_addr(uint64_t > >>> address_space_start, > >>> int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp); > >>> > >>> int qmp_pc_dimm_device_list(Object *obj, void *opaque); > >>> + > >>> +void pc_dimm_stat_node_mem(uint64_t *node_mem); > >>> #endif > >>> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h > >>> index d8539fd..cfc1592 100644 > >>> --- a/include/sysemu/sysemu.h > >>> +++ b/include/sysemu/sysemu.h > >>> @@ -160,6 +160,7 @@ typedef struct node_info { > >>> extern NodeInfo numa_info[MAX_NODES]; > >>> void set_numa_nodes(void); > >>> void set_numa_modes(void); > >>> +int query_numa_node_mem(uint64_t *node_mem); > >>> extern QemuOptsList qemu_numa_opts; > >>> int numa_init_func(QemuOpts *opts, void *opaque); > >>> > >>> diff --git a/monitor.c b/monitor.c > >>> index 7467521..c8c812f 100644 > >>> --- a/monitor.c > >>> +++ b/monitor.c > >>> @@ -1948,7 +1948,10 @@ static void do_info_numa(Monitor *mon, const QDict > >>> *qdict) > >>> { > >>> int i; > >>> CPUState *cpu; > >>> + uint64_t *node_mem; > >>> > >>> + node_mem = g_new0(uint64_t, nb_numa_nodes); > >>> + query_numa_node_mem(node_mem); > >>> monitor_printf(mon, "%d nodes\n", nb_numa_nodes); > >>> for (i = 0; i < nb_numa_nodes; i++) { > >>> monitor_printf(mon, "node %d cpus:", i); > >>> @@ -1959,8 +1962,9 @@ static void do_info_numa(Monitor *mon, const QDict > >>> *qdict) > >>> } > >>> monitor_printf(mon, "\n"); > >>> monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i, > >>> - numa_info[i].node_mem >> 20); > >>> + node_mem[i] >> 20); > >>> } > >>> + g_free(node_mem); > >>> } > >>> > >>> #ifdef CONFIG_PROFILER > >>> diff --git a/numa.c b/numa.c > >>> index 3b98135..4e27dd8 100644 > >>> --- a/numa.c > >>> +++ b/numa.c > >>> @@ -35,6 +35,7 @@ > >>> #include "hw/boards.h" > >>> #include "sysemu/hostmem.h" > >>> #include "qmp-commands.h" > >>> +#include "hw/mem/pc-dimm.h" > >>> > >>> QemuOptsList qemu_numa_opts = { > >>> .name = "numa", > >>> @@ -315,6 +316,20 @@ void > >>> memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, > >>> } > >>> } > >>> > >>> +int query_numa_node_mem(uint64_t *node_mem) > >>> +{ > >>> + int i; > >>> + > >>> + if (nb_numa_nodes <= 0) { > >>> + return 0; > >>> + } > >>> + pc_dimm_stat_node_mem(node_mem); > >>> + for (i = 0; i < nb_numa_nodes; i++) { > >>> + node_mem[i] += numa_info[i].node_mem; > >>> + } > >>> + return 0; > >>> +} > >>> + > >>> static int query_memdev(Object *obj, void *opaque) > >>> { > >>> MemdevList **list = opaque; > >> > >> > >> . > >> > > > > > > > > > > . > > > >