From 077e41b0a9a4924f3a302cbd6f09b090ccd7304e Mon Sep 17 00:00:00 2001 From: Saza-ku Date: Mon, 5 Feb 2024 00:54:41 +0900 Subject: [PATCH] virtio net: interrupt coalescing when sending packets --- src/drivers/virtio/common.zig | 4 ++++ src/drivers/virtio/net.zig | 22 +++++++++++++--------- src/timer.zig | 3 +++ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/drivers/virtio/common.zig b/src/drivers/virtio/common.zig index 16e8d5fd..4d9520dd 100644 --- a/src/drivers/virtio/common.zig +++ b/src/drivers/virtio/common.zig @@ -530,6 +530,10 @@ pub fn VirtioMmioTransport(comptime DeviceConfigType: type) type { } pub fn notifyQueue(self: *Self, virtq: *Virtqueue) void { + if (virtq.not_notified_num_descs == 0) { + return; + } + self.common_config.queue_select = virtq.index; @fence(std.builtin.AtomicOrder.SeqCst); const offset = self.notify_off_multiplier * self.common_config.queue_notify_off; diff --git a/src/drivers/virtio/net.zig b/src/drivers/virtio/net.zig index 8e611ea9..255c2e90 100644 --- a/src/drivers/virtio/net.zig +++ b/src/drivers/virtio/net.zig @@ -129,17 +129,17 @@ const VirtioNet = struct { const buf = @as([*]u8, @ptrFromInt(base + @sizeOf(Header))); @memcpy(buf, data); - var desc_buf = [_]common.VirtqDescBuffer{ common.VirtqDescBuffer{ + var desc_buf = [_]common.VirtqDescBuffer{common.VirtqDescBuffer{ .addr = base, - .len = @sizeOf(Header), + .len = @sizeOf(Header) + @as(u32, @intCast(data.len)), .type = common.VirtqDescBufferType.ReadonlyFromDevice, - }, common.VirtqDescBuffer{ - .addr = base + @sizeOf(Header), - .len = @as(u32, @intCast(data.len)), - .type = common.VirtqDescBufferType.ReadonlyFromDevice, - } }; - self.transmitq().enqueue(desc_buf[0..2]); - self.virtio.transport.notifyQueue(self.transmitq()); + }}; + + self.transmitq().enqueue(desc_buf[0..1]); + + if (self.transmitq().not_notified_num_descs > self.transmitq().num_descs / 2) { + self.virtio.transport.notifyQueue(self.transmitq()); + } } pub fn receive(self: *Self) void { @@ -207,3 +207,7 @@ fn handleIrq(frame: *interrupt.InterruptFrame) void { log.debug.print("interrupt\n"); virtio_net.receive(); } + +pub fn flush() void { + virtio_net.virtio.transport.notifyQueue(virtio_net.transmitq()); +} diff --git a/src/timer.zig b/src/timer.zig index 31a45d2c..324305b5 100644 --- a/src/timer.zig +++ b/src/timer.zig @@ -2,6 +2,7 @@ const std = @import("std"); const heap = @import("heap.zig"); const interrupt = @import("interrupt.zig"); const sync = @import("sync.zig"); +const net = @import("drivers/virtio/net.zig"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayList; @@ -58,6 +59,8 @@ pub fn handleIrq(frame: *interrupt.InterruptFrame) void { } } timers.release(); + + net.flush(); } pub fn init() void {