Skip to content

Commit d0cc9c8

Browse files
committed
virtionet: Using minimal amount of buffers
1 parent 4a79796 commit d0cc9c8

2 files changed

Lines changed: 29 additions & 29 deletions

File tree

src/drivers/virtionet.cpp

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,11 @@ void VirtioNet::get_config() {
4444
VirtioNet::VirtioNet(hw::PCI_Device& d)
4545
: Virtio(d),
4646
Link(Link_protocol{{this, &VirtioNet::transmit}, mac()},
47-
std::max(2048u, queue_size(0) * 2), 2048 /* half-page buffers */),
47+
std::max(256u, queue_size(0) * 2), 2048 /* half-page buffers */),
4848
packets_rx_{Statman::get().create(Stat::UINT64, device_name() + ".packets_rx").get_uint64()},
4949
packets_tx_{Statman::get().create(Stat::UINT64, device_name() + ".packets_tx").get_uint64()}
5050
{
5151
INFO("VirtioNet", "Driver initializing");
52-
static_assert(VIRTIO_HDR_OFFSET >= sizeof(virtio_net_hdr),
53-
"Must be at least larger than the driver header itself");
5452

5553
uint32_t needed_features = 0
5654
| (1 << VIRTIO_NET_F_MAC)
@@ -188,20 +186,17 @@ void VirtioNet::msix_conf_handler()
188186
}
189187
void VirtioNet::msix_recv_handler()
190188
{
191-
bool dequeued_rx = false;
189+
int dequeued_rx = 0;
192190
rx_q.disable_interrupts();
193191
// handle incoming packets as long as bufstore has available buffers
194192
while (rx_q.new_incoming())
195193
{
196194
auto res = rx_q.dequeue();
197-
auto pckt_ptr = recv_packet(res.data(), res.size());
198-
Link::receive(std::move(pckt_ptr));
195+
Link::receive( recv_packet(res.data(), res.size()) );
199196

197+
dequeued_rx++;
200198
// Requeue a new buffer
201-
if (bufstore().available() > 0)
202-
add_receive_buffer(bufstore().get_buffer());
203-
204-
dequeued_rx = true;
199+
add_receive_buffer(bufstore().get_buffer());
205200

206201
// Stat increase packets received
207202
packets_rx_++;
@@ -248,7 +243,7 @@ void VirtioNet::add_receive_buffer(uint8_t* pkt)
248243
auto* vnet = pkt + sizeof(Packet);
249244

250245
Token token1 {{vnet, sizeof(virtio_net_hdr)}, Token::IN };
251-
Token token2 {{vnet + VIRTIO_HDR_OFFSET, packet_len()}, Token::IN };
246+
Token token2 {{vnet + sizeof(virtio_net_hdr), packet_len()}, Token::IN };
252247

253248
std::array<Token, 2> tokens {{ token1, token2 }};
254249
rx_q.enqueue(tokens);
@@ -263,19 +258,25 @@ VirtioNet::recv_packet(uint8_t* data, uint16_t size)
263258
assert(bufstore().is_buffer((uint8_t*) ptr));
264259
#endif
265260

266-
new (ptr) net::Packet(frame_offset_device(), size - frame_offset_device(), frame_offset_device() + packet_len(), &bufstore());
261+
new (ptr) net::Packet(
262+
sizeof(virtio_net_hdr),
263+
size - sizeof(virtio_net_hdr),
264+
sizeof(virtio_net_hdr) + packet_len(),
265+
&bufstore());
267266

268267
return net::Packet_ptr(ptr);
269268
}
270269

271270
net::Packet_ptr
272271
VirtioNet::create_packet(int link_offset)
273272
{
274-
debug("<Virtionet> Creating packet, device offset %i (virtionet header size %i) link offset %i \n",
275-
frame_offset_device(), sizeof(virtio_net_hdr), link_offset);
276273
auto* ptr = (net::Packet*) bufstore().get_buffer();
277274

278-
new (ptr) net::Packet(frame_offset_device() + link_offset, 0, frame_offset_device() + packet_len(), &bufstore());
275+
new (ptr) net::Packet(
276+
sizeof(virtio_net_hdr) + link_offset,
277+
0,
278+
sizeof(virtio_net_hdr) + packet_len(),
279+
&bufstore());
279280

280281
return net::Packet_ptr(ptr);
281282
}
@@ -314,7 +315,8 @@ void VirtioNet::transmit(net::Packet_ptr pckt) {
314315
net::Packet_ptr tail = std::move(pckt);
315316

316317
// Transmit all we can directly
317-
while (tx_q.num_free() and tail) {
318+
while (tx_q.num_free() and tail != nullptr)
319+
{
318320
debug("%i tokens left in TX queue \n", tx_q.num_free());
319321
// next in line
320322
auto next = tail->detach_tail();
@@ -325,20 +327,22 @@ void VirtioNet::transmit(net::Packet_ptr pckt) {
325327
transmitted++;
326328
// Stat increase packets transmitted
327329
packets_tx_++;
328-
329-
if (!tail) break;
330330
}
331331

332-
// Notify virtio about new packets
333332
if (LIKELY(transmitted)) {
333+
#ifdef NO_DEFERRED_KICK
334+
tx_q.enable_interrupts();
335+
tx_q.kick();
336+
#else
334337
begin_deferred_kick();
338+
#endif
335339
}
336340

337341
// Buffer the rest
338342
if (UNLIKELY(tail)) {
339343
debug("Buffering remaining packets..\n");
340344
add_to_tx_buffer(std::move(tail));
341-
}
345+
}
342346
}
343347

344348
void VirtioNet::enqueue(net::Packet* pckt)
@@ -357,10 +361,7 @@ void VirtioNet::enqueue(net::Packet* pckt)
357361

358362
void VirtioNet::begin_deferred_kick()
359363
{
360-
#ifdef NO_DEFERRED_KICK
361-
tx_q.enable_interrupts();
362-
tx_q.kick();
363-
#else
364+
#ifndef NO_DEFERRED_KICK
364365
if (!deferred_kick) {
365366
deferred_kick = true;
366367
PER_CPU(deferred_devs).devs.push_back(this);
@@ -371,9 +372,11 @@ void VirtioNet::begin_deferred_kick()
371372
void VirtioNet::handle_deferred_devices()
372373
{
373374
#ifndef NO_DEFERRED_KICK
374-
for (auto* dev : PER_CPU(deferred_devs).devs) {
375-
// kick transmitq
375+
for (auto* dev : PER_CPU(deferred_devs).devs)
376+
if (dev->deferred_kick)
377+
{
376378
dev->deferred_kick = false;
379+
// kick transmitq
377380
dev->tx_q.enable_interrupts();
378381
dev->tx_q.kick();
379382
}

src/drivers/virtionet.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,6 @@ class VirtioNet : Virtio, public net::Link_layer<net::Ethernet> {
187187
uint16_t num_buffers;
188188
}__attribute__((packed));
189189

190-
// make packets cache-aligned on the IP-layer
191-
static const int VIRTIO_HDR_OFFSET = sizeof(virtio_net_hdr);
192-
193190
Virtio::Queue rx_q;
194191
Virtio::Queue tx_q;
195192
Virtio::Queue ctrl_q;

0 commit comments

Comments
 (0)