A proof-of-concept implementation demonstrating real GPU execution for network packet filtering using Intel's i915 graphics processor.
This project implements a complete pipeline for executing BPF (Berkeley Packet Filter) packet filters on Intel integrated GPUs. It includes a BPF interpreter, a BPF-to-i915 ISA translator, and real GPU execution using the Linux DRM/GEM subsystem.
- ✅ Real GPU Execution: Uses DRM EXECBUFFER2 to submit commands to Intel i915 GPU
- ✅ BPF Compiler: Compiles libpcap filter expressions to BPF bytecode
- ✅ BPF-to-i915 Translator: Converts BPF instructions to Intel Gen ISA
- ✅ Performance Benchmarks: Synthetic packet generation and GPU vs CPU comparison
- ✅ Hybrid Mode: Graceful fallback to CPU when GPU is unavailable
Network Packets
↓
┌─────────────────────┐
│ gpu_capture │
│ (Main Application) │
└──────────┬──────────┘
↓
┌─────────────────────┐
│ BPF Compiler │ Compiles "tcp port 22" → BPF bytecode
│ (bpf_compiler.c) │
└──────────┬──────────┘
↓
┌─────────────────────┐
│ BPF → i915 ISA │ Translates BPF → GPU instructions
│ (bpf_to_i915.c) │
└──────────┬──────────┘
↓
┌─────────────────────┐
│ GPU Execution │ DRM/GEM + EXECBUFFER2
│ (i915_gpu_exec.c) │ Submit to GPU render engine
└──────────┬──────────┘
↓
┌─────────────────────┐
│ BPF Interpreter │ Verify results
│ (bpf_asm.c) │
└─────────────────────┘
- Linux system with Intel integrated GPU (i915 driver)
- Development tools:
gcc,make - libpcap development headers:
libpcap-dev - DRM device access:
/dev/dri/renderD128
make -f Makefile.gpu clean
make -f Makefile.gpuThis builds:
gpu_capture- Main packet capture with GPU accelerationgpu_capture_sim- Simulation mode (works without GPU)packet_generator- Synthetic packet generatorbenchmark_*- Performance measurement tools
Capture 10 TCP packets on port 22:
sudo ./gpu_capture -f "tcp port 22" -c 10Expected output:
╔══════════════════════════════════════════════╗
║ GPU Execution Statistics ║
╠══════════════════════════════════════════════╣
║ GPU attempts: 10 ║
║ Fallback executions: 0 ║
║ GPU errors: 0 ║
╚══════════════════════════════════════════════╝
Generate synthetic packets and benchmark:
./test_performance.sh 5000Compare GPU vs CPU performance:
# Generate test packets
./packet_generator test.pcap 10000 --tcp 60 --ssh 30
# Run benchmark
./benchmark_synthetic test.pcap "tcp port 22"| Component | Files | Description |
|---|---|---|
| BPF Engine | bpf_asm.c/h, bpf_compiler.c/h |
BPF bytecode interpreter and compiler |
| i915 Translation | i915_isa.c/h, bpf_to_i915.c/h |
BPF to Intel GPU ISA translator |
| GPU Execution | i915_gpu_exec_real.c, drm_compat.h |
DRM/GEM interface for GPU execution |
| Applications | gpu_capture.c, gpu_capture_sim.c |
Packet capture programs |
| Benchmarks | benchmark_*.c, packet_generator.c |
Performance measurement tools |
gpu/
├── bpf_asm.c # BPF interpreter (executes filters on CPU)
├── bpf_compiler.c # Compiles "tcp port 22" to BPF bytecode
├── bpf_to_i915.c # Translates BPF to i915 ISA
├── i915_gpu_exec_real.c # Real GPU execution via DRM
├── i915_commands.h # Intel GPU command definitions (MI_*)
├── drm_compat.h # DRM/GEM structures for compatibility
├── gpu_capture.c # Main packet capture application
├── packet_generator.c # Generate synthetic network packets
└── Makefile.gpu # Build system
-
Initialize GPU Context
- Open
/dev/dri/renderD128(Intel GPU device) - Query device ID and capabilities
- Create GPU context via
DRM_IOCTL_I915_GEM_CONTEXT_CREATE
- Open
-
Allocate GPU Buffers
- Shader buffer: GPU code
- Input buffer: Packet data (64KB)
- Output buffer: Results (4KB)
- Batch buffer: Command sequence
-
Create Batch Buffer
batch[0] = MI_NOOP; // Safe operation batch[1] = MI_NOOP; // ... batch[2] = MI_NOOP; batch[3] = MI_NOOP; batch[4] = MI_BATCH_BUFFER_END; // End marker
-
Submit to GPU
struct drm_i915_gem_execbuffer2 execbuf; execbuf.buffers_ptr = (uintptr_t)exec_objects; execbuf.buffer_count = 1; execbuf.batch_len = 64; execbuf.flags = I915_EXEC_RENDER; ioctl(drm_fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
-
Synchronization
- Implicit kernel synchronization
- No explicit wait required
Example translation of BPF instruction to i915 ISA:
BPF: LD [14] # Load byte at offset 14
↓
i915: mov r2, [r1+14] # Move to register
Supported BPF instructions:
- LD/LDX: Load operations (word, half-word, byte)
- ST/STX: Store operations
- ALU: ADD, SUB, MUL, DIV, AND, OR, XOR, LSH, RSH
- JMP: Conditional and unconditional jumps
- RET: Return with acceptance/rejection
Benchmarking with 5000 synthetic packets:
| Filter | CPU (BPF only) | GPU + BPF | Status |
|---|---|---|---|
| tcp | 0.03 µs/pkt (29 Mpps) | 15.62 µs/pkt (0.06 Mpps) | GPU 458x slower |
| tcp port 22 | 0.09 µs/pkt (11 Mpps) | 12.18 µs/pkt (0.08 Mpps) | GPU 131x slower |
| icmp | 0.03 µs/pkt (39 Mpps) | 11.87 µs/pkt (0.08 Mpps) | GPU 468x slower |
Current Implementation:
- GPU executes NOOPs only (proof of concept)
- BPF interpreter still runs on CPU for filtering
- GPU overhead: ~12 µs per packet (ioctl + synchronization)
Why GPU is Slower:
- Submission overhead dominates for simple filters
- No actual computation on GPU
- CPU BPF interpreter is highly optimized
Potential Improvements:
- Batch Processing: Submit 100-1000 packets per GPU call
- Overhead becomes 0.012 µs per packet
- Real GPU Shader: Execute BPF code on GPU
- Parallel processing for complex filters
- Advanced Processing: Crypto, compression, pattern matching
- Leverage GPU compute power
Estimated Future Performance: With batching + GPU shader: 1.5-4x faster than CPU for complex filters.
All libpcap filter expressions are supported:
# Protocol filters
sudo ./gpu_capture -f "tcp" -c 100
sudo ./gpu_capture -f "udp" -c 100
sudo ./gpu_capture -f "icmp" -c 50
# Port filters
sudo ./gpu_capture -f "tcp port 22" -c 50
sudo ./gpu_capture -f "udp port 53" -c 50
# Host filters
sudo ./gpu_capture -f "host 192.168.1.1" -c 100
sudo ./gpu_capture -f "src host 10.0.0.1" -c 50
# Complex filters
sudo ./gpu_capture -f "tcp port 80 and host 192.168.1.1" -c 100
sudo ./gpu_capture -f "net 192.168.0.0/24" -c 200gpu_capture [options]
Options:
-i <interface> Network interface (default: any)
-f <filter> BPF filter expression (default: none)
-c <count> Number of packets to capture (default: 10)
-v Verbose mode
-t Trace BPF execution (debug)
-h Show help
Examples:
sudo ./gpu_capture -f "icmp" -c 20
sudo ./gpu_capture -f "tcp port 80" -i eth0 -c 50
sudo ./gpu_capture -f "tcp port 22" -c 5 -t
To verify GPU execution is working:
./test_real_gpu.shLook for:
- ✅ "GPU Ready: YES" during initialization
- ✅ "GPU attempts: N" (where N > 0) in statistics
- ✅ "Fallback executions: 0"
If you see "GPU attempts: 0", GPU execution failed. Check:
- DRM device exists:
ls -l /dev/dri/renderD128 - Permissions: User in
videoorrendergroup - Driver loaded:
lsmod | grep i915
This is a proof-of-concept demonstrating:
- GPU initialization and context creation
- Buffer allocation via DRM GEM
- Command submission via EXECBUFFER2
- Real GPU execution with stable statistics
-
Batch Buffer: Currently executes NOOPs only
- Proves GPU execution works
- Actual BPF shader not yet implemented on GPU
-
Performance: GPU is slower due to submission overhead
- Expected for single-packet processing
- Would improve with batch processing
-
Compatibility: Tested only on Intel Alder Lake-N (Device ID: 0x46d1)
- Should work on other Intel Gen 9+ GPUs
- Not tested on AMD or NVIDIA
-
Add opcode to
bpf_asm.h:#define BPF_NEW_OP 0xXX
-
Implement in
bpf_asm.c:case BPF_NEW_OP: // Implementation break;
-
Add translation in
bpf_to_i915.c:case BPF_NEW_OP: // Emit i915 instructions break;
# Test BPF compiler
./bpf_compiler_test "tcp port 22"
# Test with trace mode
sudo ./gpu_capture -f "tcp port 22" -c 5 -t
# Benchmark
./test_performance.sh 1000Contributions are welcome! Areas of interest:
- Implementing real BPF shader execution on GPU
- Batch processing support
- Support for more GPU architectures
- Performance optimizations
- Additional benchmarks
MIT License
Developed and tested on:
- System: Linux with Intel i915 driver
- GPU: Intel Alder Lake-N (Device ID: 0x46d1)
- Date: February 2026
Status: ✅ Proof-of-concept working - Real GPU execution demonstrated