Backports sst fixes

This commit is contained in:
Alexander Krause 2025-04-25 16:18:43 +02:00
parent eea50e36c8
commit 46a6cd2c89
6 changed files with 57 additions and 32 deletions

View File

@ -3755,9 +3755,8 @@ CONFIG_NVMEM_SYSFS=y
# CONFIG_PECI is not set # CONFIG_PECI is not set
# CONFIG_HTE is not set # CONFIG_HTE is not set
CONFIG_SST=y CONFIG_SST=y
CONFIG_SST_MEMLEAK=y
# CONFIG_SST_BOUNDS is not set # CONFIG_SST_BOUNDS is not set
# CONFIG_SST_LOCKING is not set # CONFIG_SST_ASYNC_SOURCE is not set
# end of Device Drivers # end of Device Drivers
# #

View File

@ -4,27 +4,21 @@
# #
menuconfig SST menuconfig SST
bool "Modules for system software techniques" tristate "Modules for system software techniques"
default y default y
help help
TODO TODO
if SST if SST
config SST_MEMLEAK
tristate "Memleak errors for exercise a1.2"
default n
help
Enable memleaks for exercise a1.2
config SST_BOUNDS config SST_BOUNDS
tristate "Out-of-bounds accesses for exercise a1.3" tristate "Out-of-bounds accesses for exercise a1.3"
default n default n
help help
Activate out-of-bounds accesses for exercise a1.3 Activate out-of-bounds accesses for exercise a1.3
config SST_LOCKING config SST_ASYNC_SOURCE
tristate "Faulty locking for exercise a1.4" tristate "Enable async source of messages from the universe"
default n default n
help help
Make locking for exercise a1.4 faulty This is needed for task a1.4
endif endif

View File

@ -6,31 +6,36 @@
#define OFFSET 0 #define OFFSET 0
#endif #endif
noinline int is_full(volatile struct boundedbuffer *buffer) { void init_bbuffer(struct boundedbuffer *buffer) {
buffer->next_in = 0;
buffer->next_out = 0;
buffer->size = BOUNDEDBUFFER_SIZE;
}
int is_full(struct boundedbuffer *buffer) {
return (buffer->next_in + 1) % buffer->size == buffer->next_out; return (buffer->next_in + 1) % buffer->size == buffer->next_out;
} }
noinline int is_empty(volatile struct boundedbuffer *buffer) { int is_empty(struct boundedbuffer *buffer) {
return buffer->next_out == buffer->next_in; return buffer->next_out == buffer->next_in;
} }
noinline int produce(volatile struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE data) { int produce(struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE data) {
if (is_full(buffer)) { if (is_full(buffer)) {
return -1; return -1;
} }
buffer->data[buffer->next_in] = data; buffer->data[buffer->next_in + OFFSET] = data;
buffer->next_in = (buffer->next_in + 1) % buffer->size; buffer->next_in = (buffer->next_in + 1) % buffer->size;
return 0; return 0;
} }
noinline int consume(volatile struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE *ret) { int consume(struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE *ret) {
if (is_empty(buffer)) { if (is_empty(buffer)) {
return -1; return -1;
} }
*ret = buffer->data[buffer->next_out]; *ret = buffer->data[buffer->next_out + OFFSET];
buffer->data[buffer->next_out] = 0;
buffer->next_out = (buffer->next_out + 1) % buffer->size; buffer->next_out = (buffer->next_out + 1) % buffer->size;
return 0; return 0;

View File

@ -21,8 +21,9 @@ struct boundedbuffer {
BOUNDEDBUFFER_STORAGE_TYPE data[BOUNDEDBUFFER_SIZE_REAL]; BOUNDEDBUFFER_STORAGE_TYPE data[BOUNDEDBUFFER_SIZE_REAL];
}; };
noinline int is_full(volatile struct boundedbuffer *buffer); void init_bbuffer(struct boundedbuffer *buffer);
noinline int is_empty(volatile struct boundedbuffer *buffer); int is_full(struct boundedbuffer *buffer);
noinline int produce(volatile struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE data); int is_empty(struct boundedbuffer *buffer);
noinline int consume(volatile struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE *ret); int produce(struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE data);
int consume(struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE *ret);
#endif // __BOUNDEDBUFFER_H__ #endif // __BOUNDEDBUFFER_H__

View File

@ -29,7 +29,7 @@ static ssize_t universe_read(struct file *file, char __user *buf, size_t count,
size_t len = 0; size_t len = 0;
if (sst_consume_answer(sst_info, &answer)) { if (sst_consume_answer(sst_info, &answer)) {
pr_err("Cannot read from answers!\n"); pr_debug("Cannot read from answers!\n");
return 0; return 0;
} }
len = strlen(answer); len = strlen(answer);
@ -78,7 +78,7 @@ static struct class universe_class = {
.name = SST_CHRDEV, .name = SST_CHRDEV,
}; };
static int __init sst_chdev_init(void) { static int __init sst_chrdev_init(void) {
int err; int err;
sst_chrdev_major = err = register_chrdev(0, SST_CHRDEV, &universe_fops); sst_chrdev_major = err = register_chrdev(0, SST_CHRDEV, &universe_fops);
@ -99,11 +99,14 @@ static int __init sst_chdev_init(void) {
} }
err = sst_init(); err = sst_init();
if (err) { if (err) {
return err; pr_err("Cannot init sst_common: %d\n", err);
goto out_device;
} }
pr_notice("Loaded module %s\n", KBUILD_MODNAME); pr_notice("Loaded module %s\n", KBUILD_MODNAME);
return 0; return 0;
out_device:
device_destroy(&universe_class, MKDEV(sst_chrdev_major, 0));
out_class: out_class:
class_unregister(&universe_class); class_unregister(&universe_class);
out_chrdev: out_chrdev:
@ -112,7 +115,7 @@ out:
return err; return err;
} }
static void __exit sst_chdev_exit(void) { static void __exit sst_chrdev_exit(void) {
sst_destroy(); sst_destroy();
device_destroy(&universe_class, MKDEV(sst_chrdev_major, 0)); device_destroy(&universe_class, MKDEV(sst_chrdev_major, 0));
class_unregister(&universe_class); class_unregister(&universe_class);
@ -120,6 +123,6 @@ static void __exit sst_chdev_exit(void) {
pr_notice("Unloaded module %s\n", KBUILD_MODNAME); pr_notice("Unloaded module %s\n", KBUILD_MODNAME);
} }
module_init(sst_chdev_init); module_init(sst_chrdev_init);
module_exit(sst_chdev_exit); module_exit(sst_chrdev_exit);
MODULE_LICENSE("LGPL"); MODULE_LICENSE("LGPL");

View File

@ -44,6 +44,9 @@ static int control_thread_work(void *data) {
if (err) { if (err) {
pr_err("Questions was empty!\n"); pr_err("Questions was empty!\n");
continue; continue;
} else if (question == NULL) {
pr_err("Question is NULL although ret value is 0.\n");
continue;
} else { } else {
sst_debug("Received msg '%s' at 0x%lx\n", question, (uintptr_t)question); sst_debug("Received msg '%s' at 0x%lx\n", question, (uintptr_t)question);
} }
@ -52,7 +55,7 @@ static int control_thread_work(void *data) {
(question[len_question - 1] == '\n' && question[len_question - 2] == '?'))) { (question[len_question - 1] == '\n' && question[len_question - 2] == '?'))) {
my_answer = sst_answers[0]; my_answer = sst_answers[0];
for (i = 0; i < SST_MAX_QUESTIONS; i++) { for (i = 0; i < SST_MAX_QUESTIONS; i++) {
if (strcasecmp(question, sst_questions[i]) == 0) { if (strcmp(question, sst_questions[i]) == 0) {
my_answer = sst_answers[i]; my_answer = sst_answers[i];
break; break;
} }
@ -93,8 +96,8 @@ int sst_init(void) {
spin_lock_init(&cur_sst_info->lock_answers); spin_lock_init(&cur_sst_info->lock_answers);
sema_init(&cur_sst_info->answers_rdy, 0); sema_init(&cur_sst_info->answers_rdy, 0);
init_waitqueue_head(&cur_sst_info->wait); init_waitqueue_head(&cur_sst_info->wait);
cur_sst_info->questions.size = BOUNDEDBUFFER_SIZE_REAL; init_bbuffer(&cur_sst_info->answers);
cur_sst_info->answers.size = BOUNDEDBUFFER_SIZE_REAL; init_bbuffer(&cur_sst_info->questions);
sst_debug("Allocated private data for the universe at [0x%lx,0x%lx]\n", (uintptr_t)cur_sst_info, (uintptr_t)((uintptr_t)cur_sst_info + sizeof(*cur_sst_info))); sst_debug("Allocated private data for the universe at [0x%lx,0x%lx]\n", (uintptr_t)cur_sst_info, (uintptr_t)((uintptr_t)cur_sst_info + sizeof(*cur_sst_info)));
cur_sst_info->thread = kthread_create(control_thread_work, get_sst_info(), "sst-worker-%d", 1); cur_sst_info->thread = kthread_create(control_thread_work, get_sst_info(), "sst-worker-%d", 1);
if (IS_ERR(cur_sst_info->thread)) { if (IS_ERR(cur_sst_info->thread)) {
@ -118,6 +121,11 @@ EXPORT_SYMBOL(sst_destroy);
int sst_produce_question(sst_info_t *info, char *value) { int sst_produce_question(sst_info_t *info, char *value) {
int err = 0; int err = 0;
if (!info) {
return -1;
}
sst_debug("%s:info=%lx, questions=%lx\n", __func__, (uintptr_t)cur_sst_info, (uintptr_t)&info->questions);
spin_lock_bh(&info->lock_questions); spin_lock_bh(&info->lock_questions);
err = produce(&info->questions, value); err = produce(&info->questions, value);
spin_unlock_bh(&info->lock_questions); spin_unlock_bh(&info->lock_questions);
@ -131,6 +139,11 @@ EXPORT_SYMBOL(sst_produce_question);
int sst_produce_answer(sst_info_t *info, char *value) { int sst_produce_answer(sst_info_t *info, char *value) {
int err = 0; int err = 0;
unsigned long flags; unsigned long flags;
if (!info) {
return -1;
}
sst_debug("%s:info=%lx, answers=%lx\n", __func__, (uintptr_t)cur_sst_info, (uintptr_t)&info->answers);
spin_lock_irqsave(&info->lock_answers, flags); spin_lock_irqsave(&info->lock_answers, flags);
err = produce(&info->answers, value); err = produce(&info->answers, value);
spin_unlock_irqrestore(&info->lock_answers, flags); spin_unlock_irqrestore(&info->lock_answers, flags);
@ -141,6 +154,11 @@ EXPORT_SYMBOL(sst_produce_answer);
int sst_consume_question(sst_info_t *info, char **value) { int sst_consume_question(sst_info_t *info, char **value) {
int err = 0; int err = 0;
if (!info) {
return -1;
}
sst_debug("%s:info=%lx, questions=%lx\n", __func__, (uintptr_t)cur_sst_info, (uintptr_t)&info->questions);
spin_lock_bh(&info->lock_questions); spin_lock_bh(&info->lock_questions);
err = consume(&info->questions, value); err = consume(&info->questions, value);
spin_unlock_bh(&info->lock_questions); spin_unlock_bh(&info->lock_questions);
@ -151,6 +169,11 @@ EXPORT_SYMBOL(sst_consume_question);
int sst_consume_answer(sst_info_t *info, char **value) { int sst_consume_answer(sst_info_t *info, char **value) {
int err = 0; int err = 0;
unsigned long flags; unsigned long flags;
if (!info) {
return -1;
}
sst_debug("%s:info=%lx, answers=%lx\n", __func__, (uintptr_t)cur_sst_info, (uintptr_t)&info->answers);
if (down_trylock(&info->answers_rdy)) { if (down_trylock(&info->answers_rdy)) {
sst_debug("Sry. No answer for you!\n"); sst_debug("Sry. No answer for you!\n");
return -2; return -2;