in pkg/events/events.go [113:159]
func (ev *events) setupRingBuffer(mapFD int, maxEntries uint32) (chan []byte, error) {
ringbuffer := &RingBuffer{
RingBufferMapFD: mapFD,
Mask: uint64(maxEntries - 1),
}
// [Consumer page - 4k][Producer page - 4k][Data section - twice the size of max entries]
// Refer kernel code, twice the size of max entries will help in boundary scenarios
// https://github.com/torvalds/linux/blob/master/kernel/bpf/ringbuf.c#L125
consumer, err := unix.Mmap(mapFD, 0, ev.PageSize, unix.PROT_READ|unix.PROT_WRITE, unix.MAP_SHARED)
if err != nil {
return nil, fmt.Errorf("failed to create Mmap for consumer -> %d: %s", mapFD, err)
}
ringbuffer.Consumerpos = unsafe.Pointer(&consumer[0])
ringbuffer.Consumer = consumer
mmap_sz := uint32(ev.PageSize) + 2*maxEntries
producer, err := unix.Mmap(mapFD, int64(ev.PageSize), int(mmap_sz), unix.PROT_READ, unix.MAP_SHARED)
if err != nil {
unix.Munmap(producer)
return nil, fmt.Errorf("failed to create Mmap for producer -> %d: %s", mapFD, err)
}
ringbuffer.Producerpos = unsafe.Pointer(&producer[0])
ringbuffer.Producer = producer
ringbuffer.Data = unsafe.Pointer(uintptr(unsafe.Pointer(&producer[0])) + uintptr(ev.PageSize))
ev.RingBuffers = append(ev.RingBuffers, ringbuffer)
err = ev.epoller.AddEpollCtl(mapFD, ev.EventFdCnt)
if err != nil {
unix.Munmap(producer)
return nil, fmt.Errorf("failed to Epoll event: %s", err)
}
ev.RingCnt++
ev.EventFdCnt++
//Start channels read
ev.eventsStopChannel = make(chan struct{})
ev.eventsDataChannel = make(chan []byte)
ev.wg.Add(1)
go ev.reconcileEventsDataChannel()
return ev.eventsDataChannel, nil
}