eBPF’s Abilities and Limitations: The Truth - Liz Rice & John Fastabend, Isovalent

CNCF [Cloud Native Computing Foundation]
22 Mar 202429:32

Summary

TLDRIn this engaging session, Liz Rice and John Fastabend introduce and explore the capabilities of eBPF, a technology allowing custom programs to run within the Linux kernel. They debunk myths about eBPF's limitations, demonstrating its power by implementing the Turing-complete 'Game of Life' directly in eBPF. The discussion covers the evolution of eBPF, its current state, and its potential for complex tasks, emphasizing the vibrant community driving its continuous improvement.

Takeaways

  • 😀 Liz Rice and John Fastabend are presenting on BPF (Berkeley Packet Filter), emphasizing its power and potential for custom kernel behavior modification.
  • 🔧 BPF allows for running custom programs in the kernel, which can change the kernel's behavior by attaching to events, making it a versatile tool for system operations.
  • 🖥️ The kernel is central to operating systems, involved in hardware interaction, file access, network communication, and process management, making BPF's impact extensive.
  • 🛠️ There are numerous infrastructure tools built using eBPF, such as Cilium and Tetragon, which focus on networking, security, and observability.
  • 🚫 Common misconceptions about BPF's limitations, such as its inability to handle complex tasks like layer seven packet parsing, are being challenged in the presentation.
  • 🔄 The concept of 'Turing completeness' is discussed, highlighting that while BPF is not Turing complete, it is still capable of processing complex tasks within certain bounds.
  • 🔒 The BPF verifier is crucial for ensuring safety when BPF programs are loaded into the kernel, checking memory access, control flow, and preventing indefinite loops.
  • 🔄 BPF has evolved to include features like loops and timers, which enable more complex and long-running programs to be safely executed within the kernel.
  • 💡 The demonstration of running Conway's Game of Life within BPF showcases the capability of BPF to handle complex, ongoing computations.
  • 📈 The BPF community and ecosystem are continuously growing, with ongoing work to improve the verifier, compiler, and overall usability of BPF.
  • 📚 Resources for learning more about BPF, including books and labs, are available, and the presenters encourage engagement with the community for advancing BPF capabilities.

Q & A

  • What is eBPF and why is it significant in the context of the kernel?

    -eBPF, or Extended Berkeley Packet Filter, allows custom programs to run in the kernel, enabling changes to the kernel's behavior by attaching these programs to events. It's significant because the kernel is involved in all hardware-related operations of an operating system, such as file access, network communication, and memory allocation, as well as managing system processes and permissions.

  • What is the role of the kernel verifier in eBPF programs?

    -The kernel verifier checks eBPF programs to ensure they are safe to run. It verifies that the program can only read and write to allowed memory, has valid control flow, does not get stuck on the CPU, and properly manages locks and references.

  • Why was the concept of Turing completeness brought up in the discussion about eBPF?

    -Turing completeness was discussed to address misconceptions about the capabilities of eBPF. It was used to illustrate that eBPF can, in theory, process any task that a Turing machine can, given it has the ability to process an arbitrary amount of data and time and store states.

  • What is the Game of Life and how does it relate to eBPF?

    -The Game of Life is a cellular automaton that evolves based on a set of rules determined by the state of neighboring cells. It was used in the script to demonstrate that eBPF is capable of running complex tasks, as it was successfully implemented within an eBPF program.

  • How has the eBPF verifier evolved to accommodate more complex programs?

    -The verifier has evolved to support loops, allowing programs to repeat operations without the risk of running indefinitely. It also supports callbacks and iterations, enabling eBPF programs to perform tasks over time without locking up the CPU.

  • What are the practical limitations of eBPF programs in terms of instructions and loops?

    -While eBPF programs were initially limited to 4,000 instructions, this limit has been increased to 1 million instructions in newer kernel versions. Loops are allowed as long as they can be verified to terminate, ensuring the program does not run indefinitely.

  • How can eBPF programs handle memory allocation?

    -eBPF programs can handle memory allocation through the use of array maps, which are memory blocks allocated by the user space and given to the eBPF program. The size of these maps is limited by the system's available memory and the user space's allocation limits.

  • What are some of the practical benefits of not being fully Turing complete in certain eBPF applications?

    -Not being fully Turing complete can be beneficial in scenarios where bounded execution is desired, such as in parsers where an upper limit on execution time can prevent infinite loops, or in systems monitoring where it's important to avoid long-running processes that could impact system performance.

  • What is the relationship between eBPF and infrastructure tools like Cilium and Tetragon?

    -eBPF is used in infrastructure tools like Cilium and Tetragon for networking, security, and observability tasks. These tools leverage the capabilities of eBPF to perform complex operations within the kernel, improving efficiency and performance.

  • What is the future outlook for eBPF in terms of development and community growth?

    -The future outlook for eBPF is positive, with continuous improvements and evolution of the technology. The community is growing, and there is a vision of pushing more processing into the kernel, which could lead to even more powerful and efficient applications in areas like networking and system monitoring.

Outlines

00:00

📘 Introduction to BPF and Session Overview

The session begins with an introduction by Liz Rice and John Fastabend, who express excitement about discussing BPF (Berkeley Packet Filter). John, an expert in eBPF with nearly a decade of experience, clarifies that eBPF allows custom programs to run within the kernel, influencing its behavior by attaching to events. The kernel's role in operating systems is highlighted, emphasizing its involvement in hardware interactions, file access, network communication, and process management. The speakers aim to debunk misconceptions about eBPF's capabilities, particularly its alleged limitations in handling complex tasks like layer seven packet inspection and its supposed incompleteness compared to general-purpose programming languages.

05:01

🔍 Exploring eBPF's Potential and Limitations

The speakers delve into the concept of Turing completeness, explaining it as the ability to process any arbitrarily complex task, data, or time without bounds. They contrast this with eBPF's design, which includes intentional limitations to ensure safety and performance, such as bounded execution times. Examples of both useful and less useful Turing complete systems are given, including the Game of Life, which is Turing complete but not necessarily practical for certain applications. The benefits of bounded properties in eBPF are discussed, such as preventing infinite loops in parsers or kernel functions, which can be crucial for maintaining system stability.

10:01

🛠 The Role of the eBPF Verifier in Safeguarding Kernel Programs

John Fastabend explains the role of the eBPF verifier, a component that ensures the safety of programs running in the kernel. The verifier checks for memory access permissions, control flow integrity, and ensures that programs do not get stuck on the CPU indefinitely. It also verifies that locks and references are properly accounted for. The discussion highlights the evolution of eBPF, including the addition of features that allow programs to sleep, handle callbacks, and iterate, which have expanded the capabilities of eBPF beyond the original model.

15:02

🎲 Demonstrating Game of Life in eBPF

The speakers present a live demonstration of Conway's Game of Life implemented in eBPF, showing that complex, Turing complete tasks can be executed within the kernel. The demonstration involves a sensor added to Tetragon, an eBPF project, which generates and evolves a pattern of 'cells' according to the rules of the Game of Life. The core logic of the game is briefly explained, including the copying of cell states, iteration of rules, and updates sent to user space for visualization.

20:03

🔧 Evolution of eBPF and Overcoming Instruction Limits

The discussion addresses the evolution of eBPF, particularly the increase in the number of allowable instructions from 4,000 to 1 million, to accommodate more complex programs. The importance of loops in eBPF is highlighted, as they allow for more sophisticated program logic while still ensuring termination. The speakers also touch on the challenges of writing eBPF programs that are verified by the kernel, emphasizing the need for synchronization between human programmers, compilers, and the verifier.

25:03

🌐 Future Prospects and Encouraging Community Engagement

The session concludes with a look towards the future of eBPF, emphasizing its continuous improvement and expansion. The speakers encourage the audience to engage with the eBPF community, suggesting that with enough interest and collaboration, even more complex and diverse applications can be developed using eBPF. They highlight the potential for eBPF to handle more networking-related processing in the kernel and mention resources for learning more about eBPF, including books, labs, and community projects.

Mindmap

Keywords

💡eBPF

eBPF, or Extended Berkeley Packet Filter, is a revolutionary technology that allows for the running of custom programs within the Linux kernel. It is central to the video's theme as it enables the modification of kernel behavior through the attachment of eBPF programs to various kernel events. The script discusses the evolution and capabilities of eBPF, demonstrating its power through the implementation of complex tasks like the Game of Life directly in the kernel.

💡Kernel

The kernel is the core part of an operating system that has control over everything the system does, including hardware access, file operations, and network communication. In the context of the video, the kernel's significance is highlighted by its role in eBPF programming, where eBPF programs can be attached to kernel events to alter system behavior.

💡Turing Completeness

Turing completeness refers to the ability of a system to perform any arbitrary computation given unlimited time and resources. The video discusses the concept in relation to eBPF, addressing misconceptions about the limitations of eBPF and demonstrating that it can handle complex tasks indicative of Turing completeness, such as running the Game of Life.

💡Verifier

The verifier in the context of eBPF is a component that checks the safety of eBPF programs before they are loaded into the kernel. It ensures that the programs adhere to certain constraints, such as not reading unauthorized memory or causing the kernel to crash. The script explains how the verifier has evolved to support more complex eBPF programs, including those with loops.

💡Game of Life

The Game of Life is a cellular automaton devised by the mathematician John Conway. It is used in the video as a practical demonstration of the capabilities of eBPF, showing that it can execute a Turing complete program. The script describes how the Game of Life was implemented in eBPF, emphasizing the flexibility and power of eBPF for complex tasks.

💡Instruction Limit

The instruction limit in eBPF refers to the maximum number of instructions an eBPF program can have. Initially set to 4,000, this limit has been increased to accommodate more complex programs. The script discusses how the evolution of eBPF has led to an increase in this limit, allowing for more sophisticated programs to be written.

💡Looping

Looping is a programming construct that allows for the repetition of a block of code. The script explains how early versions of eBPF did not support loops due to verifier limitations but have since evolved to include this feature. This advancement is crucial for handling more complex tasks within eBPF programs.

💡Cilium

Cilium is an open-source project that utilizes eBPF for providing networking, security, and observability for microservices. It is mentioned in the script as an example of infrastructure tools built using eBPF, showcasing the practical applications of eBPF in the industry.

💡Tetragon

Tetragon is a project that is part of the script's discussion, used to demonstrate the capabilities of eBPF. It is shown to be capable of adding new sensors, such as the Game of Life, and is used to illustrate the flexibility and extensibility of eBPF in real-world applications.

💡Memory Management

Memory management in eBPF involves how programs handle memory allocation and access within the kernel. The script touches on this topic, explaining the use of array maps for memory blocks and the importance of ensuring that eBPF programs do not exceed the available system memory.

Highlights

Introduction to BPF (Berkeley Packet Filter) and its evolution to eBPF (extended BPF), allowing custom programs to run in the kernel and modify its behavior.

John's 10-year experience with eBPF and his role as an engineer in night surveillance, emphasizing his expertise in the field.

Explanation of the kernel's role in operating systems, particularly its involvement in hardware interactions, process management, and permissions.

Discussion on the capabilities of eBPF to change kernel behavior and its use in infrastructure tools for networking, security, and observability.

Misleading statements about the limitations of eBPF, such as its inability to implement complex layer seven packet inspection, debunked by the speakers.

Introduction of the concept of 'Turing completeness' and its relevance to eBPF's ability to process complex tasks and data.

Examples of Turing complete systems, including general-purpose programming languages and the Game of Life, to illustrate the concept.

Benefits of not being fully Turing complete, such as bounded processing for safety and performance in certain applications.

Live demonstration of running the Game of Life within eBPF, showcasing the capabilities of eBPF beyond traditional expectations.

Details on eBPF verifier's role in ensuring safety, memory access control, and preventing indefinite loops in eBPF programs.

Evolution of eBPF to support loops and iterations, overcoming early limitations and allowing more complex programs to run.

Comparison of eBPF instruction limits with real-world programs like Doom, Envoy, and Clang, highlighting the practicality of eBPF for large-scale applications.

Explanation of subprograms in eBPF and how they relate to function calls, enabling large programs to be executed within the kernel.

Discussion on the future improvements in eBPF, including better support for loops and increased ease of programming.

Practical applications of eBPF in cloud providers and distributions, indicating the growing adoption and integration of eBPF in the industry.

Resources for learning more about eBPF, including books, labs, and community projects, encouraging further exploration and contribution.

Final thoughts on the potential of eBPF, emphasizing its current capabilities and the ongoing efforts to expand its utility and accessibility.

Transcripts

play00:00

good morning thank you so much for

play00:02

coming to our session this morning just

play00:04

about still morning right uh I hope

play00:06

everybody's able to find a seat if you

play00:08

have got a seat next to you maybe

play00:10

shuffle along and and let people in uh

play00:13

yes so my name's Liz rice uh myself and

play00:17

John here do you want to say hi yeah hi

play00:19

my name is John fman I'm engineer night

play00:21

surveillance and excited to talk about

play00:23

BPF today I've been you know working on

play00:25

it for almost 10 years now so hopefully

play00:27

you guys get as excited as um as I am

play00:30

yeah

play00:32

so I mean as John says he's he works in

play00:34

the Kel right he is a proper expert in

play00:39

ebpf let's just quickly recap to make

play00:42

sure everybody understands what we're

play00:43

talking about with ebpf it allows us to

play00:46

run custom programs in the

play00:49

kernel so we can change the way the

play00:52

kernel behaves by loading ebpf programs

play00:55

there and attaching them to events why

play00:57

is the kernel interesting well the

play01:00

kernel is the part of the operating

play01:01

system that is involved whenever we're

play01:04

doing anything with Hardware so if

play01:06

you're accessing a file or sending

play01:09

receiving over a network or uh even

play01:12

allocating memory the Kernel's going to

play01:15

be involved the Kernel's also um

play01:18

managing the processes running on a

play01:20

system so it's looking after things like

play01:22

permissions and privileges so the kernel

play01:25

is involved in pretty much everything

play01:27

interesting with ef we can change the

play01:30

way that it

play01:32

behaves so already there are lots of

play01:36

really great infrastructure tools built

play01:40

using ebpf I mean we're both very

play01:42

involved in psyllium and uh cium sub

play01:44

project tetragon doing things like

play01:47

networking security observability there

play01:51

are also loads of other great projects

play01:53

out there and great products out there

play01:55

that are doing things in these kind of

play01:57

infrastructure tooling spaces

play02:02

but sometimes you'll hear statements

play02:04

that give the impression that there are

play02:07

limits to what you can do with ebpf so

play02:11

for example we've heard people saying

play02:13

yeah you can't really Implement like

play02:16

layer seven paing that's just too

play02:18

complex for ebpf or another thing that

play02:21

you'll quite often hear people saying is

play02:24

yeah but there are limits to what you

play02:25

can do with ebpf because it's not cheer

play02:27

and complete right so do we think those

play02:30

statements are true well a hint here is

play02:34

these things were not said by people who

play02:35

are working on

play02:37

ebpf we're going to explore these kind

play02:40

of statements

play02:42

today so I've said the term cheering

play02:45

completeness this is not going to be a

play02:47

computer science class it's not going to

play02:49

be like super pedantic about

play02:52

terminology but really what true

play02:55

incompleteness about is about is can we

play02:58

process some on arbitrarily complex task

play03:02

can we process an arbitrary amount of

play03:05

data can we continue processing for an

play03:09

unbounded amount of time do we have the

play03:12

ability to store States so that we can

play03:15

continue sort of process state so this

play03:17

is broadly speaking what true

play03:20

incompleteness is about

play03:23

right so I I think it's interesting um

play03:26

just to talk a little bit about some

play03:28

concrete examples right I mean we could

play03:30

talk about the like mathematical

play03:32

formulation of turn complete but that's

play03:34

perhaps not interesting to everyone here

play03:36

so like typically when we think about

play03:38

turning completeness people really

play03:39

talking about like your general purpose

play03:41

languages C C++ Java python go all the

play03:45

things that we um programmers love um

play03:48

but I I also want to point out that

play03:49

there's a lot of like really also

play03:51

interesting but maybe less interesting

play03:53

for programmers you know nobody really

play03:55

wants to write um your uh application in

play03:59

the one instruction set computer so

play04:02

that's a totally valid turing machine it

play04:05

is Turing complete but you know try to

play04:07

write a proxy with just the move

play04:10

instruction and it might not be quite as

play04:12

fun as you want um another example is

play04:14

The Game of Life that will go back to

play04:16

but there's just loads of these things

play04:18

and you know the the point is try not to

play04:20

equate I think turn completeness um with

play04:22

sort of usefulness as a programming

play04:24

language to um you know developers right

play04:28

um I also want to note that there's some

play04:30

like actual benefits of not being fully

play04:32

tur and complete sometimes um you might

play04:34

be interested for example in having a a

play04:37

parser um that is bounded and why would

play04:40

you want that you might want that

play04:42

because you don't want to receive a

play04:43

packet and then have your parser Loop

play04:45

forever really would like the thing to

play04:47

stop at some point um you know it's the

play04:50

same way like in BPF space where we do

play04:51

like CIS call and tetron we'll watch CIS

play04:53

calls or watch kernel functions right we

play04:55

really like to have an upper bound on

play04:56

the time that we're going to kind of

play04:58

impact the application or the operating

play05:00

system and when you do that you want to

play05:02

say like it's really nice to say you

play05:04

know this will not run longer than a

play05:06

millisecond or you know 500 NCS or

play05:08

something like this right and that

play05:10

really is not touring Complete because

play05:11

we're putting a bound on that

play05:13

environment but um there you know

play05:16

there's really concrete advantages to

play05:17

that as well so just want to you know

play05:19

kind of lay that out there and and kind

play05:21

of give you some examples of of turning

play05:23

complete things that are both useful and

play05:24

not useful and an example of maybe why

play05:26

you you know would want some bounded

play05:28

properties as well

play05:30

and true and completeness talks about an

play05:32

infinite tape right and there is no

play05:35

infinite tape in the world so in reality

play05:37

we're always dealing with just large

play05:39

rather than infinite yep

play05:42

exactly so that previous slide mentioned

play05:45

Conway's Game of Life and this is an

play05:47

example of something that's cheering

play05:48

complete so this is something that uh

play05:52

every step it it goes through

play05:54

generations every step and each of those

play05:58

steps the state of one cell is

play06:01

determined by it the state of the

play06:03

previous state of the cells around it so

play06:06

it's a little bit like an actual living

play06:08

cell if the cell has no uh living cells

play06:12

around it it's going to die of

play06:14

loneliness if it has too many cells

play06:16

around it that are alive it's going to

play06:18

dive overcrowding but if it's got the

play06:20

right number of cells uh around an empty

play06:22

space the cell will actually uh come to

play06:25

life so this is an example of something

play06:27

that can kind of go on for ever

play06:30

generating these

play06:33

patterns very kind of common example of

play06:35

something that's uh used as an

play06:37

equivalent of cheing completeness yeah

play06:40

so if this is an example of something

play06:41

that's cheing complete is it something

play06:44

that we can write in

play06:47

ebpf and one reason why you might

play06:50

think I don't think it can is because of

play06:53

this thing the ebpf

play06:56

verifier so when you load a program into

play06:58

the kernel the verifier is going to run

play07:02

o over this program and analyze the

play07:04

program and establish whether it's safe

play07:07

to run and one of the things I would

play07:09

normally say when I talk about whether

play07:11

it's safe to run I'll say it's not going

play07:13

to crash the kernel but I would also say

play07:15

that it's going to run to completion we

play07:17

might pause on that

play07:20

later you want to dive intoit more what

play07:23

what it's really doing yeah yeah so I I

play07:26

think um users of ebpf or or even people

play07:29

that are in the stack you know they

play07:31

might think about the verifier as this

play07:32

kind of thing that is there stopping you

play07:34

from writing interesting programs

play07:36

perhaps um as a konel developer though I

play07:40

want to kind of lay out what do we as

play07:42

developers of the Kel that we want to

play07:44

ensure that the Colonel's safe to run

play07:45

and all this kind what do we think the

play07:47

verifier is doing right and and

play07:48

specifically this is kind of my criteria

play07:51

um you know the first thing we always

play07:52

want to do when we load a BPF program in

play07:54

to the colonels we want to make sure

play07:55

that we can only read memory that is

play07:57

allowed by that program and by your

play08:00

permissions that you have when you load

play08:01

that program and and BPF has a whole

play08:03

series of places you can hook in the

play08:04

kernel you can hook kernel functions you

play08:06

can hook the networking stack um you can

play08:08

even hook user space and and depending

play08:10

on where you hook you'll have different

play08:12

permissions on what kind of memory you

play08:13

can read right so we want to make sure

play08:15

that your program is only reading memory

play08:16

it's supposed to and we definitely 100%

play08:19

want to make sure that you're only

play08:20

writing to memory that you're allowed to

play08:22

you know want to make sure that you're

play08:23

not writing to random spots in memory

play08:24

you're only writing to you know valid

play08:26

locations in your vpf program um the

play08:29

next one is we want to make sure that

play08:30

the control flow is well formed and that

play08:33

it's valid and in bounds we don't want

play08:34

you to jump your BPF program off into

play08:36

the kernel somewhere and run an

play08:37

arbitrary code and crash the kernel

play08:39

right don't want to make sure that

play08:40

happens and I think the fourth Point

play08:42

here is really interesting because we'

play08:44

we've actually evolved this over time

play08:46

it's like what does it mean for ebfp

play08:48

programs to be bounded in the kernel and

play08:51

if you think where the original BPF that

play08:53

meant the program ran to completion but

play08:56

over time we've sort of evolved BPF now

play08:59

BPF programs know how to sleep we know

play09:01

how to do callbacks and iterations we

play09:03

know how to keep a program running and

play09:05

we'll go into that in a little bit um

play09:07

and really what we want to verify in the

play09:09

verifier is that we don't get a Program

play09:12

stuck on the CPU so long that it looks

play09:14

and feels like the system is hung right

play09:16

and for kernel developers or or people

play09:19

that are really system level programmers

play09:20

I think this is a sort of intuitive

play09:22

concept because you've been writing in

play09:23

this low level if you're if you're a

play09:25

higher up in the stack and maybe an

play09:26

application programmer or um kind of a

play09:29

distrib systems programmer somewhere in

play09:30

there it may be foreign because um you

play09:33

don't have to worry about this stuff

play09:34

because the OS is doing all the context

play09:36

switching right you you never in never

play09:38

write an application in user space C++ C

play09:41

go whatever where you go like at this

play09:43

point I need to make sure that I release

play09:45

the CPU right because the the OS just

play09:47

deals with that for you right once you

play09:49

get yourself into the kernel into you

play09:50

kind of the deep system stuff you really

play09:52

need to um tell the OS when it's okay to

play09:57

um to let your program off the CP view

play09:59

right the reason we do this is really if

play10:01

you're in an interrupt context if you're

play10:03

uh trying to write some kind of locking

play10:05

and stuff like this we can't just you

play10:06

know release it um at any arbitrary

play10:09

Point um and then the last thing we want

play10:11

to do with the verifier is we want to

play10:12

make sure like locks and references are

play10:13

all accounted for and that that's sort

play10:14

of a an accounting detail but it's

play10:16

important if you're going to like

play10:17

reference a socket or reference a file

play10:20

um walk a path you want to make sure

play10:21

that those things exist when you're

play10:23

doing that and that's just a um kind of

play10:25

a correctness property so th those are

play10:27

the things um you know that

play10:30

that I think about when I'm working on

play10:31

the verifier or improving the verifier

play10:33

um over time

play10:35

so and I think as we'll see later this

play10:37

idea that ebpf continues to evolve and

play10:40

continues to improve over time because

play10:42

of the work that people like John are

play10:44

doing this is why we're able to perhaps

play10:48

do more with ebpf than you might imagine

play10:50

because it continues to improve yeah so

play10:54

all right John can we run Game of Life

play10:56

in ebpf all right we're gonna give it a

play10:58

try here because we like to do demos so

play11:01

what you see here is um this is just

play11:03

basically tetragon um but we added a new

play11:05

sensor to tetragon called Game of Life

play11:09

all right and so we're going to kick it

play11:12

off um what it did here is it just

play11:14

iterate created the very similar to what

play11:16

Liz just showed you with that um web app

play11:19

is it created a a

play11:21

map filled in some cells with some

play11:23

random pattern and we could load it from

play11:25

a BPF map or something if we wanted to

play11:27

but for the for the demo it's just a

play11:28

random map

play11:29

and now it's running and it's there it

play11:33

goes all right so while that's running

play11:35

Let's uh dig into how you were able to

play11:38

get this to to work

play11:41

yeah so this is just a brief I'm not

play11:43

going to go into all the details of

play11:45

everything here but this is basically

play11:47

the core um code that is running right

play11:50

now in the background and we'll get back

play11:52

to it but the important pieces I do want

play11:54

to call out is that very far left for

play11:57

you guys is do game this is our core

play12:01

game logic for life here and you can see

play12:03

kind of three things we copy the cell

play12:05

map it's basically taking the Old State

play12:07

copying it into the new state so that we

play12:09

have a good State for the next iteration

play12:12

we do the next iteration which is all of

play12:14

those rules are run that Liz was talking

play12:16

about you check to see if your um if

play12:18

your neighbors are alive Al or you

play12:20

create a new cell or you remove a new

play12:22

cell so that's the sort of the business

play12:24

logic of this program and then we send

play12:26

an update all right so what the update

play12:29

it does is it sends that map State up to

play12:31

user space you know unfortunately you

play12:34

know I don't have a a BPF Graphics

play12:37

Library yet so you know if somebody's

play12:40

interested and they have like a GPU

play12:41

Shader from BPF or something to come

play12:43

talk to me let's make it happen but I

play12:46

couldn't do it from BPF so I had to send

play12:47

the map up to user space slightly

play12:50

disappointing but doesn't really impact

play12:51

you know the the logic of the game right

play12:54

so the user space is actually taking

play12:55

that BPF map and just drawing it on the

play12:57

screen there is what you were seeing and

play12:59

then the last piece is this run next

play13:01

which just reruns the business log but

play13:03

goes back to the beginning of du game

play13:04

and runs it again every two seconds all

play13:06

right and we'll talk about how that

play13:08

happens other slides you can get to in

play13:10

in your in your spare time later if

play13:11

you're

play13:12

interested so you may have heard that

play13:16

ebpf programs are limited to only a

play13:19

small number of instructions so maybe

play13:21

let's dive into that yeah um this is you

play13:24

know what what's really interesting here

play13:26

is you know when we first landed BPF and

play13:29

414 um back in like 2015 kind of the

play13:32

first

play13:33

iterations um we really started at 4,000

play13:37

instructions and like why did we pick

play13:39

4,000 instructions because it seemed

play13:40

like a good number it's you know Colonel

play13:42

developers like you know like numbers

play13:44

with k at the end of them 496 sounds

play13:46

good right

play13:48

um that was interesting but we very

play13:50

quickly realized that you know 496 is

play13:53

kind of small right you might want more

play13:55

instructions um and the the other thing

play13:57

I think is important

play14:00

why do we have to have a limit was not

play14:03

primarily because um we need the program

play14:05

to terminate in some finite time and we

play14:07

decided 4K instructions was a good

play14:09

amount of time but I think it's really

play14:11

if you think about it we have to verify

play14:12

that program and we really want to make

play14:14

sure that when you load a program into

play14:15

the kernel it takes some reasonable

play14:19

amount of time you know less than a

play14:20

second right if you loaded a 20 million

play14:24

um line code program perhaps maybe it

play14:27

would take 20 seconds and you know we

play14:28

kind of thought well a long time right

play14:30

so keep it bounded but at one some point

play14:33

we decided that 4K was just too limiting

play14:35

people want to write things that are

play14:36

bigger than 4K and so in 54 Colonels we

play14:39

went to 1 million um and and kind of

play14:43

beefed up that allow allowable

play14:46

limit um just kind of follow up you

play14:49

might wonder like that's interesting

play14:51

John but give me some kind of reference

play14:53

you know like how many instructions

play14:54

really is a million instructions and so

play14:56

what I did is just this is kind of a

play14:58

napkin approach you know know go look at

play15:00

a few programs I had on my laptop of

play15:01

course I had Doom right got to have Doom

play15:03

there so you know I took a look it's you

play15:06

know less than a,k instructions for a

play15:08

for a basic kind of Doom clone if you

play15:11

think of the like the original Dune and

play15:13

then I had Envoy on my system because um

play15:15

you know we work on celium and tetragon

play15:16

and that uses Envoy as a kind of one one

play15:19

option for doing proxies I took a look

play15:21

15 million instructions and then clang

play15:25

uh you know compiler stuff 26 million

play15:27

instructions so that's kind of where

play15:28

we're at

play15:29

um you know you might come back and say

play15:31

okay Doom is only maybe less than a

play15:33

thousand 100,000 instructions but John

play15:35

it might have some Loops how are you

play15:36

going to deal with that right and then

play15:38

stay tuned we'll talk about how to get

play15:40

these kind of much larger cases going

play15:43

forward so there's also this idea that

play15:47

and it was true in the early days that

play15:49

you couldn't do loops in BPF because you

play15:51

were only able to jump forwards in a

play15:53

program yeah so this was something that

play15:55

we put in and it not because necessarily

play15:58

PF like um folks that were working on

play16:00

BPF thought hey Loops are somehow bad it

play16:03

was purely like the verifier needs to

play16:05

somehow ensure that this isn't going to

play16:07

run forever right um and that was the

play16:10

early days and so we simplest thing to

play16:14

do is look at your program and ensure

play16:16

that you don't have any jumps to code

play16:18

that you've already been to right we

play16:20

want to make sure that the program

play16:21

control flow is a d basically a graph

play16:24

and no Loops in that graph um so early

play16:28

PR programming what we did is we did

play16:30

something called called an unroll

play16:31

basically you tell the compiler I'm not

play16:34

allowed to do loops please just cut and

play16:35

paste this code right it'd be very

play16:37

similar to a developer just doing like

play16:38

cut cut paste their Loop many many times

play16:42

you kind of do that but you can see very

play16:43

quickly that you're not going to be able

play16:45

to get things to to run very long right

play16:48

especially in 4k instructions but even

play16:49

with a million instructions you know

play16:51

you're kind of only so much can be

play16:55

done yeah so clearly not a not an

play16:57

approximation of forever right when

play16:59

you're kind of in this space um the next

play17:03

piece here is we

play17:04

have we as we were evolving BPF this

play17:08

became a very obvious sort of limitation

play17:11

right the fact that the limitation in

play17:13

two way two ways I'd say is one is it

play17:15

makes it hard to write programs and two

play17:16

it makes it hard for the compiler to

play17:17

compile things you know optimize your

play17:19

code basically so we added Loops this is

play17:22

this allows the verifier to look at a

play17:24

loop and verify that that Loop is going

play17:25

to terminate um and then we added an

play17:28

actually helper call for cases where you

play17:31

want the BPF program to do a loop but

play17:33

the compiler human and verifier are

play17:34

having trouble all agreeing on how that

play17:36

Loop is going to look like actually and

play17:38

if you think about the assmbly code and

play17:39

object code when it's loaded in the

play17:41

compiler and once you have this you can

play17:42

write statements like that at the bottom

play17:44

where you have a four Loop H here is a

play17:46

um is a you know kind of a pound Define

play17:49

or a global variable that tells you the

play17:50

max loop size and and the verifier is

play17:52

perfectly happy with this um today so

play17:55

that's we're allowed to Loop but we're

play17:57

not allowed to Loop indefinitely at this

play17:59

point right correct yep that's why we

play18:00

have that Max there and so if you just

play18:03

kind of take a layout of what kernels

play18:05

these were added in you know you 414 and

play18:07

419 we had our kind of basic cut and

play18:09

paste model 54 we added Loop support so

play18:12

the colonel could figure out how if

play18:14

these Loops are going to terminate 515

play18:16

made a bunch of technical improvements

play18:17

to that so the verifier got much better

play18:19

at finding these things and then 61 we

play18:21

added this um call that you can do to

play18:23

basically you as the human can tell the

play18:26

verifier through the compiler that hey

play18:28

this is going to be a loop please take a

play18:30

look at it and make sure that it

play18:31

terminates yeah and I just wanted to

play18:33

call this out because um you know we

play18:34

have people working on this the the BPF

play18:36

site is just evolving continuously so

play18:39

there's another type of loop coming

play18:40

we're not going to talk about it here

play18:41

find me afterwards if you want but even

play18:44

even uh more improved version of looping

play18:46

is is on the way

play18:49

so Okay so we've

play18:51

got a limit to how many uh instructions

play18:55

but it's quite a big limit we can Loop

play18:58

yeah yeah

play19:00

what about these big program what about

play19:01

these big programs can we do Envoy or

play19:03

Clan could you write in theory a $15

play19:05

million 15 million instruction ppf

play19:09

program uh that would be great right um

play19:13

the thing that is interesting and I I

play19:15

think it's it's a choice we made very

play19:17

early on in the BPF um kind of verifier

play19:19

is we call these things subprograms and

play19:22

we said subprograms must terminate

play19:25

roughly equivalent a subprogram is is

play19:27

really roughly equivalent to a function

play19:29

and so the limits are actually on the

play19:30

functions not on the entire program and

play19:33

as sort of a back a napkin you can do

play19:35

like um 31 function calls or 31

play19:39

subprograms is what a BPF programmer

play19:41

would say and really that gets you up to

play19:44

you know 15 million without much trouble

play19:46

31 million actually with 31 calls right

play19:48

um You can actually do more in the

play19:49

kernel depending on where you're

play19:50

actually being where you're hooking but

play19:53

sort of as a rough estimate we can

play19:54

pretty easily get to 31 million

play19:56

instructions which is a really big

play19:57

program right you can all of clay is not

play19:59

even 31 million instructions so give you

play20:02

some words of warning you know this uh

play20:06

the verifier is getting better and

play20:08

better and better and people are working

play20:09

on this and making it usable for humans

play20:11

um to write code right um but really the

play20:13

trick right now is the human's going to

play20:15

write the code the compiler's going to

play20:17

compile it and the verifier is going to

play20:18

verify it and they all need to kind of

play20:20

be in sync and understand what's going

play20:21

on right um to get the kind of something

play20:24

into the kernel right and this is why

play20:25

it's just not as easy as it should be

play20:27

you know the team is working on this um

play20:30

I fully predict that in 5 years 10 years

play20:33

something like that BPF will be easier

play20:35

and easier to write and and kind of open

play20:37

up that that uh number of people that

play20:40

are you know willing to dive in and

play20:42

really get into the BPF

play20:43

space um and then the last thing you

play20:46

know if you do go this way and you maybe

play20:48

have the right mentality it might be

play20:50

addictive you might try to write things

play20:52

like Tetris and doom and Quake and Game

play20:54

of Life in the kernel um you know the

play20:57

utility of that is um kind of great for

play20:59

cubec con talks right I'm not sure you

play21:02

know like is surveillant Enterprise will

play21:05

have a or you know yeah we we're doing

play21:06

the I surveillant Enterprise launch of

play21:08

Game of Life yeah exactly you heard it

play21:10

here first yeah yep um so Game of Life

play21:14

you know it goes on forever so what

play21:16

about this idea of not

play21:19

terminating yeah so this is an

play21:21

interesting one right so like if you

play21:22

want something to run forever I've told

play21:24

you there's a maximum instructions

play21:25

you're like well certainly you're going

play21:26

to run out of those instructions at some

play21:28

point right and this really goes back to

play21:30

this kind of carefully worded um point

play21:33

in the verifier where we said well it's

play21:36

not just that we want the program to

play21:38

terminate it's that we want to release

play21:40

the CPU that we're on we don't want to

play21:42

lock a CPU down and like we said early

play21:45

on early kernel versions that meant the

play21:47

program terminated there was no

play21:49

exceptions to that the program was done

play21:51

um but when we evolved the um kind of

play21:54

Kernel and BPF and the verifier and the

play21:56

compiler as well like all these pieces

play21:58

are moving moving forward we developed

play22:00

these kind of other ideas of kind of Rel

play22:03

other ways to release the CPU um one of

play22:06

them was an iterator this is a program

play22:08

that can like run over every file in a

play22:11

directory right it doesn't matter how

play22:12

many files are in there and it'll

play22:14

basically ensure that the CPU doesn't

play22:16

get locked up right it's been iterating

play22:17

for too long it'll release let something

play22:20

else run the scheduler will come back

play22:22

and say okay BPF program you can run

play22:24

again um we've allowed programs to sleep

play22:27

now so this is really really useful if

play22:29

like you're trying to read some memory

play22:30

and it gets the page fold so the memory

play22:32

is not in in the page cache so you can't

play22:35

just read it because it's not there um

play22:38

and so you have to do something called a

play22:39

page fault which requires sleeping

play22:41

anyways it's it's in the details but

play22:43

super important if you're be program

play22:45

tries to read some memory and it you

play22:46

know you don't want to get a fault we

play22:48

added timer call backs this is basically

play22:50

a way to say hey I've done something

play22:52

useful um I'm going to release my

play22:55

program let the OS do something and then

play22:57

just call me back at some time you can

play22:59

even set this to zero which just looks

play23:01

like hey I'm done um but you know I'm

play23:04

safe to release but call me as soon as

play23:05

you can again

play23:08

so and I guess the last thing is you

play23:11

know how can an ebpf program allocate

play23:14

some amount of memory yeah so the um

play23:19

there's really a bunch of different ways

play23:20

we can do this but the most obvious one

play23:22

is that we have these array maps and the

play23:25

maps are basically memory blocks that

play23:27

the program can all ate or user space

play23:29

can allocate and then give to the

play23:31

program and um these can be actually

play23:35

quite large the basic limit of these is

play23:37

you know like whatever the user space is

play23:38

allowed to allocate based on its cgroup

play23:41

if it's not in a cgroup they can be more

play23:42

or less unbounded and kind of related to

play23:44

system memory and all this kind of stuff

play23:45

we have some limits but those are tied

play23:47

to like how much RAM you have in your

play23:48

system right same type of thing that a

play23:51

user space application has you can't

play23:52

allocate more memory than you know your

play23:54

system has available right so so we

play23:57

could pot entally have a pretty big

play24:00

absolutely uh sort of field of play for

play24:03

our game yeah yeah and you know even you

play24:05

know four gigabytes we've sort of

play24:07

optimized this case in newer kernels to

play24:09

allow applications up to four gigabytes

play24:11

of virtual memory um amazing stuff so

play24:15

with all of these component pieces put

play24:17

together we've really avoided the

play24:19

limitations right we don't have uh we

play24:22

well we don't really have an effective

play24:24

limit on how many instructions we don't

play24:26

have an effective limit on how many time

play24:28

times we can call a loop effectively

play24:31

because we can use these timer call

play24:32

backs shall we see if it's still running

play24:35

what do you think is it still

play24:37

running yeah so see how good I I am at

play24:40

programming right if it's still running

play24:42

or if it's still going so here you go

play24:45

looks like it's still up and running um

play24:48

you can see it's still doing its thing

play24:50

um and if you go back to kind of some of

play24:51

the details um I think we can talk for a

play24:54

couple seconds here basically if you

play24:56

think about that first program that was

play24:58

doing in that due game you know what we

play25:00

see here is it does a copy of the last

play25:03

state into the new state runs the logic

play25:06

that's what moves all these kind of

play25:08

fields around on the screen right and

play25:11

then um sends it up to user space and

play25:14

then this is the user space just kind of

play25:17

printing the dots you know one's on zero

play25:20

is off printing the dots on the screen

play25:22

and you can see it kind of it keeps

play25:23

evolving over time every every two

play25:25

seconds is the limit um just so that you

play25:27

all can see it

play25:28

um so there it goes and it's it's still

play25:31

going you told me a pretty interesting

play25:33

thing about like the fact that you can't

play25:35

predict the future State yeah yeah one

play25:38

of the neat things about like game and

play25:40

life and and a lot of terrain machines

play25:41

in general is that this thing will um

play25:44

you you if you want to know what the

play25:45

thousandth iteration is or the 10,000th

play25:47

iteration of this there's no shortcut to

play25:49

that from a from a kind of a

play25:51

mathematical side you can't say tell me

play25:53

I'm not going to actually run this thing

play25:54

10,000 steps let me just run it two

play25:56

times and then tell me what the answer

play25:58

is is so like it's interesting in that

play25:59

sense is you have to you really have to

play26:01

run this thing to figure it out right um

play26:04

and uh we could rerun it and see what

play26:06

pattern we get you know sometimes you'll

play26:08

get interesting patterns this one is

play26:09

still running um since it's a random

play26:11

pattern we could have been unlucky right

play26:12

and had like the screen be black when we

play26:14

turned this on but um you know but it

play26:16

didn't it work Round of Applause for a

play26:18

live demo please

play26:25

great perfect yep go back

play26:30

amazing so we have Game of Life in ebpf

play26:33

which is really a good demonstration

play26:35

that you can today do arbitrarily

play26:38

complex tasks with

play26:42

ebpf so those statements about things

play26:45

like can you do layer sing protocol

play26:48

passing in

play26:49

ebpf absolutely it's possible doesn't

play26:53

necessarily mean that all these things

play26:55

have been implemented yet but it is

play26:58

possible to do you know pretty much any

play27:01

processing maybe not necessarily to do

play27:03

the display part yet but the actual

play27:05

computation part the processing part and

play27:08

and I would say the key is there not yet

play27:10

I mean I I think the really interesting

play27:12

thing or one takeaway I think from this

play27:13

talk is like you know there's a bunch of

play27:15

folks in the kernel in the compiler

play27:17

community and you know we're working to

play27:18

make BPF better and make BPF improve BPF

play27:22

so if you have a use case and if your

play27:24

use case is graphics on GPU for your

play27:26

cubec con talk come talk talk to me it

play27:29

would be interesting you know like so

play27:31

these things can be we can make them

play27:32

happen right you know in 10 years ago

play27:34

when we got started we had like this

play27:36

very small scope and you know it just

play27:37

keeps growing and growing the community

play27:39

is getting bigger you know it's kind of

play27:41

its own sub Community with ebpf but um

play27:44

you know I I think definitely if you

play27:46

have a use case and you think there's

play27:48

value in it you going come talk to us

play27:49

and we can we can figure out what it

play27:51

what it takes to make it happen and I

play27:53

think when we think about selum you know

play27:55

selum is using ebpf for lot of network

play27:59

based processing and you know our vision

play28:02

is to push more and more of that

play28:04

processing into the kernel so yeah

play28:06

there's tons of networking related

play28:08

processing happening in user space today

play28:11

where I'm not going to tell you that you

play28:12

know we're writing it and it's going to

play28:13

be released next week that's not what

play28:14

I'm trying to say but I'm trying to say

play28:16

the vision is that more and more of this

play28:19

processing will be happening in the

play28:21

kernel yeah and I I mean I I would also

play28:23

just say absolutely the same for I I

play28:24

work on tetron mostly these days it's

play28:26

the same thing early we started on

play28:27

tetron a couple years back you know

play28:29

there was missing features we added the

play28:31

features and then you you figure out how

play28:32

to bridge the gap in the interum but if

play28:34

you look forward in two three years you

play28:36

can see like all the cloud providers

play28:38

will have that kernel all the uh

play28:40

distributions will have that kernel and

play28:41

you can start to use that functionality

play28:43

right and that's I think um a really

play28:45

powerful kind of kind of point of the

play28:47

open source effort

play28:50

here so I hope that's convinced you that

play28:53

ebpf is well probably more powerful than

play28:55

you

play28:56

thought if you want to learn more about

play28:58

ebpf we have uh some books that you can

play29:01

download from is surveillent.com there's

play29:03

also a ton of really great Labs on the

play29:05

website there is the ebpf doio site

play29:08

which has loads of information about

play29:09

ebpf itself and lots of projects that

play29:12

are being uh built using it uh we're

play29:15

also doing uh well I'm going to be

play29:17

signing some books at the I surveillant

play29:18

booth at 1:00 today so if you want to

play29:20

come around and pick up a copy of the

play29:21

book then uh please say hello and with

play29:25

that I hope you have a wonderful wrap po

play29:28

to the end of your

play29:30

keepon

Rate This

5.0 / 5 (0 votes)

Ähnliche Tags
eBPFLinux KernelProgrammingGame of LifeSyscallNetworkingObservabilitySecurityInfrastructureTechnical Talk
Benötigen Sie eine Zusammenfassung auf Englisch?