[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 5/7] net: reduce the unnecessary memory allocation o
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PATCH 5/7] net: reduce the unnecessary memory allocation of multiqueue |
Date: |
Wed, 27 Feb 2013 16:22:23 +0100 |
From: Jason Wang <address@hidden>
Edivaldo reports a problem that the array of NetClientState in NICState is too
large - MAX_QUEUE_NUM(1024) which will wastes memory even if multiqueue is not
used.
Instead of static arrays, solving this issue by allocating the queues on demand
for both the NetClientState array in NICState and VirtIONetQueue array in
VirtIONet.
Tested by myself, with single virtio-net-pci device. The memory allocation is
almost the same as when multiqueue is not merged.
Cc: Edivaldo de Araujo Pereira <address@hidden>
Cc: address@hidden
Signed-off-by: Jason Wang <address@hidden>
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
hw/virtio-net.c | 6 ++++--
include/net/net.h | 2 +-
net/net.c | 19 +++++++++----------
3 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 573c669..bb2c26c 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -44,7 +44,7 @@ typedef struct VirtIONet
VirtIODevice vdev;
uint8_t mac[ETH_ALEN];
uint16_t status;
- VirtIONetQueue vqs[MAX_QUEUE_NUM];
+ VirtIONetQueue *vqs;
VirtQueue *ctrl_vq;
NICState *nic;
uint32_t tx_timeout;
@@ -1326,8 +1326,9 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf
*conf,
n->vdev.set_status = virtio_net_set_status;
n->vdev.guest_notifier_mask = virtio_net_guest_notifier_mask;
n->vdev.guest_notifier_pending = virtio_net_guest_notifier_pending;
+ n->max_queues = MAX(conf->queues, 1);
+ n->vqs = g_malloc0(sizeof(VirtIONetQueue) * n->max_queues);
n->vqs[0].rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
- n->max_queues = conf->queues;
n->curr_queues = 1;
n->vqs[0].n = n;
n->tx_timeout = net->txtimer;
@@ -1412,6 +1413,7 @@ void virtio_net_exit(VirtIODevice *vdev)
}
}
+ g_free(n->vqs);
qemu_del_nic(n->nic);
virtio_cleanup(&n->vdev);
}
diff --git a/include/net/net.h b/include/net/net.h
index 43a045e..cb049a1 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -72,7 +72,7 @@ struct NetClientState {
};
typedef struct NICState {
- NetClientState ncs[MAX_QUEUE_NUM];
+ NetClientState *ncs;
NICConf *conf;
void *opaque;
bool peer_deleted;
diff --git a/net/net.c b/net/net.c
index a66aa02..f3d67f8 100644
--- a/net/net.c
+++ b/net/net.c
@@ -235,23 +235,20 @@ NICState *qemu_new_nic(NetClientInfo *info,
const char *name,
void *opaque)
{
- NetClientState *nc;
NetClientState **peers = conf->peers.ncs;
NICState *nic;
- int i;
+ int i, queues = MAX(1, conf->queues);
assert(info->type == NET_CLIENT_OPTIONS_KIND_NIC);
assert(info->size >= sizeof(NICState));
- nc = qemu_new_net_client(info, peers[0], model, name);
- nc->queue_index = 0;
-
- nic = qemu_get_nic(nc);
+ nic = g_malloc0(info->size + sizeof(NetClientState) * queues);
+ nic->ncs = (void *)nic + info->size;
nic->conf = conf;
nic->opaque = opaque;
- for (i = 1; i < conf->queues; i++) {
- qemu_net_client_setup(&nic->ncs[i], info, peers[i], model, nc->name,
+ for (i = 0; i < queues; i++) {
+ qemu_net_client_setup(&nic->ncs[i], info, peers[i], model, name,
NULL);
nic->ncs[i].queue_index = i;
}
@@ -261,7 +258,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
NetClientState *qemu_get_subqueue(NICState *nic, int queue_index)
{
- return &nic->ncs[queue_index];
+ return nic->ncs + queue_index;
}
NetClientState *qemu_get_queue(NICState *nic)
@@ -273,7 +270,7 @@ NICState *qemu_get_nic(NetClientState *nc)
{
NetClientState *nc0 = nc - nc->queue_index;
- return DO_UPCAST(NICState, ncs[0], nc0);
+ return (NICState *)((void *)nc0 - nc->info->size);
}
void *qemu_get_nic_opaque(NetClientState *nc)
@@ -368,6 +365,8 @@ void qemu_del_nic(NICState *nic)
qemu_cleanup_net_client(nc);
qemu_free_net_client(nc);
}
+
+ g_free(nic);
}
void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
--
1.8.1.2
- [Qemu-devel] [PULL 0/7] Net patches, Stefan Hajnoczi, 2013/02/27
- [Qemu-devel] [PATCH 1/7] net: fix qemu_flush_queued_packets() in presence of a hub, Stefan Hajnoczi, 2013/02/27
- [Qemu-devel] [PATCH 3/7] tap: forbid creating multiqueue tap when hub is used, Stefan Hajnoczi, 2013/02/27
- [Qemu-devel] [PATCH 2/7] net: fix unbounded NetQueue, Stefan Hajnoczi, 2013/02/27
- [Qemu-devel] [PATCH 5/7] net: reduce the unnecessary memory allocation of multiqueue,
Stefan Hajnoczi <=
- [Qemu-devel] [PATCH 6/7] doc: document -netdev hubport, Stefan Hajnoczi, 2013/02/27
- [Qemu-devel] [PATCH 7/7] qmp: netdev_add is like -netdev, not -net, fix documentation, Stefan Hajnoczi, 2013/02/27
- [Qemu-devel] [PATCH 4/7] tap: set IFF_ONE_QUEUE per default, Stefan Hajnoczi, 2013/02/27