|
@@ -332,6 +332,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
|
|
nic = g_malloc0(info->size + sizeof(NetClientState) * queues);
|
|
nic = g_malloc0(info->size + sizeof(NetClientState) * queues);
|
|
nic->ncs = (void *)nic + info->size;
|
|
nic->ncs = (void *)nic + info->size;
|
|
nic->conf = conf;
|
|
nic->conf = conf;
|
|
|
|
+ nic->reentrancy_guard = reentrancy_guard,
|
|
nic->opaque = opaque;
|
|
nic->opaque = opaque;
|
|
|
|
|
|
for (i = 0; i < queues; i++) {
|
|
for (i = 0; i < queues; i++) {
|
|
@@ -814,6 +815,7 @@ static ssize_t qemu_deliver_packet_iov(NetClientState *sender,
|
|
int iovcnt,
|
|
int iovcnt,
|
|
void *opaque)
|
|
void *opaque)
|
|
{
|
|
{
|
|
|
|
+ MemReentrancyGuard *owned_reentrancy_guard;
|
|
NetClientState *nc = opaque;
|
|
NetClientState *nc = opaque;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
@@ -826,12 +828,24 @@ static ssize_t qemu_deliver_packet_iov(NetClientState *sender,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (nc->info->type != NET_CLIENT_DRIVER_NIC ||
|
|
|
|
+ qemu_get_nic(nc)->reentrancy_guard->engaged_in_io) {
|
|
|
|
+ owned_reentrancy_guard = NULL;
|
|
|
|
+ } else {
|
|
|
|
+ owned_reentrancy_guard = qemu_get_nic(nc)->reentrancy_guard;
|
|
|
|
+ owned_reentrancy_guard->engaged_in_io = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (nc->info->receive_iov && !(flags & QEMU_NET_PACKET_FLAG_RAW)) {
|
|
if (nc->info->receive_iov && !(flags & QEMU_NET_PACKET_FLAG_RAW)) {
|
|
ret = nc->info->receive_iov(nc, iov, iovcnt);
|
|
ret = nc->info->receive_iov(nc, iov, iovcnt);
|
|
} else {
|
|
} else {
|
|
ret = nc_sendv_compat(nc, iov, iovcnt, flags);
|
|
ret = nc_sendv_compat(nc, iov, iovcnt, flags);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (owned_reentrancy_guard) {
|
|
|
|
+ owned_reentrancy_guard->engaged_in_io = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (ret == 0) {
|
|
if (ret == 0) {
|
|
nc->receive_disabled = 1;
|
|
nc->receive_disabled = 1;
|
|
}
|
|
}
|