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_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
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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__
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user