Hi, Anthony is it reasonable split?
在 2013-02-28四的 12:45 +0800,liguang写道: > now, lots of other functions which were not related with > mainloop exist in vl.c, e.g. > > numa related functions (numa_add() ...) > bt related functions (bt_parse() ...) > usb related functions (usb_parse() ...) > gui related functions (gui_update()) > system power related functions (qemu_shutdown_requested() ...) > ... > > they can all be moved out of vl.c by function, > this patch is only a RFC patch, hope > one can help to decide if I can continue > to do clean up work. > > Signed-off-by: liguang <lig.f...@cn.fujitsu.com> > --- > Makefile.objs | 2 + > bt-opts.c | 200 ++++++++++++++++++++++++++++ > bt-opts.h | 13 ++ > cpus.c | 2 +- > hw/pc.c | 10 +- > hw/spapr.c | 6 +- > include/sysemu/sysemu.h | 1 - > monitor.c | 4 +- > numa-opts.c | 166 +++++++++++++++++++++++ > numa-opts.h | 9 ++ > vl.c | 339 > +---------------------------------------------- > 11 files changed, 406 insertions(+), 346 deletions(-) > create mode 100644 bt-opts.c > create mode 100644 bt-opts.h > create mode 100644 numa-opts.c > create mode 100644 numa-opts.h > > diff --git a/Makefile.objs b/Makefile.objs > index a68cdac..4bfc559 100644 > --- a/Makefile.objs > +++ b/Makefile.objs > @@ -73,6 +73,8 @@ common-obj-y += bt-host.o bt-vhci.o > > common-obj-y += dma-helpers.o > common-obj-y += vl.o > +common-obj-y += numa-opts.o > +common-obj-y += bt-opts.o > > common-obj-$(CONFIG_SLIRP) += slirp/ > > diff --git a/bt-opts.c b/bt-opts.c > new file mode 100644 > index 0000000..d34ac62 > --- /dev/null > +++ b/bt-opts.c > @@ -0,0 +1,200 @@ > +#include "bt-opts.h" > +#include "qemu-common.h" > + > + > +static int nb_hcis; > +static int cur_hci; > +static struct HCIInfo *hci_table[MAX_NICS]; > + > +static struct bt_vlan_s { > + struct bt_scatternet_s net; > + int id; > + struct bt_vlan_s *next; > +} *first_bt_vlan; > + > +static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len) > +{ > +} > + > +static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr) > +{ > + return -ENOTSUP; > +} > + > +/* find or alloc a new bluetooth "VLAN" */ > +static struct HCIInfo null_hci = { > + .cmd_send = null_hci_send, > + .sco_send = null_hci_send, > + .acl_send = null_hci_send, > + .bdaddr_set = null_hci_addr_set, > +}; > + > +struct HCIInfo *qemu_next_hci(void) > +{ > + if (cur_hci == nb_hcis) { > + return &null_hci; > + } > + > + return hci_table[cur_hci++]; > +} > + > +struct HCIInfo *hci_init(const char *str) > +{ > + char *endp; > + struct bt_scatternet_s *vlan = 0; > + > + if (!strcmp(str, "null")) { > + /* null */ > + return &null_hci; > + } else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == > ':')) { > + /* host[:hciN] */ > + return bt_host_hci(str[4] ? str + 5 : "hci0"); > + } else if (!strncmp(str, "hci", 3)) { > + /* hci[,vlan=n] */ > + if (str[3]) { > + if (!strncmp(str + 3, ",vlan=", 6)) { > + vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0)); > + if (*endp) { > + vlan = 0; > + } > + } > + } else { > + vlan = qemu_find_bt_vlan(0); > + } > + if (vlan) { > + return bt_new_hci(vlan); > + } > + } > + > + fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str); > + > + return 0; > +} > + > +static int bt_hci_parse(const char *str) > +{ > + struct HCIInfo *hci; > + bdaddr_t bdaddr; > + > + if (nb_hcis >= MAX_NICS) { > + fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", > MAX_NICS); > + return -1; > + } > + > + hci = hci_init(str); > + if (!hci) { > + return -1; > + } > + bdaddr.b[0] = 0x52; > + bdaddr.b[1] = 0x54; > + bdaddr.b[2] = 0x00; > + bdaddr.b[3] = 0x12; > + bdaddr.b[4] = 0x34; > + bdaddr.b[5] = 0x56 + nb_hcis; > + hci->bdaddr_set(hci, bdaddr.b); > + > + hci_table[nb_hcis++] = hci; > + > + return 0; > +} > + > +static void bt_vhci_add(int vlan_id) > +{ > + struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id); > + > + if (!vlan->slave) { > + fprintf(stderr, "qemu: warning: adding a VHCI to " > + "an empty scatternet %i\n", vlan_id); > + } > + > + bt_vhci_init(bt_new_hci(vlan)); > +} > + > +static struct bt_device_s *bt_device_add(const char *opt) > +{ > + struct bt_scatternet_s *vlan; > + int vlan_id = 0; > + char *endp = strstr(opt, ",vlan="); > + int len = (endp ? endp - opt : strlen(opt)) + 1; > + char devname[10]; > + > + pstrcpy(devname, MIN(sizeof(devname), len), opt); > + > + if (endp) { > + vlan_id = strtol(endp + 6, &endp, 0); > + if (*endp) { > + fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n"); > + return 0; > + } > + } > + > + vlan = qemu_find_bt_vlan(vlan_id); > + > + if (!vlan->slave) { > + fprintf(stderr, "qemu: warning: adding a slave device to " > + "an empty scatternet %i\n", vlan_id); > + } > + if (!strcmp(devname, "keyboard")) { > + return bt_keyboard_init(vlan); > + } > + fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname); > + return 0; > +} > + > +struct bt_scatternet_s *qemu_find_bt_vlan(int id) > +{ > + struct bt_vlan_s **pvlan, *vlan; > + for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) { > + if (vlan->id == id) { > + return &vlan->net; > + } > + } > + vlan = g_malloc0(sizeof(struct bt_vlan_s)); > + vlan->id = id; > + pvlan = &first_bt_vlan; > + while (*pvlan != NULL) { > + pvlan = &(*pvlan)->next; > + } > + *pvlan = vlan; > + return &vlan->net; > +} > + > +int bt_parse(const char *opt) > +{ > + const char *endp, *p; > + int vlan; > + > + if (strstart(opt, "hci", &endp)) { > + if (!*endp || *endp == ',') { > + if (*endp) { > + if (!strstart(endp, ",vlan=", 0)) { > + opt = endp + 1; > + } > + } > + return bt_hci_parse(opt); > + } > + } else if (strstart(opt, "vhci", &endp)) { > + if (!*endp || *endp == ',') { > + if (*endp) { > + if (strstart(endp, ",vlan=", &p)) { > + vlan = strtol(p, (char **) &endp, 0); > + if (*endp) { > + fprintf(stderr, "qemu: bad scatternet '%s'\n", p); > + return 1; > + } > + } else { > + fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1); > + return 1; > + } > + } else { > + vlan = 0; > + } > + bt_vhci_add(vlan); > + return 0; > + } > + } else if (strstart(opt, "device:", &endp)) { > + return !bt_device_add(endp); > + } > + fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt); > + return 1; > +} > diff --git a/bt-opts.h b/bt-opts.h > new file mode 100644 > index 0000000..fcd80c1 > --- /dev/null > +++ b/bt-opts.h > @@ -0,0 +1,13 @@ > +#ifndef BT_OPTS_H > +#define BT_OPTS_H > + > +#include "net/net.h" > +#include "bt/bt.h" > +#include "hw/bt.h" > + > +int bt_parse(const char *opt); > +struct HCIInfo *hci_init(const char *str); > +struct bt_scatternet_s *qemu_find_bt_vlan(int id); > + > + > +#endif > diff --git a/cpus.c b/cpus.c > index c4b021d..9f05390 100644 > --- a/cpus.c > +++ b/cpus.c > @@ -1167,7 +1167,7 @@ void set_numa_modes(void) > > for (env = first_cpu; env != NULL; env = env->next_cpu) { > cpu = ENV_GET_CPU(env); > - for (i = 0; i < nb_numa_nodes; i++) { > + for (i = 0; i < get_nr_numa_nodes(); i++) { > if (test_bit(cpu->cpu_index, node_cpumask[i])) { > cpu->numa_node = i; > } > diff --git a/hw/pc.c b/hw/pc.c > index 07caba7..6ea9452 100644 > --- a/hw/pc.c > +++ b/hw/pc.c > @@ -606,23 +606,23 @@ static void *bochs_bios_init(void) > * of nodes, one word for each VCPU->node and one word for each node to > * hold the amount of memory. > */ > - numa_fw_cfg = g_new0(uint64_t, 1 + apic_id_limit + nb_numa_nodes); > - numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes); > + numa_fw_cfg = g_new0(uint64_t, 1 + apic_id_limit + get_nr_numa_nodes()); > + numa_fw_cfg[0] = cpu_to_le64(get_nr_numa_nodes()); > for (i = 0; i < max_cpus; i++) { > unsigned int apic_id = x86_cpu_apic_id_from_index(i); > assert(apic_id < apic_id_limit); > - for (j = 0; j < nb_numa_nodes; j++) { > + for (j = 0; j < get_nr_numa_nodes(); j++) { > if (test_bit(i, node_cpumask[j])) { > numa_fw_cfg[apic_id + 1] = cpu_to_le64(j); > break; > } > } > } > - for (i = 0; i < nb_numa_nodes; i++) { > + for (i = 0; i < get_nr_numa_nodes(); i++) { > numa_fw_cfg[apic_id_limit + 1 + i] = cpu_to_le64(node_mem[i]); > } > fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg, > - (1 + apic_id_limit + nb_numa_nodes) * > + (1 + apic_id_limit + get_nr_numa_nodes()) * > sizeof(*numa_fw_cfg)); > > return fw_cfg; > diff --git a/hw/spapr.c b/hw/spapr.c > index e88a27a..43777f8 100644 > --- a/hw/spapr.c > +++ b/hw/spapr.c > @@ -162,7 +162,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment > *spapr) > return offset; > } > > - if (nb_numa_nodes > 1) { > + if (get_nr_numa_nodes() > 1) { > ret = fdt_setprop(fdt, offset, "ibm,associativity", > associativity, > sizeof(associativity)); > if (ret < 0) { > @@ -453,7 +453,7 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, > void *fdt) > int i, off; > > /* memory node(s) */ > - node0_size = (nb_numa_nodes > 1) ? node_mem[0] : ram_size; > + node0_size = (get_nr_numa_nodes() > 1) ? node_mem[0] : ram_size; > if (spapr->rma_size > node0_size) { > spapr->rma_size = node0_size; > } > @@ -486,7 +486,7 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, > void *fdt) > > /* RAM: Node 1 and beyond */ > mem_start = node0_size; > - for (i = 1; i < nb_numa_nodes; i++) { > + for (i = 1; i < get_nr_numa_nodes(); i++) { > mem_reg_property[0] = cpu_to_be64(mem_start); > mem_reg_property[1] = cpu_to_be64(node_mem[i]); > associativity[3] = associativity[4] = cpu_to_be32(i); > diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h > index b19ec95..1375f3b 100644 > --- a/include/sysemu/sysemu.h > +++ b/include/sysemu/sysemu.h > @@ -128,7 +128,6 @@ extern QEMUClock *rtc_clock; > > #define MAX_NODES 64 > #define MAX_CPUMASK_BITS 255 > -extern int nb_numa_nodes; > extern uint64_t node_mem[MAX_NODES]; > extern unsigned long *node_cpumask[MAX_NODES]; > > diff --git a/monitor.c b/monitor.c > index 32a6e74..1893766 100644 > --- a/monitor.c > +++ b/monitor.c > @@ -1772,8 +1772,8 @@ static void do_info_numa(Monitor *mon, const QDict > *qdict) > CPUArchState *env; > CPUState *cpu; > > - monitor_printf(mon, "%d nodes\n", nb_numa_nodes); > - for (i = 0; i < nb_numa_nodes; i++) { > + monitor_printf(mon, "%d nodes\n", get_nr_numa_nodes()); > + for (i = 0; i < get_nr_numa_nodes(); i++) { > monitor_printf(mon, "node %d cpus:", i); > for (env = first_cpu; env != NULL; env = env->next_cpu) { > cpu = ENV_GET_CPU(env); > diff --git a/numa-opts.c b/numa-opts.c > new file mode 100644 > index 0000000..ae87c2d > --- /dev/null > +++ b/numa-opts.c > @@ -0,0 +1,166 @@ > +#include "numa-opts.h" > +#include "sysemu/sysemu.h" > +#include "qemu-common.h" > +#include "qemu/bitmap.h" > +#include "exec/cpu-common.h" > + > +extern ram_addr_t ram_size; > + > +static int nr_numa_nodes; > +uint64_t node_mem[MAX_NODES]; > +unsigned long *node_cpumask[MAX_NODES]; > + > +int get_nr_numa_nodes(void) > +{ > + return nr_numa_nodes; > +} > + > +void set_nr_numa_nodes(int nr) > +{ > + nr_numa_nodes = nr; > +} > + > +static void numa_node_parse_cpus(int nodenr, const char *cpus) > +{ > + char *endptr; > + unsigned long long value, endvalue; > + > + /* Empty CPU range strings will be considered valid, they will simply > + * not set any bit in the CPU bitmap. > + */ > + if (!*cpus) { > + return; > + } > + > + if (parse_uint(cpus, &value, &endptr, 10) < 0) { > + goto error; > + } > + if (*endptr == '-') { > + if (parse_uint_full(endptr + 1, &endvalue, 10) < 0) { > + goto error; > + } > + } else if (*endptr == '\0') { > + endvalue = value; > + } else { > + goto error; > + } > + > + if (endvalue >= MAX_CPUMASK_BITS) { > + endvalue = MAX_CPUMASK_BITS - 1; > + fprintf(stderr, > + "qemu: NUMA: A max of %d VCPUs are supported\n", > + MAX_CPUMASK_BITS); > + } > + > + if (endvalue < value) { > + goto error; > + } > + > + bitmap_set(node_cpumask[nodenr], value, endvalue-value+1); > + return; > + > +error: > + fprintf(stderr, "qemu: Invalid NUMA CPU range: %s\n", cpus); > + exit(1); > +} > + > + > + > +void numa_add(const char *optarg) > +{ > + char option[128]; > + char *endptr; > + unsigned long long nodenr; > + > + optarg = get_opt_name(option, 128, optarg, ','); > + if (*optarg == ',') { > + optarg++; > + } > + if (!strcmp(option, "node")) { > + > + if (nr_numa_nodes >= MAX_NODES) { > + fprintf(stderr, "qemu: too many NUMA nodes\n"); > + exit(1); > + } > + > + if (get_param_value(option, 128, "nodeid", optarg) == 0) { > + nodenr = nr_numa_nodes; > + } else { > + if (parse_uint_full(option, &nodenr, 10) < 0) { > + fprintf(stderr, "qemu: Invalid NUMA nodeid: %s\n", option); > + exit(1); > + } > + } > + > + if (nodenr >= MAX_NODES) { > + fprintf(stderr, "qemu: invalid NUMA nodeid: %llu\n", nodenr); > + exit(1); > + } > + > + if (get_param_value(option, 128, "mem", optarg) == 0) { > + node_mem[nodenr] = 0; > + } else { > + int64_t sval; > + sval = strtosz(option, &endptr); > + if (sval < 0 || *endptr) { > + fprintf(stderr, "qemu: invalid numa mem size: %s\n", optarg); > + exit(1); > + } > + node_mem[nodenr] = sval; > + } > + if (get_param_value(option, 128, "cpus", optarg) != 0) { > + numa_node_parse_cpus(nodenr, option); > + } > + nr_numa_nodes++; > + } else { > + fprintf(stderr, "Invalid -numa option: %s\n", option); > + exit(1); > + } > +} > + > +void numa_assignment(void) > +{ > + int i = 0; > + > + if (nr_numa_nodes > 0) { > + if (nr_numa_nodes > MAX_NODES) { > + nr_numa_nodes = MAX_NODES; > + } > + > + /* If no memory size if given for any node, assume the default case > + * and distribute the available memory equally across all nodes > + */ > + for (i = 0; i < nr_numa_nodes; i++) { > + if (node_mem[i] != 0) { > + break; > + } > + } > + if (i == nr_numa_nodes) { > + uint64_t usedmem = 0; > + > + /* On Linux, the each node's border has to be 8MB aligned, > + * the final node gets the rest. > + */ > + for (i = 0; i < nr_numa_nodes - 1; i++) { > + node_mem[i] = (ram_size / nr_numa_nodes) & ~((1 << 23UL) - > 1); > + usedmem += node_mem[i]; > + } > + node_mem[i] = ram_size - usedmem; > + } > + > + for (i = 0; i < nr_numa_nodes; i++) { > + if (!bitmap_empty(node_cpumask[i], MAX_CPUMASK_BITS)) { > + break; > + } > + } > + /* assigning the VCPUs round-robin is easier to implement, guest OSes > + * must cope with this anyway, because there are BIOSes out there in > + * real machines which also use this scheme. > + */ > + if (i == nr_numa_nodes) { > + for (i = 0; i < max_cpus; i++) { > + set_bit(i, node_cpumask[i % nr_numa_nodes]); > + } > + } > + } > +} > diff --git a/numa-opts.h b/numa-opts.h > new file mode 100644 > index 0000000..9accea3 > --- /dev/null > +++ b/numa-opts.h > @@ -0,0 +1,9 @@ > +#ifndef NUMA_OPTS_H > +#define NUMA_OPTS_H > + > +int get_nr_numa_nodes(void); > +void set_nr_numa_nodes(int nr); > +void numa_add(const char *optarg); > +void numa_assignment(void); > + > +#endif > diff --git a/vl.c b/vl.c > index febd2ea..4e6606f 100644 > --- a/vl.c > +++ b/vl.c > @@ -170,6 +170,9 @@ int main(int argc, char **argv) > #include "ui/qemu-spice.h" > #include "qapi/string-input-visitor.h" > > +#include "numa-opts.h" > +#include "bt-opts.h" > + > //#define DEBUG_NET > //#define DEBUG_SLIRP > > @@ -248,10 +251,6 @@ struct FWBootEntry { > static QTAILQ_HEAD(, FWBootEntry) fw_boot_order = > QTAILQ_HEAD_INITIALIZER(fw_boot_order); > > -int nb_numa_nodes; > -uint64_t node_mem[MAX_NODES]; > -unsigned long *node_cpumask[MAX_NODES]; > - > uint8_t qemu_uuid[16]; > > static QEMUBootSetHandler *boot_set_handler; > @@ -769,197 +768,6 @@ static void configure_rtc(QemuOpts *opts) > } > } > > -/***********************************************************/ > -/* Bluetooth support */ > -static int nb_hcis; > -static int cur_hci; > -static struct HCIInfo *hci_table[MAX_NICS]; > - > -static struct bt_vlan_s { > - struct bt_scatternet_s net; > - int id; > - struct bt_vlan_s *next; > -} *first_bt_vlan; > - > -/* find or alloc a new bluetooth "VLAN" */ > -static struct bt_scatternet_s *qemu_find_bt_vlan(int id) > -{ > - struct bt_vlan_s **pvlan, *vlan; > - for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) { > - if (vlan->id == id) > - return &vlan->net; > - } > - vlan = g_malloc0(sizeof(struct bt_vlan_s)); > - vlan->id = id; > - pvlan = &first_bt_vlan; > - while (*pvlan != NULL) > - pvlan = &(*pvlan)->next; > - *pvlan = vlan; > - return &vlan->net; > -} > - > -static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len) > -{ > -} > - > -static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr) > -{ > - return -ENOTSUP; > -} > - > -static struct HCIInfo null_hci = { > - .cmd_send = null_hci_send, > - .sco_send = null_hci_send, > - .acl_send = null_hci_send, > - .bdaddr_set = null_hci_addr_set, > -}; > - > -struct HCIInfo *qemu_next_hci(void) > -{ > - if (cur_hci == nb_hcis) > - return &null_hci; > - > - return hci_table[cur_hci++]; > -} > - > -static struct HCIInfo *hci_init(const char *str) > -{ > - char *endp; > - struct bt_scatternet_s *vlan = 0; > - > - if (!strcmp(str, "null")) > - /* null */ > - return &null_hci; > - else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':')) > - /* host[:hciN] */ > - return bt_host_hci(str[4] ? str + 5 : "hci0"); > - else if (!strncmp(str, "hci", 3)) { > - /* hci[,vlan=n] */ > - if (str[3]) { > - if (!strncmp(str + 3, ",vlan=", 6)) { > - vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0)); > - if (*endp) > - vlan = 0; > - } > - } else > - vlan = qemu_find_bt_vlan(0); > - if (vlan) > - return bt_new_hci(vlan); > - } > - > - fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str); > - > - return 0; > -} > - > -static int bt_hci_parse(const char *str) > -{ > - struct HCIInfo *hci; > - bdaddr_t bdaddr; > - > - if (nb_hcis >= MAX_NICS) { > - fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", > MAX_NICS); > - return -1; > - } > - > - hci = hci_init(str); > - if (!hci) > - return -1; > - > - bdaddr.b[0] = 0x52; > - bdaddr.b[1] = 0x54; > - bdaddr.b[2] = 0x00; > - bdaddr.b[3] = 0x12; > - bdaddr.b[4] = 0x34; > - bdaddr.b[5] = 0x56 + nb_hcis; > - hci->bdaddr_set(hci, bdaddr.b); > - > - hci_table[nb_hcis++] = hci; > - > - return 0; > -} > - > -static void bt_vhci_add(int vlan_id) > -{ > - struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id); > - > - if (!vlan->slave) > - fprintf(stderr, "qemu: warning: adding a VHCI to " > - "an empty scatternet %i\n", vlan_id); > - > - bt_vhci_init(bt_new_hci(vlan)); > -} > - > -static struct bt_device_s *bt_device_add(const char *opt) > -{ > - struct bt_scatternet_s *vlan; > - int vlan_id = 0; > - char *endp = strstr(opt, ",vlan="); > - int len = (endp ? endp - opt : strlen(opt)) + 1; > - char devname[10]; > - > - pstrcpy(devname, MIN(sizeof(devname), len), opt); > - > - if (endp) { > - vlan_id = strtol(endp + 6, &endp, 0); > - if (*endp) { > - fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n"); > - return 0; > - } > - } > - > - vlan = qemu_find_bt_vlan(vlan_id); > - > - if (!vlan->slave) > - fprintf(stderr, "qemu: warning: adding a slave device to " > - "an empty scatternet %i\n", vlan_id); > - > - if (!strcmp(devname, "keyboard")) > - return bt_keyboard_init(vlan); > - > - fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname); > - return 0; > -} > - > -static int bt_parse(const char *opt) > -{ > - const char *endp, *p; > - int vlan; > - > - if (strstart(opt, "hci", &endp)) { > - if (!*endp || *endp == ',') { > - if (*endp) > - if (!strstart(endp, ",vlan=", 0)) > - opt = endp + 1; > - > - return bt_hci_parse(opt); > - } > - } else if (strstart(opt, "vhci", &endp)) { > - if (!*endp || *endp == ',') { > - if (*endp) { > - if (strstart(endp, ",vlan=", &p)) { > - vlan = strtol(p, (char **) &endp, 0); > - if (*endp) { > - fprintf(stderr, "qemu: bad scatternet '%s'\n", p); > - return 1; > - } > - } else { > - fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1); > - return 1; > - } > - } else > - vlan = 0; > - > - bt_vhci_add(vlan); > - return 0; > - } > - } else if (strstart(opt, "device:", &endp)) > - return !bt_device_add(endp); > - > - fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt); > - return 1; > -} > - > static int parse_sandbox(QemuOpts *opts, void *opaque) > { > /* FIXME: change this to true for 1.3 */ > @@ -1244,102 +1052,6 @@ char *get_boot_devices_list(size_t *size) > return list; > } > > -static void numa_node_parse_cpus(int nodenr, const char *cpus) > -{ > - char *endptr; > - unsigned long long value, endvalue; > - > - /* Empty CPU range strings will be considered valid, they will simply > - * not set any bit in the CPU bitmap. > - */ > - if (!*cpus) { > - return; > - } > - > - if (parse_uint(cpus, &value, &endptr, 10) < 0) { > - goto error; > - } > - if (*endptr == '-') { > - if (parse_uint_full(endptr + 1, &endvalue, 10) < 0) { > - goto error; > - } > - } else if (*endptr == '\0') { > - endvalue = value; > - } else { > - goto error; > - } > - > - if (endvalue >= MAX_CPUMASK_BITS) { > - endvalue = MAX_CPUMASK_BITS - 1; > - fprintf(stderr, > - "qemu: NUMA: A max of %d VCPUs are supported\n", > - MAX_CPUMASK_BITS); > - } > - > - if (endvalue < value) { > - goto error; > - } > - > - bitmap_set(node_cpumask[nodenr], value, endvalue-value+1); > - return; > - > -error: > - fprintf(stderr, "qemu: Invalid NUMA CPU range: %s\n", cpus); > - exit(1); > -} > - > -static void numa_add(const char *optarg) > -{ > - char option[128]; > - char *endptr; > - unsigned long long nodenr; > - > - optarg = get_opt_name(option, 128, optarg, ','); > - if (*optarg == ',') { > - optarg++; > - } > - if (!strcmp(option, "node")) { > - > - if (nb_numa_nodes >= MAX_NODES) { > - fprintf(stderr, "qemu: too many NUMA nodes\n"); > - exit(1); > - } > - > - if (get_param_value(option, 128, "nodeid", optarg) == 0) { > - nodenr = nb_numa_nodes; > - } else { > - if (parse_uint_full(option, &nodenr, 10) < 0) { > - fprintf(stderr, "qemu: Invalid NUMA nodeid: %s\n", option); > - exit(1); > - } > - } > - > - if (nodenr >= MAX_NODES) { > - fprintf(stderr, "qemu: invalid NUMA nodeid: %llu\n", nodenr); > - exit(1); > - } > - > - if (get_param_value(option, 128, "mem", optarg) == 0) { > - node_mem[nodenr] = 0; > - } else { > - int64_t sval; > - sval = strtosz(option, &endptr); > - if (sval < 0 || *endptr) { > - fprintf(stderr, "qemu: invalid numa mem size: %s\n", optarg); > - exit(1); > - } > - node_mem[nodenr] = sval; > - } > - if (get_param_value(option, 128, "cpus", optarg) != 0) { > - numa_node_parse_cpus(nodenr, option); > - } > - nb_numa_nodes++; > - } else { > - fprintf(stderr, "Invalid -numa option: %s\n", option); > - exit(1); > - } > -} > - > static void smp_parse(const char *optarg) > { > int smp, sockets = 0, threads = 0, cores = 0; > @@ -2892,7 +2604,7 @@ int main(int argc, char **argv, char **envp) > node_cpumask[i] = bitmap_new(MAX_CPUMASK_BITS); > } > > - nb_numa_nodes = 0; > + set_nr_numa_nodes(0); > nb_nics = 0; > > autostart= 1; > @@ -4141,48 +3853,7 @@ int main(int argc, char **argv, char **envp) > > register_savevm_live(NULL, "ram", 0, 4, &savevm_ram_handlers, NULL); > > - if (nb_numa_nodes > 0) { > - int i; > - > - if (nb_numa_nodes > MAX_NODES) { > - nb_numa_nodes = MAX_NODES; > - } > - > - /* If no memory size if given for any node, assume the default case > - * and distribute the available memory equally across all nodes > - */ > - for (i = 0; i < nb_numa_nodes; i++) { > - if (node_mem[i] != 0) > - break; > - } > - if (i == nb_numa_nodes) { > - uint64_t usedmem = 0; > - > - /* On Linux, the each node's border has to be 8MB aligned, > - * the final node gets the rest. > - */ > - for (i = 0; i < nb_numa_nodes - 1; i++) { > - node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - > 1); > - usedmem += node_mem[i]; > - } > - node_mem[i] = ram_size - usedmem; > - } > - > - for (i = 0; i < nb_numa_nodes; i++) { > - if (!bitmap_empty(node_cpumask[i], MAX_CPUMASK_BITS)) { > - break; > - } > - } > - /* assigning the VCPUs round-robin is easier to implement, guest OSes > - * must cope with this anyway, because there are BIOSes out there in > - * real machines which also use this scheme. > - */ > - if (i == nb_numa_nodes) { > - for (i = 0; i < max_cpus; i++) { > - set_bit(i, node_cpumask[i % nb_numa_nodes]); > - } > - } > - } > + numa_assignment(); > > if (qemu_opts_foreach(qemu_find_opts("mon"), mon_init_func, NULL, 1) != > 0) { > exit(1);