pre-fill the tx ring with bogus empty packets

This commit is contained in:
JackDoan
2025-12-18 15:18:19 -06:00
parent 726e282d0a
commit 111efc0779
7 changed files with 57 additions and 50 deletions

View File

@@ -123,6 +123,9 @@ func NewDevice(options ...Option) (*Device, error) {
if err = dev.refillReceiveQueue(); err != nil {
return nil, fmt.Errorf("refill receive queue: %w", err)
}
if err = dev.prefillTxQueue(); err != nil {
return nil, fmt.Errorf("refill tx queue: %w", err)
}
dev.initialized = true
@@ -150,6 +153,27 @@ func (dev *Device) refillReceiveQueue() error {
}
}
func (dev *Device) prefillTxQueue() error {
for {
dt := dev.TransmitQueue.DescriptorTable()
for {
x, _, err := dt.CreateDescriptorForOutputs()
if err != nil {
if errors.Is(err, virtqueue.ErrNotEnoughFreeDescriptors) {
// Queue is full, job is done.
return nil
}
return err
}
err = dev.TransmitQueue.OfferDescriptorChains([]uint16{x}, false)
if err != nil {
return err
}
}
}
}
// Close cleans up the vhost networking device within the kernel and releases
// all resources used for it.
// The implementation will try to release as many resources as possible and
@@ -211,15 +235,16 @@ func createQueue(controlFD int, queueIndex int, queueSize int, itemSize int) (*v
func (dev *Device) GetPacketForTx() (uint16, []byte, error) {
var err error
var idx uint16
if !dev.fullTable {
idx, err = dev.TransmitQueue.DescriptorTable().CreateDescriptorForOutputs()
if err == virtqueue.ErrNotEnoughFreeDescriptors {
dev.fullTable = true
idx, err = dev.TransmitQueue.TakeSingleIndex(context.TODO())
}
} else {
idx, err = dev.TransmitQueue.TakeSingleIndex(context.TODO())
}
//if !dev.fullTable {
// idx, err = dev.TransmitQueue.DescriptorTable().CreateDescriptorForOutputs()
// if err == virtqueue.ErrNotEnoughFreeDescriptors {
// dev.fullTable = true
// idx, err = dev.TransmitQueue.TakeSingleIndex(context.TODO())
// }
//} else {
// idx, err = dev.TransmitQueue.TakeSingleIndex(context.TODO())
//}
idx, err = dev.TransmitQueue.TakeSingleIndex(context.TODO())
if err != nil {
return 0, nil, fmt.Errorf("transmit queue: %w", err)
}
@@ -304,26 +329,26 @@ func (dev *Device) ProcessRxChain(pkt *VirtIOPacket, chain virtqueue.UsedElement
//shift the buffer out of out:
pkt.payload = buf[virtio.NetHdrSize:chain.Length]
pkt.Chains = append(pkt.Chains, idx)
pkt.Chain = idx
return 1, nil
}
type VirtIOPacket struct {
payload []byte
//header virtio.NetHdr
Chains []uint16
Chain uint16
}
func NewVIO() *VirtIOPacket {
out := new(VirtIOPacket)
out.payload = nil
out.Chains = make([]uint16, 0, 8)
out.Chain = 0
return out
}
func (v *VirtIOPacket) Reset() {
v.payload = nil
v.Chains = v.Chains[:0]
v.Chain = 0
}
func (v *VirtIOPacket) GetPayload() []byte {