Skip to content

Commit

Permalink
Push kbenchmark for getting
Browse files Browse the repository at this point in the history
  • Loading branch information
AdityaAtulTewari committed Dec 27, 2024
1 parent feebdac commit 42e3dfd
Show file tree
Hide file tree
Showing 8 changed files with 507 additions and 6 deletions.
42 changes: 42 additions & 0 deletions module/fstore/fstore.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ int fstore_get(u64 map_name,
void* value,
size_t value_size);
EXPORT_SYMBOL_GPL(fstore_get);
int fstore_get_value_size(u64 map_name,
size_t* size);
EXPORT_SYMBOL_GPL(fstore_get_value_size);
int fstore_get_num_keys(u64 map_name,
size_t* size);
EXPORT_SYMBOL_GPL(fstore_get_num_keys);

struct file_operations fops = {
.owner = THIS_MODULE,
Expand Down Expand Up @@ -159,6 +165,42 @@ int fstore_get(u64 map_name,
return err;
}

int fstore_get_value_size(u64 map_name,
size_t* size) {
int err = 0;
struct bpf_map* map;
int i = 0;
hash_t* item = NULL;
hash_for_each_possible_rcu_notrace(fstore_map, item, hnode, map_name) {
i++;
map = item->map;
if(IS_ERR(map)) err = -EKEYEXPIRED;
else *size = map->value_size;
}
// If either of these are hit we can safely exit
if(err == -EKEYEXPIRED) return -EKEYEXPIRED;
if(i == 0) return -ENOKEY;
return err;
}

int fstore_get_num_keys(u64 map_name,
size_t* size) {
int err = 0;
struct bpf_map* map;
int i = 0;
hash_t* item = NULL;
hash_for_each_possible_rcu_notrace(fstore_map, item, hnode, map_name) {
i++;
map = item->map;
if(IS_ERR(map)) err = -EKEYEXPIRED;
else *size = map->max_entries;
}
// If either of these are hit we can safely exit
if(err == -EKEYEXPIRED) return -EKEYEXPIRED;
if(i == 0) return -ENOKEY;
return err;
}

static long fstore_ioctl(struct file *file,
unsigned int cmd,
unsigned long data)
Expand Down
6 changes: 3 additions & 3 deletions module/test/e2e/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ echo:
@echo OUT_DIR ${OUT_DIR}
@echo EXPORT_BUILD ${EXPORT_BUILD}
@echo DIRS ${DIRS}
@$(foreach path,${DIRS},echo ${path}: && ${MAKE} ${EXPORT_BUILD} -C ${path} echo)
@$(foreach path,${DIRS},echo ${path}: && ${MAKE} ${EXPORT_BUILD} -C ${path} echo;)

test:
@$(foreach path,${DIRS},${MAKE} ${EXPORT_BUILD} -C ${path} test)
@$(foreach path,${DIRS},${MAKE} ${EXPORT_BUILD} -C ${path} test;)

undeploy:
@$(foreach path,${DIRS},${MAKE} ${EXPORT_BUILD} -C ${path} undeploy)
@$(foreach path,${DIRS},${MAKE} ${EXPORT_BUILD} -C ${path} undeploy;)
60 changes: 60 additions & 0 deletions module/test/e2e/bench_kernel_get/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
BUILD ?= build
ROOT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
OUT_DIR := ${BUILD}/$(notdir ${ROOT_DIR:/=})

TEST_SRC := $(wildcard *.cpp)
BLD_OUT := $(patsubst %.cpp,%,${TEST_SRC})
FULL_OUT := $(addprefix ${OUT_DIR}/,${BLD_OUT})

KERNEL_MOD_STUB = bench_kernel_get

KERNEL_MOD_OUT = ${KERNEL_MOD_STUB}.ko

KERNEL_MOD_NAME = $(patsubst %.ko,%,${KERNEL_MOD_OUT})

TMP_KERNEL_MOD_OUT = $(addprefix /tmp/,${KERNEL_MOD_NAME})

KBUILD_EXTRA_SYMBOLS := $(realpath ../../../fstore/Module.symvers)
obj-m += ${KERNEL_MOD_STUB}.o

default: ${OUT_DIR}/${KERNEL_MOD_OUT}

echo:
@echo BUILD ${BUILD}
@echo ROOT_DIR ${ROOT_DIR}
@echo OUT_DIR ${OUT_DIR}
@echo KBUILD ${KBUILD}
@echo TEST_SRC ${TEST_SRC}
@echo BLD_OUT ${BLD_OUT}
@echo FULL_OUT ${FULL_OUT}
@echo KERNEL_MOD_OUT ${KERNEL_MOD_OUT}
@echo TMP_KERNEL_MOD_OUT ${TMP_KERNEL_MOD_OUT}
@echo KBUILD_EXTRA_SYMBOLS ${KBUILD_EXTRA_SYMBOLS}

${OUT_DIR}:
mkdir -p $@

${OUT_DIR}/${KERNEL_MOD_OUT}: ${OUT_DIR}/%.ko : %.c ../../../fstore/fstore.h | ${OUT_DIR}
+${MAKE} KBUILD_EXTRA_SYMBOLS=${KBUILD_EXTRA_SYMBOLS} -C ${KBUILD} M=${ROOT_DIR} modules
cp $*.ko ${OUT_DIR}/${KERNEL_MOD_OUT}
+${MAKE} -C . clean

${TMP_KERNEL_MOD_OUT} : /tmp/% : ${OUT_DIR}/%.ko
-sudo rmmod $*
sudo insmod $<
touch $@

undeploy:
-sudo rmmod ${KERNEL_MOD_NAME}
-rm ${TMP_KERNEL_MOD_OUT}

${FULL_OUT}: ${OUT_DIR}/% : %.cpp ../../../fstore/fstore.h | ${OUT_DIR}
${CXX} -O3 -I/usr/src/linux-headers-$(shell uname -r)/include/ \
-std=gnu++2b $< -o $@

test: ${TMP_KERNEL_MOD_OUT} ${FULL_OUT}
@$(foreach path,${FULL_OUT}, printf "$(shell basename $(path)) ... "; \
sudo $(path) && printf "pass\n" || printf "fail\n";)

clean:
+${MAKE} -C ${KBUILD} M=${ROOT_DIR} MO=${OUT_DIR} clean
210 changes: 210 additions & 0 deletions module/test/e2e/bench_kernel_get/bench_kernel_get.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/*
* get_set.h - Kernel module for testing get ops inside kernel from fstore
*/

#include <linux/module.h> /* Needed by all modules */
#include <linux/printk.h> /* Needed for pr_info() */
#include <linux/fs.h> /* Needed for ioctl api */
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/hashtable.h>
#include "../../../fstore/fstore.h"
#include "bench_kernel_get.h"

#define DEBUG 1

dev_t dev = 0;
static struct class *dev_class;
static struct cdev bench_get_many_cdev;

int fstore_get(u64 map_name,
void* key,
size_t key_size,
void* value,
size_t value_size);

int fstore_get_value_size(u64 map_name,
size_t* size);

int fstore_get_num_keys(u64 map_name,
size_t* size);

static long get_set_ioctl(struct file *file,
unsigned int cmd,
unsigned long data);

static struct file_operations fops = {
.owner = THIS_MODULE,
.read = NULL,
.write = NULL,
.open = NULL,
.unlocked_ioctl = get_set_ioctl,
.release = NULL,
};

typedef struct bench_get_args gsa_t;

typedef struct ShiftXor shift_xor;

__u32 returner;

typedef int (*get_fn)(__u64, void*, size_t, void*, size_t);

static int bench_get_many(__u64 map_name,
__u64 times,
__u64* nanos,
get_fn fn)
{
int err = 0;
shift_xor rand = {1, 4, 7, 13};
size_t size;
size_t key_bound;
err = fstore_get_value_size(map_name, &size);
if(err != 0) {
pr_err("%s:%d: Getting value size not working\n",
__FILE__, __LINE__);
return err;
}
err = fstore_get_num_keys(map_name, &key_bound);
if( err != 0) {
pr_err("%s:%d: Getting number of keys not working\n",
__FILE__, __LINE__);
return err;
}

void* data = kmalloc(size, GFP_KERNEL);
if( !data ) {
return -ENOMEM;
}
pr_info("%s:%d: size: %zu\tkey_bound: %zu\n",
__FILE__, __LINE__, size, key_bound);

__u64 start = ktime_get_raw_fast_ns();
for(__u64 i = 0; i < times; i++) {
__u32 key = simplerand(&rand) % key_bound;
if(DEBUG) {
pr_info("%s:%d: map_name: %lld key:%u\n",
__FILE__, __LINE__, map_name, key);
}
if( (err = fn(map_name, &key, 4, data, size)) ) {
goto cleanup;
}
returner ^= ((__u32*) data)[0];
}
__u64 stop = ktime_get_raw_fast_ns();

*nanos = stop - start;
cleanup:
kfree(data);
return err;
}

static int get_none(u64 map_name,
void* key,
size_t key_size,
void* value,
size_t value_size)
{
if(key_size < 4 && value_size < 4) {
return -EINVAL;
}
((__u32 *)value)[0] = ((__u32 *) key)[0];
return 0;
}


static long get_set_ioctl(struct file* file,
unsigned int cmd,
unsigned long data)
{
int err = -EINVAL;
gsa_t* uptr = (gsa_t*) data;
gsa_t gsa;
if( copy_from_user(&gsa, (gsa_t*) data, sizeof(gsa_t)) )
{
pr_err("Getting initial struct impossible\n");
err = -EINVAL;
return err;
}
switch (cmd) {
case BENCH_GET_NONE:
err = bench_get_many(gsa.map_name,
gsa.number,
&gsa.number,
get_none);
break;
case BENCH_GET_MANY:
err = bench_get_many(gsa.map_name,
gsa.number,
&gsa.number,
fstore_get);
break;
default:
break;
}
if( err == 0 && copy_to_user(&uptr->number,
&(gsa.number),
sizeof(__u64)) ) {
pr_err("Returning was thwarted\n");
err = -EINVAL;
}

return err;
}

int __init init_module(void)
{
/*Allocating Major number*/
if((alloc_chrdev_region(&dev, 0, 1, NAME"_dev")) <0){
pr_err("Cannot allocate major number\n");
return -1;
}

pr_info("Major = %d Minor = %d \n",MAJOR(dev), MINOR(dev));

/*Creating cdev structure*/
cdev_init(&bench_get_many_cdev, &fops);

/*Adding character device to the system*/
if((cdev_add(&bench_get_many_cdev, dev, 1)) < 0){
pr_err("Cannot add the device to the system\n");
goto r_class;
}

/*Creating struct class*/
if(IS_ERR(dev_class = class_create(NAME "_class"))){
pr_err("Cannot create the struct class\n");
goto r_class;
}

/*Creating device*/
if(IS_ERR(device_create(dev_class, NULL, dev, NULL, NAME "_device"))){
pr_err("Cannot create the Device 1\n");
goto r_device;
}

pr_info(NAME " Driver Insert...Done!!!\n");
return 0;

r_device:
class_destroy(dev_class);
r_class:
unregister_chrdev_region(dev,1);
return -1;
}

void __exit cleanup_module(void)
{
/* release device*/
device_destroy(dev_class,dev);
class_destroy(dev_class);
cdev_del(&bench_get_many_cdev);
unregister_chrdev_region(dev, 1);

pr_info(NAME " exit; returner: %u \n", returner);
}

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Aditya Tewari <[email protected]>");
MODULE_DESCRIPTION("benchmark getting many in kmods for feature store");
Loading

0 comments on commit 42e3dfd

Please sign in to comment.