[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 06/37] net: reduce the unnecessary memory allocation
From: |
Michael Roth |
Subject: |
[Qemu-devel] [PATCH 06/37] net: reduce the unnecessary memory allocation of multiqueue |
Date: |
Tue, 2 Apr 2013 16:45:11 -0500 |
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>
(cherry picked from commit f6b26cf257232e5854c0e5c98a8685c625bf986e)
Signed-off-by: Michael Roth <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 be03a8d..6262ed0 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.7.9.5
- [Qemu-devel] Patch Round-up for stable 1.4.1, freeze next Tuesday, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 01/37] target-ppc: Fix "G2leGP3" PVR, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 02/37] coroutine: trim down nesting level in perf_nesting test, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 03/37] block: complete all IOs before .bdrv_truncate, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 04/37] tap: forbid creating multiqueue tap when hub is used, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 05/37] qemu-char.c: fix waiting for telnet connection message, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 06/37] net: reduce the unnecessary memory allocation of multiqueue,
Michael Roth <=
- [Qemu-devel] [PATCH 08/37] vga: fix byteswapping., Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 09/37] qmp: netdev_add is like -netdev, not -net, fix documentation, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 07/37] help: add docs for multiqueue tap options, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 10/37] qemu-ga: make guest-sync-delimited available during fsfreeze, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 11/37] scsi-disk: handle io_canceled uniformly and correctly, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 12/37] iscsi: look for pkg-config file too, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 13/37] scsi: do not call scsi_read_data/scsi_write_data for a canceled request, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 14/37] scsi-disk: do not complete canceled UNMAP requests, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 15/37] rtc-test: Fix test failures with recent glib, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 16/37] Allow virtio-net features for legacy s390 virtio bus, Michael Roth, 2013/04/02