-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathpktqueue.go
133 lines (114 loc) · 3.69 KB
/
pktqueue.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package iface
/*
#include "../csrc/iface/pktqueue.h"
*/
import "C"
import (
"time"
"unsafe"
"github.com/usnistgov/ndn-dpdk/core/cptr"
"github.com/usnistgov/ndn-dpdk/core/nnduration"
"github.com/usnistgov/ndn-dpdk/dpdk/eal"
"github.com/usnistgov/ndn-dpdk/dpdk/pktmbuf"
"github.com/usnistgov/ndn-dpdk/dpdk/ringbuffer"
)
// PktQueueConfig contains PktQueue configuration.
type PktQueueConfig struct {
// Ring capacity, must be power of 2, default 131072 with delay/CoDel or 4096 without
Capacity int `json:"capacity,omitempty"`
// dequeue burst size limit, default MaxBurstSize
DequeueBurstSize int `json:"dequeueBurstSize,omitempty"`
// if non-zero, enforce minimum delay, implies DisableCoDel
Delay nnduration.Nanoseconds `json:"delay,omitempty"`
// if true, disable CoDel algorithm
DisableCoDel bool `json:"disableCoDel,omitempty"`
// CoDel TARGET parameter, default 5ms
Target nnduration.Nanoseconds `json:"target,omitempty"`
// CoDel INTERVAL parameter, default 100ms
Interval nnduration.Nanoseconds `json:"interval,omitempty"`
}
// PktQueue is a packet queue with simplified CoDel algorithm.
type PktQueue C.PktQueue
// PktQueueFromPtr converts *C.PktQueue to PktQueue.
func PktQueueFromPtr(ptr unsafe.Pointer) (q *PktQueue) {
return (*PktQueue)(ptr)
}
// Ptr return *C.PktQueue pointer.
func (q *PktQueue) Ptr() unsafe.Pointer {
return unsafe.Pointer(q)
}
func (q *PktQueue) ptr() *C.PktQueue {
return (*C.PktQueue)(q)
}
// Init initializes PktQueue.
func (q *PktQueue) Init(cfg PktQueueConfig, socket eal.NumaSocket) error {
capacity := 131072
switch {
case cfg.Delay > 0:
q.pop = C.PktQueuePopActDelay
q.target = C.TscDuration(eal.ToTscDuration(cfg.Delay.Duration()))
case cfg.DisableCoDel:
q.pop = C.PktQueuePopActPlain
capacity = 4096
default:
q.pop = C.PktQueuePopActCoDel
q.target = C.TscDuration(eal.ToTscDuration(cfg.Target.DurationOr(nnduration.Nanoseconds(5 * time.Millisecond))))
q.interval = C.TscDuration(eal.ToTscDuration(cfg.Interval.DurationOr(nnduration.Nanoseconds(100 * time.Millisecond))))
}
if cfg.Capacity > 0 {
capacity = cfg.Capacity
}
ring, e := ringbuffer.New(capacity, socket, ringbuffer.ProducerMulti, ringbuffer.ConsumerSingle)
if e != nil {
return e
}
q.ring = (*C.struct_rte_ring)(ring.Ptr())
if cfg.DequeueBurstSize > 0 && cfg.DequeueBurstSize < MaxBurstSize {
q.dequeueBurstSize = C.uint32_t(cfg.DequeueBurstSize)
} else {
q.dequeueBurstSize = MaxBurstSize
}
return nil
}
// Ring provides access to the internal ring.
func (q *PktQueue) Ring() *ringbuffer.Ring {
return ringbuffer.FromPtr(unsafe.Pointer(q.ring))
}
// Close drains and deallocates the PktQueue.
// It will not free *C.PktQueue itself.
func (q *PktQueue) Close() error {
ring := q.Ring()
if ring == nil {
return nil
}
q.ring = nil
vec := make(pktmbuf.Vector, MaxBurstSize)
for {
n := ringbuffer.Dequeue(ring, vec)
if n == 0 {
break
}
vec[:n].Close()
}
return ring.Close()
}
// Push enqueues a slice of packets.
// Timestamps must have been assigned on the packets.
// Caller must free rejected packets.
func (q *PktQueue) Push(vec pktmbuf.Vector) (nRej int) {
return int(C.PktQueue_Push(q.ptr(), cptr.FirstPtr[*C.struct_rte_mbuf](vec), C.uint32_t(len(vec))))
}
// Pop dequeues a slice of packets.
func (q *PktQueue) Pop(vec pktmbuf.Vector, now eal.TscTime) (count int, drop bool) {
res := C.PktQueue_Pop(q.ptr(), cptr.FirstPtr[*C.struct_rte_mbuf](vec), C.uint32_t(len(vec)), C.TscTime(now))
return int(res.count), bool(res.drop)
}
// PktQueueCounters contains PktQueue counters.
type PktQueueCounters struct {
NDrops uint64 `json:"nDrops"`
}
// Counters reads counters.
func (q *PktQueue) Counters() (cnt PktQueueCounters) {
cnt.NDrops = uint64(q.nDrops)
return cnt
}