Backports sst fixes
This commit is contained in:
parent
eea50e36c8
commit
46a6cd2c89
@ -3755,9 +3755,8 @@ CONFIG_NVMEM_SYSFS=y
|
||||
# CONFIG_PECI is not set
|
||||
# CONFIG_HTE is not set
|
||||
CONFIG_SST=y
|
||||
CONFIG_SST_MEMLEAK=y
|
||||
# CONFIG_SST_BOUNDS is not set
|
||||
# CONFIG_SST_LOCKING is not set
|
||||
# CONFIG_SST_ASYNC_SOURCE is not set
|
||||
# end of Device Drivers
|
||||
|
||||
#
|
||||
|
@ -4,27 +4,21 @@
|
||||
#
|
||||
|
||||
menuconfig SST
|
||||
bool "Modules for system software techniques"
|
||||
tristate "Modules for system software techniques"
|
||||
default y
|
||||
help
|
||||
TODO
|
||||
|
||||
if SST
|
||||
config SST_MEMLEAK
|
||||
tristate "Memleak errors for exercise a1.2"
|
||||
default n
|
||||
help
|
||||
Enable memleaks for exercise a1.2
|
||||
|
||||
config SST_BOUNDS
|
||||
tristate "Out-of-bounds accesses for exercise a1.3"
|
||||
default n
|
||||
help
|
||||
Activate out-of-bounds accesses for exercise a1.3
|
||||
|
||||
config SST_LOCKING
|
||||
tristate "Faulty locking for exercise a1.4"
|
||||
config SST_ASYNC_SOURCE
|
||||
tristate "Enable async source of messages from the universe"
|
||||
default n
|
||||
help
|
||||
Make locking for exercise a1.4 faulty
|
||||
This is needed for task a1.4
|
||||
endif
|
||||
|
@ -6,31 +6,36 @@
|
||||
#define OFFSET 0
|
||||
#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;
|
||||
}
|
||||
|
||||
noinline int is_empty(volatile struct boundedbuffer *buffer) {
|
||||
int is_empty(struct boundedbuffer *buffer) {
|
||||
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)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer->data[buffer->next_in] = data;
|
||||
buffer->data[buffer->next_in + OFFSET] = data;
|
||||
buffer->next_in = (buffer->next_in + 1) % buffer->size;
|
||||
|
||||
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)) {
|
||||
return -1;
|
||||
}
|
||||
*ret = buffer->data[buffer->next_out];
|
||||
buffer->data[buffer->next_out] = 0;
|
||||
*ret = buffer->data[buffer->next_out + OFFSET];
|
||||
buffer->next_out = (buffer->next_out + 1) % buffer->size;
|
||||
|
||||
return 0;
|
||||
|
@ -21,8 +21,9 @@ struct boundedbuffer {
|
||||
BOUNDEDBUFFER_STORAGE_TYPE data[BOUNDEDBUFFER_SIZE_REAL];
|
||||
};
|
||||
|
||||
noinline int is_full(volatile struct boundedbuffer *buffer);
|
||||
noinline int is_empty(volatile struct boundedbuffer *buffer);
|
||||
noinline int produce(volatile struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE data);
|
||||
noinline int consume(volatile struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE *ret);
|
||||
void init_bbuffer(struct boundedbuffer *buffer);
|
||||
int is_full(struct boundedbuffer *buffer);
|
||||
int is_empty(struct boundedbuffer *buffer);
|
||||
int produce(struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE data);
|
||||
int consume(struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE *ret);
|
||||
#endif // __BOUNDEDBUFFER_H__
|
||||
|
@ -29,7 +29,7 @@ static ssize_t universe_read(struct file *file, char __user *buf, size_t count,
|
||||
size_t len = 0;
|
||||
|
||||
if (sst_consume_answer(sst_info, &answer)) {
|
||||
pr_err("Cannot read from answers!\n");
|
||||
pr_debug("Cannot read from answers!\n");
|
||||
return 0;
|
||||
}
|
||||
len = strlen(answer);
|
||||
@ -78,7 +78,7 @@ static struct class universe_class = {
|
||||
.name = SST_CHRDEV,
|
||||
};
|
||||
|
||||
static int __init sst_chdev_init(void) {
|
||||
static int __init sst_chrdev_init(void) {
|
||||
int err;
|
||||
|
||||
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();
|
||||
if (err) {
|
||||
return err;
|
||||
pr_err("Cannot init sst_common: %d\n", err);
|
||||
goto out_device;
|
||||
}
|
||||
pr_notice("Loaded module %s\n", KBUILD_MODNAME);
|
||||
return 0;
|
||||
|
||||
out_device:
|
||||
device_destroy(&universe_class, MKDEV(sst_chrdev_major, 0));
|
||||
out_class:
|
||||
class_unregister(&universe_class);
|
||||
out_chrdev:
|
||||
@ -112,7 +115,7 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit sst_chdev_exit(void) {
|
||||
static void __exit sst_chrdev_exit(void) {
|
||||
sst_destroy();
|
||||
device_destroy(&universe_class, MKDEV(sst_chrdev_major, 0));
|
||||
class_unregister(&universe_class);
|
||||
@ -120,6 +123,6 @@ static void __exit sst_chdev_exit(void) {
|
||||
pr_notice("Unloaded module %s\n", KBUILD_MODNAME);
|
||||
}
|
||||
|
||||
module_init(sst_chdev_init);
|
||||
module_exit(sst_chdev_exit);
|
||||
module_init(sst_chrdev_init);
|
||||
module_exit(sst_chrdev_exit);
|
||||
MODULE_LICENSE("LGPL");
|
||||
|
@ -44,6 +44,9 @@ static int control_thread_work(void *data) {
|
||||
if (err) {
|
||||
pr_err("Questions was empty!\n");
|
||||
continue;
|
||||
} else if (question == NULL) {
|
||||
pr_err("Question is NULL although ret value is 0.\n");
|
||||
continue;
|
||||
} else {
|
||||
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] == '?'))) {
|
||||
my_answer = sst_answers[0];
|
||||
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];
|
||||
break;
|
||||
}
|
||||
@ -93,8 +96,8 @@ int sst_init(void) {
|
||||
spin_lock_init(&cur_sst_info->lock_answers);
|
||||
sema_init(&cur_sst_info->answers_rdy, 0);
|
||||
init_waitqueue_head(&cur_sst_info->wait);
|
||||
cur_sst_info->questions.size = BOUNDEDBUFFER_SIZE_REAL;
|
||||
cur_sst_info->answers.size = BOUNDEDBUFFER_SIZE_REAL;
|
||||
init_bbuffer(&cur_sst_info->answers);
|
||||
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)));
|
||||
cur_sst_info->thread = kthread_create(control_thread_work, get_sst_info(), "sst-worker-%d", 1);
|
||||
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 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);
|
||||
err = produce(&info->questions, value);
|
||||
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 err = 0;
|
||||
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);
|
||||
err = produce(&info->answers, value);
|
||||
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 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);
|
||||
err = consume(&info->questions, value);
|
||||
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 err = 0;
|
||||
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)) {
|
||||
sst_debug("Sry. No answer for you!\n");
|
||||
return -2;
|
||||
|
Loading…
Reference in New Issue
Block a user