Skip to content

Commit 68cff00

Browse files
authored
Merge pull request #1641 from fwsGonzo/dev
e1000 optimizations
2 parents c125c5f + b736c91 commit 68cff00

4 files changed

Lines changed: 45 additions & 6 deletions

File tree

src/drivers/e1000.cpp

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
#include <malloc.h>
2626
// loosely based on OSdev article http://wiki.osdev.org/Intel_Ethernet_i217
2727

28+
static int deferred_event = 0;
29+
static std::vector<e1000*> deferred_devices;
30+
2831
e1000::e1000(hw::PCI_Device& d) :
2932
Link(Link_protocol{{this, &e1000::transmit}, mac()}, bufstore_),
3033
m_pcidev(d), bufstore_{1024, 2048}
@@ -40,6 +43,11 @@ e1000::e1000(hw::PCI_Device& d) :
4043
__arch_enable_legacy_irq(this->m_irq);
4144
INFO2("Subscribed on IRQ %u", this->m_irq);
4245

46+
if (deferred_event == 0)
47+
{
48+
deferred_event = Events::get().subscribe(&e1000::do_deferred_xmit);
49+
}
50+
4351
// shared-memory & I/O address
4452
this->shm_base = d.get_bar(0);
4553
this->io_base = d.iobase();
@@ -208,6 +216,8 @@ void e1000::event_handler()
208216

209217
void e1000::recv_handler()
210218
{
219+
uint16_t old_idx = 0xffff;
220+
211221
while (rx.desc[rx.current].status & 1)
212222
{
213223
auto& tk = rx.desc[rx.current];
@@ -221,11 +231,11 @@ void e1000::recv_handler()
221231
tk.addr = (uint64_t) this->new_rx_packet();
222232
tk.status = 0;
223233
// go to next index
224-
uint16_t old_idx = rx.current;
234+
old_idx = rx.current;
225235
rx.current = (rx.current + 1) % NUM_RX_DESC;
226-
write_cmd(REG_RXDESCTAIL, old_idx);
227236
}
228-
237+
if (old_idx != 0xffff)
238+
write_cmd(REG_RXDESCTAIL, old_idx);
229239
}
230240

231241
void e1000::transmit(net::Packet_ptr pckt)
@@ -265,12 +275,28 @@ void e1000::transmit_data(uint8_t* data, uint16_t length)
265275
tk.status = 0;
266276

267277
tx.current = (tx.current + 1) % NUM_TX_DESC;
278+
if (tx.deferred == false)
279+
{
280+
tx.deferred = true;
281+
deferred_devices.push_back(this);
282+
Events::get().trigger_event(deferred_event);
283+
}
284+
}
285+
void e1000::xmit_kick()
286+
{
268287
write_cmd(REG_TXDESCTAIL, tx.current);
288+
tx.deferred = false;
289+
}
290+
void e1000::do_deferred_xmit()
291+
{
292+
for (auto& dev : deferred_devices)
293+
dev->xmit_kick();
294+
deferred_devices.clear();
269295
}
270296

271297
void e1000::flush()
272298
{
273-
299+
this->transmit(std::move(sendq));
274300
}
275301
void e1000::poll()
276302
{
@@ -283,7 +309,7 @@ void e1000::deactivate()
283309
}
284310
void e1000::move_to_this_cpu()
285311
{
286-
312+
// TODO: implement me
287313
}
288314

289315
#include <kernel/pci_manager.hpp>
@@ -294,5 +320,6 @@ static void register_func()
294320
PCI_manager::register_nic(PCI::VENDOR_INTEL, 0x100E, &e1000::new_instance);
295321
PCI_manager::register_nic(PCI::VENDOR_INTEL, 0x100F, &e1000::new_instance);
296322
PCI_manager::register_nic(PCI::VENDOR_INTEL, 0x153A, &e1000::new_instance);
323+
PCI_manager::register_nic(PCI::VENDOR_INTEL, 0x1539, &e1000::new_instance);
297324
PCI_manager::register_nic(PCI::VENDOR_INTEL, 0x10EA, &e1000::new_instance);
298325
}

src/drivers/e1000.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class e1000 : public net::Link_layer<net::Ethernet>
9090
void recv_handler();
9191
bool can_transmit();
9292
void transmit_data(uint8_t*, uint16_t);
93+
void xmit_kick();
94+
static void do_deferred_xmit();
9395

9496
hw::PCI_Device& m_pcidev;
9597
std::vector<uint8_t> irqs;
@@ -127,6 +129,7 @@ class e1000 : public net::Link_layer<net::Ethernet>
127129
struct tx_t {
128130
tx_desc desc[NUM_TX_DESC];
129131
uint16_t current = 0;
132+
bool deferred = false;
130133
} tx;
131134

132135
// sendq as packet chain

vmrunner/vm.schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@
9999
"vga" : {
100100
"description" : "Enable VGA screen",
101101
"enum" : ["std", "cirrus", "vmware", "qxl", "xenfb", "tcx", "cg3", "virtio", "none"]
102+
},
103+
104+
"vfio" : {
105+
"description" : "VFIO PCI-passthrough on device",
106+
"type" : "string"
102107
}
103108
}
104109

vmrunner/vmrunner.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,13 +379,17 @@ def boot(self, multiboot, kernel_args = "", image_name = None):
379379
if "vga" in self._config:
380380
vga_arg = ["-vga", str(self._config["vga"])]
381381

382+
pci_arg = []
383+
if "vfio" in self._config:
384+
pci_arg = ["-device", "vfio-pci,host=" + self._config["vfio"]]
385+
382386
# TODO: sudo is only required for tap networking and kvm. Check for those.
383387
command = ["sudo", "--preserve-env", "qemu-system-x86_64"]
384388
if self._kvm_present: command.extend(["--enable-kvm"])
385389

386390
command += kernel_args
387391

388-
command += disk_args + net_args + mem_arg + vga_arg + mod_args
392+
command += disk_args + net_args + mem_arg + vga_arg + pci_arg + mod_args
389393

390394
#command_str = " ".join(command)
391395
#command_str.encode('ascii','ignore')

0 commit comments

Comments
 (0)