Code Monkey home page Code Monkey logo

bmc-cache's Introduction

BMC

Code for the NSDI'21 paper "BMC: Accelerating Memcached using Safe In-kernel Caching and Pre-stack Processing".

BibTex entry available here.

BMC (BPF Memory Cache) is an in-kernel cache for memcached. It enables runtime, crash-safe extension of the Linux kernel to process specific memcached requests before the execution of the standard network stack. BMC does not require modification of neither the Linux kernel nor the memcached application. Running memcached with BMC improves throughput by up to 18x compared to the vanilla memcached application.

Requirements

Linux kernel v5.3 or higher is required to run BMC.

Other software dependencies are required to build BMC and Memcached-SR (see Building BMC and Building Memcached-SR).

Build instructions

Building BMC

BMC must be compiled with libbpf and other header files obtained from kernel sources. The project does not include the kernel sources, but the kernel-src-download.sh and kernel-src-prepare.sh scripts automate the download of the kernel sources and prepare them for the compilation of BMC.

These scripts require the following software to be installed:

gpg curl tar xz make gcc flex bison libssl-dev libelf-dev

The project uses llvm and clang version 9 to build BMC, but more recent versions might work as well:

llvm-9 clang-9

Note that libelf-dev is also required to build libbpf and BMC.

With the previous software installed, BMC can be built with the following:

$ ./kernel-src-download.sh
$ ./kernel-src-prepare.sh
$ cd bmc && make

After BMC has been successfully built, kernel sources can be removed by running the kernel-src-remove.sh script from the project root.

Building Memcached-SR

Memcached-SR is based on memcached v1.5.19. Building it requires the following software:

clang-9 (or gcc-9) automake libevent-dev

Either clang-9 or gcc-9 is required in order to compile memcached without linking issues. Depending on your distribution, you might also need to use the -Wno-deprecated-declarations compilation flag.

Memcached-SR can be built with the following:

$ cd memcached-sr 
$ ./autogen.sh
$ CC=clang-9 CFLAGS='-DREUSEPORT_OPT=1 -Wno-deprecated-declarations' ./configure && make

The memcached binary will be located in the memcached-sr directory.

Further instructions

TC egress hook

BMC doesn't attach the tx_filter eBPF program to the egress hook of TC, it needs to be attached manually.

To do so, you first need to make sure that the BPF filesystem is mounted, if it isn't you can mount it with the following command:

# mount -t bpf none /sys/fs/bpf/

Once BMC is running and the tx_filter program has been pinned to /sys/fs/bpf/bmc_tx_filter, you can attach it using the tc command line:

# tc qdisc add dev <interface_name> clsact
# tc filter add dev <interface_name> egress bpf object-pinned /sys/fs/bpf/bmc_tx_filter

After you are done using BMC, you can detach the program with these commands:

# tc filter del dev <interface_name> egress
# tc qdisc del dev <interface_name> clsact

And unpin the program with # rm /sys/fs/bpf/bmc_tx_filter

License

Files under the bmc directory are licensed under the GNU Lesser General Public License version 2.1.

Files under the memcached-sr directory are licensed under the BSD-3-Clause BSD license.

Cite this work

BibTex:

@inproceedings{265047,
	title        = {{BMC}: Accelerating Memcached using Safe In-kernel Caching and Pre-stack Processing},
	author       = {Yoann Ghigoff and Julien Sopena and Kahina Lazri and Antoine Blin and Gilles Muller},
	year         = 2021,
	month        = apr,
	booktitle    = {18th {USENIX} Symposium on Networked Systems Design and Implementation ({NSDI} 21)},
	publisher    = {{USENIX} Association},
	pages        = {487--501},
	isbn         = {978-1-939133-21-2},
	url          = {https://www.usenix.org/conference/nsdi21/presentation/ghigoff}
}

bmc-cache's People

Contributors

yoanngh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bmc-cache's Issues

error while building bmc

Hi,
I'm tring to build bmc, got the following error while building

I'm running this build in in following environment:

  1. debian 11
  2. clang 11, llvm 11
  3. gcc 10.2.1
  4. downloaded the kernel source by running apt source linux, and the kernel version is 5.10.84
gcc -g -O2 -Wall -I. -I../linux-5.10.84/tools/lib -I../linux-5.10.84/tools/include/uapi  -o bmc bmc_user.c ../linux-5.10.84/tools/lib/bpf/libbpf.a -L../linux-5.10.84/tools/lib/bpf -l:libbpf.a -lelf
In file included from /usr/include/linux/kernel.h:5,
                 from ../linux-5.10.84/tools/include/uapi/linux/netlink.h:5,
                 from ../linux-5.10.84/tools/include/uapi/linux/if_link.h:6,
                 from bmc_user.c:20:
/usr/include/linux/sysinfo.h:9:2: error: unknown type name ‘__kernel_long_t’
    9 |  __kernel_long_t uptime;  /* Seconds since boot */
      |  ^~~~~~~~~~~~~~~
/usr/include/linux/sysinfo.h:10:2: error: unknown type name ‘__kernel_ulong_t’
   10 |  __kernel_ulong_t loads[3]; /* 1, 5, and 15 minute load averages */
      |  ^~~~~~~~~~~~~~~~
/usr/include/linux/sysinfo.h:11:2: error: unknown type name ‘__kernel_ulong_t’
   11 |  __kernel_ulong_t totalram; /* Total usable main memory size */
      |  ^~~~~~~~~~~~~~~~
/usr/include/linux/sysinfo.h:12:2: error: unknown type name ‘__kernel_ulong_t’
   12 |  __kernel_ulong_t freeram; /* Available memory size */
      |  ^~~~~~~~~~~~~~~~
/usr/include/linux/sysinfo.h:13:2: error: unknown type name ‘__kernel_ulong_t’
   13 |  __kernel_ulong_t sharedram; /* Amount of shared memory */
      |  ^~~~~~~~~~~~~~~~
/usr/include/linux/sysinfo.h:14:2: error: unknown type name ‘__kernel_ulong_t’
   14 |  __kernel_ulong_t bufferram; /* Memory used by buffers */
      |  ^~~~~~~~~~~~~~~~
/usr/include/linux/sysinfo.h:15:2: error: unknown type name ‘__kernel_ulong_t’
   15 |  __kernel_ulong_t totalswap; /* Total swap space size */
      |  ^~~~~~~~~~~~~~~~
/usr/include/linux/sysinfo.h:16:2: error: unknown type name ‘__kernel_ulong_t’
   16 |  __kernel_ulong_t freeswap; /* swap space still available */
      |  ^~~~~~~~~~~~~~~~
/usr/include/linux/sysinfo.h:19:2: error: unknown type name ‘__kernel_ulong_t’
   19 |  __kernel_ulong_t totalhigh; /* Total high memory size */
      |  ^~~~~~~~~~~~~~~~
/usr/include/linux/sysinfo.h:20:2: error: unknown type name ‘__kernel_ulong_t’
   20 |  __kernel_ulong_t freehigh; /* Available high memory size */
      |  ^~~~~~~~~~~~~~~~
/usr/include/linux/sysinfo.h:22:22: error: ‘__kernel_ulong_t’ undeclared here (not in a function)
   22 |  char _f[20-2*sizeof(__kernel_ulong_t)-sizeof(__u32)]; /* Padding: libc5 uses this.. */
      |                      ^~~~~~~~~~~~~~~~

Question on Benchmarks

Hi! I see that BMC is using UDP get requests for benchmarks.
I was wondering how you dealt with packet drops.
Did the open-loop generator retransmit requests after some time?

BMC map not updating

@YoannGh after attaching all filters, GET and SET operations on memcached are not reflecting on BMC kernel map[map_kcache]?

Client-side code?

Dear authors,

Would you mind sharing the client-side benchmark code?

Best,
Yang

autogen.sh error for memcached-sr

./autogen.sh

fatal: No names found, cannot describe anything.
aclocal...
autoheader...
automake...
autoconf...
configure.ac:8: warning: 'AM_CONFIG_HEADER': this macro is obsolete.
configure.ac:8: You should use the 'AC_CONFIG_HEADERS' macro instead.
./lib/autoconf/general.m4:2434: AC_DIAGNOSE is expanded from...
aclocal.m4:745: AM_CONFIG_HEADER is expanded from...
configure.ac:8: the top level
configure.ac:79: warning: AC_PROG_CC_C99 is obsolete; use AC_PROG_CC
configure.ac:82: warning: ac_ext=c
configure.ac:82: ac_cpp='$CPP $CPPFLAGS'
configure.ac:82: ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
configure.ac:82: ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
configure.ac:82: ac_compiler_gnu=$ac_cv_c_compiler_gnu
configure.ac:82: if test -n "$ac_tool_prefix"; then
configure.ac:82:   # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
configure.ac:82: set dummy ${ac_tool_prefix}gcc; ac_word=$2
configure.ac:82: { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
configure.ac:82: printf %s "checking for $ac_word... " >&6; }
configure.ac:82: if test ${ac_cv_prog_CC+y}
configure.ac:82: then :
configure.ac:82:   printf %s "(cached) " >&6
configure.ac:82: else $as_nop
configure.ac:82:   if test -n "$CC"; then
configure.ac:82:   ac_cv_prog_CC="$CC" # Let the user override the test.
configure.ac:82: else
configure.ac:82: as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
configure.ac:82: for as_dir in $PATH
configure.ac:82: do
configure.ac:82:   IFS=$as_save_IFS
configure.ac:82:   case $as_dir in #(((
configure.ac:82:     '' is m4_require'd but not m4_defun'd
lib/m4sugar/m4sh.m4:692: _AS_IF_ELSE is expanded from...
lib/m4sugar/m4sh.m4:699: AS_IF is expanded from...
./lib/autoconf/general.m4:2249: AC_CACHE_VAL is expanded from...
./lib/autoconf/programs.m4:41: _AC_CHECK_PROG is expanded from...
./lib/autoconf/programs.m4:101: AC_CHECK_PROG is expanded from...
./lib/autoconf/programs.m4:221: AC_CHECK_TOOL is expanded from...
./lib/autoconf/c.m4:452: AC_PROG_CC is expanded from...
configure.ac:82: the top level

tx_filter does not work?

After I start bmc, I can see that rx_filter has received data, but tx_filter has never been called.I don't see tx_filter being attached to the egress hook of tc in the code. Do I need to attach it separately?How to attach it?

Why does not extend the `data_end` during re-written the packet

When the client send GET to server, the packet only contains the GET abcd. In this example, the data_end - data = 8. So, if we want to re-write the value into the original packet, the packet size should be extended.

However, the packet only seemed to extend with 128 bytes length, but the maximum allowed length is 1500, then if the value is longer then 8, where to write the rest of value?

Deployment of BMC

I tried deploying BMC on my machine without much success. With your permission, I will now detail the issues I am facing:

There are several undefined values such as IPPROTO_UDP, IPPROTO_TCP, u16, u32 when I open the code with my VS Code editor. However, I noticed that the code compiles successfully, and the bmc_tx_filter can be properly attached to a network interface. The problem occurs when the program reaches the line "__be16 sport = udp->source" in the bmc_tx_filter function. My question is, can these undefined values cause execution issues in the kernel? If so, how can I resolve these undefined value problems?

Regarding the bmc_tx_filter function exposed at /sys/fs/bpf/, after tracing the execution, I noticed that the bmc_update_cache function is called with the instruction "bpf_tail_call(skb, &map_progs_tc, BMC_PROG_TC_UPDATE_CACHE)". Assuming that skb is properly defined and the constant BMC_PROG_TC_UPDATE_CACHE is also defined, I suspect that the issue might be related to the map map_progs_tc.
My question is, at what point are the data added to this map? Are these data loaded from a userspace program? In short, could you please provide some possible reasons for the failure of the bmc_update_cache function call?

After compiling BMC and obtaining the binary, I ran "sudo ./bmc wlo1" to attach the program to my Wi-Fi network interface. However, as you mentioned in the readme.md, it failed. Nevertheless, this instruction exposes bmc_tx_filter in /sys/fs/bpf/, allowing me to successfully attach bmc_tx_filter to my network interface using the commands mentioned in the readme.md.
My question is, how can I expose the bmc_rx_filter to attach it to my network interface for processing incoming packets?

I'm using Linux Mint with a kenel version of 5.4

Thank you. @YoannGh

"make" works under bmc folder but ./bmc eth0 churns error below:

"make" works under bmc folder but ./bmc eth0 churns error below:

; for (off = 4; off < BMC_MAX_PACKET_LENGTH && payload+off+1 <= data_end && payload[off] == ' '; off++) {} // move offset to the start of the first key
46: (1f) r7 -= r8
47: (b7) r1 = 54
48: (bf) r2 = r7
49: (07) r2 += -50
; for (off = 4; off < BMC_MAX_PACKET_LENGTH && payload+off+1 <= data_end && payload[off] == ' '; off++) {} // move offset to the start of the first key
50: (1d) if r7 == r1 goto pc+23
 R0=map_value(id=0,off=0,ks=4,vs=12,imm=0) R1_w=inv54 R2_w=inv(id=0) R6=ctx(id=0,off=0,imm=0) R7_w=inv(id=3) R8=pkt(id=0,off=0,r=54,imm=0) R10=fp0 fp-8=mmmm????
; for (off = 4; off < BMC_MAX_PACKET_LENGTH && payload+off+1 <= data_end && payload[off] == ' '; off++) {} // move offset to the start of the first key
51: (bf) r3 = r8
52: (0f) r3 += r1
last_idx 52 first_idx 41
regs=2 stack=0 before 51: (bf) r3 = r8
regs=2 stack=0 before 50: (1d) if r7 == r1 goto pc+23
regs=2 stack=0 before 49: (07) r2 += -50
regs=2 stack=0 before 48: (bf) r2 = r7
regs=2 stack=0 before 47: (b7) r1 = 54
53: (71) r3 = *(u8 *)(r3 +0)
invalid access to packet, off=54 size=1, R3(id=0,off=54,r=54)
R3 offset is outside of the packet
processed 52 insns (limit 1000000) max_states_per_insn 0 total_states 4 peak_states 4 mark_read 2

libbpf: -- END LOG --
libbpf: failed to load program 'bmc_rx_filter'
libbpf: failed to load object './bmc_kern.o'
Error: bpf_object__load_xattr failed

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.