Compare commits

..

7 Commits
a1.2 ... a1.1

Author SHA1 Message Date
hamza
f1f54b4216 - fixed /dev/kmesg bug 2025-05-07 17:19:14 +02:00
be5a41ecb0 Updated a1.1.config 2025-04-17 20:12:44 +02:00
Alexander Lochmann
31e51513fb Merge remote-tracking branch 'origin/linux-6.1.y' into a1.1 2025-04-17 17:53:27 +02:00
Alexander Lochmann
0e52191467 Fixed compile error 2024-05-07 13:31:34 +02:00
Alexander Lochmann
07fad299b8 Added a1.1 bug 2024-04-29 09:02:55 +02:00
Alexander Lochmann
b1ac2df90e a1.1 config final 2024-04-29 09:02:43 +02:00
Alexander Lochmann
e63dd18335 Base config 2024-04-28 20:41:58 +02:00
17 changed files with 17 additions and 14589 deletions

View File

@ -1,20 +1,21 @@
# #
# Automatically generated file; DO NOT EDIT. # Automatically generated file; DO NOT EDIT.
# Linux/x86 6.1.55 Kernel Configuration # Linux/x86 6.1.134 Kernel Configuration
# #
CONFIG_CC_VERSION_TEXT="gcc (Debian 13.2.0-23) 13.2.0" CONFIG_CC_VERSION_TEXT="gcc (Debian 12.2.0-14) 12.2.0"
CONFIG_CC_IS_GCC=y CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=130200 CONFIG_GCC_VERSION=120200
CONFIG_CLANG_VERSION=0 CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=24200 CONFIG_AS_VERSION=24000
CONFIG_LD_IS_BFD=y CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=24200 CONFIG_LD_VERSION=24000
CONFIG_LLD_VERSION=0 CONFIG_LLD_VERSION=0
CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK=y
CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_CAN_LINK_STATIC=y
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
CONFIG_CC_HAS_ASM_INLINE=y CONFIG_CC_HAS_ASM_INLINE=y
CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
CONFIG_PAHOLE_VERSION=124 CONFIG_PAHOLE_VERSION=124
@ -175,7 +176,7 @@ CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y
CONFIG_CC_HAS_INT128=y CONFIG_CC_HAS_INT128=y
CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
CONFIG_GCC11_NO_ARRAY_BOUNDS=y CONFIG_GCC10_NO_ARRAY_BOUNDS=y
CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CC_NO_ARRAY_BOUNDS=y
CONFIG_ARCH_SUPPORTS_INT128=y CONFIG_ARCH_SUPPORTS_INT128=y
# CONFIG_NUMA_BALANCING is not set # CONFIG_NUMA_BALANCING is not set
@ -428,6 +429,7 @@ CONFIG_X86_INTEL_TSX_MODE_OFF=y
# CONFIG_X86_INTEL_TSX_MODE_AUTO is not set # CONFIG_X86_INTEL_TSX_MODE_AUTO is not set
CONFIG_EFI=y CONFIG_EFI=y
CONFIG_EFI_STUB=y CONFIG_EFI_STUB=y
# CONFIG_EFI_HANDOVER_PROTOCOL is not set
CONFIG_EFI_MIXED=y CONFIG_EFI_MIXED=y
# CONFIG_HZ_100 is not set # CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set # CONFIG_HZ_250 is not set
@ -461,7 +463,7 @@ CONFIG_HAVE_LIVEPATCH=y
CONFIG_CC_HAS_SLS=y CONFIG_CC_HAS_SLS=y
CONFIG_CC_HAS_RETURN_THUNK=y CONFIG_CC_HAS_RETURN_THUNK=y
# CONFIG_SPECULATION_MITIGATIONS is not set # CONFIG_CPU_MITIGATIONS is not set
CONFIG_ARCH_HAS_ADD_PAGES=y CONFIG_ARCH_HAS_ADD_PAGES=y
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
@ -618,6 +620,7 @@ CONFIG_AS_AVX512=y
CONFIG_AS_SHA1_NI=y CONFIG_AS_SHA1_NI=y
CONFIG_AS_SHA256_NI=y CONFIG_AS_SHA256_NI=y
CONFIG_AS_TPAUSE=y CONFIG_AS_TPAUSE=y
CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS=y
# #
# General architecture-dependent options # General architecture-dependent options
@ -865,6 +868,7 @@ CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
CONFIG_PAGE_REPORTING=y CONFIG_PAGE_REPORTING=y
CONFIG_MIGRATION=y CONFIG_MIGRATION=y
CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y
CONFIG_PCP_BATCH_SCALE_MAX=5
CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_MMU_NOTIFIER=y CONFIG_MMU_NOTIFIER=y
# CONFIG_KSM is not set # CONFIG_KSM is not set
@ -1129,7 +1133,6 @@ CONFIG_NET_SCHED=y
# #
# Queueing/Scheduling # Queueing/Scheduling
# #
# CONFIG_NET_SCH_CBQ is not set
# CONFIG_NET_SCH_HTB is not set # CONFIG_NET_SCH_HTB is not set
# CONFIG_NET_SCH_HFSC is not set # CONFIG_NET_SCH_HFSC is not set
# CONFIG_NET_SCH_PRIO is not set # CONFIG_NET_SCH_PRIO is not set
@ -1143,7 +1146,6 @@ CONFIG_NET_SCHED=y
# CONFIG_NET_SCH_ETF is not set # CONFIG_NET_SCH_ETF is not set
# CONFIG_NET_SCH_TAPRIO is not set # CONFIG_NET_SCH_TAPRIO is not set
# CONFIG_NET_SCH_GRED is not set # CONFIG_NET_SCH_GRED is not set
# CONFIG_NET_SCH_DSMARK is not set
# CONFIG_NET_SCH_NETEM is not set # CONFIG_NET_SCH_NETEM is not set
# CONFIG_NET_SCH_DRR is not set # CONFIG_NET_SCH_DRR is not set
# CONFIG_NET_SCH_MQPRIO is not set # CONFIG_NET_SCH_MQPRIO is not set
@ -1284,8 +1286,6 @@ CONFIG_ETHTOOL_NETLINK=y
# #
# Device Drivers # Device Drivers
# #
CONFIG_HAVE_EISA=y
# CONFIG_EISA is not set
CONFIG_HAVE_PCI=y CONFIG_HAVE_PCI=y
CONFIG_PCI=y CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y CONFIG_PCI_DOMAINS=y
@ -1899,9 +1899,6 @@ CONFIG_E1000E_HWTS=y
# CONFIG_ICE is not set # CONFIG_ICE is not set
# CONFIG_FM10K is not set # CONFIG_FM10K is not set
# CONFIG_IGC is not set # CONFIG_IGC is not set
CONFIG_NET_VENDOR_WANGXUN=y
# CONFIG_NGBE is not set
# CONFIG_TXGBE is not set
# CONFIG_JME is not set # CONFIG_JME is not set
CONFIG_NET_VENDOR_LITEX=y CONFIG_NET_VENDOR_LITEX=y
CONFIG_NET_VENDOR_MARVELL=y CONFIG_NET_VENDOR_MARVELL=y
@ -2003,6 +2000,9 @@ CONFIG_NET_VENDOR_VERTEXCOM=y
CONFIG_NET_VENDOR_VIA=y CONFIG_NET_VENDOR_VIA=y
# CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE is not set
# CONFIG_VIA_VELOCITY is not set # CONFIG_VIA_VELOCITY is not set
CONFIG_NET_VENDOR_WANGXUN=y
# CONFIG_NGBE is not set
# CONFIG_TXGBE is not set
CONFIG_NET_VENDOR_WIZNET=y CONFIG_NET_VENDOR_WIZNET=y
# CONFIG_WIZNET_W5100 is not set # CONFIG_WIZNET_W5100 is not set
# CONFIG_WIZNET_W5300 is not set # CONFIG_WIZNET_W5300 is not set
@ -2915,7 +2915,6 @@ CONFIG_BCMA_POSSIBLE=y
# CONFIG_MFD_SM501 is not set # CONFIG_MFD_SM501 is not set
# CONFIG_MFD_SKY81452 is not set # CONFIG_MFD_SKY81452 is not set
# CONFIG_MFD_SYSCON is not set # CONFIG_MFD_SYSCON is not set
# CONFIG_MFD_TI_AM335X_TSCADC is not set
# CONFIG_MFD_LP3943 is not set # CONFIG_MFD_LP3943 is not set
# CONFIG_MFD_LP8788 is not set # CONFIG_MFD_LP8788 is not set
# CONFIG_MFD_TI_LMU is not set # CONFIG_MFD_TI_LMU is not set
@ -3941,6 +3940,9 @@ CONFIG_KEYS=y
# CONFIG_ENCRYPTED_KEYS is not set # CONFIG_ENCRYPTED_KEYS is not set
# CONFIG_KEY_DH_OPERATIONS is not set # CONFIG_KEY_DH_OPERATIONS is not set
# CONFIG_SECURITY_DMESG_RESTRICT is not set # CONFIG_SECURITY_DMESG_RESTRICT is not set
CONFIG_PROC_MEM_ALWAYS_FORCE=y
# CONFIG_PROC_MEM_FORCE_PTRACE is not set
# CONFIG_PROC_MEM_NO_FORCE is not set
CONFIG_SECURITY=y CONFIG_SECURITY=y
CONFIG_SECURITY_WRITABLE_HOOKS=y CONFIG_SECURITY_WRITABLE_HOOKS=y
# CONFIG_SECURITYFS is not set # CONFIG_SECURITYFS is not set

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +0,0 @@
1) a) um debug beim start des kerns zu aktivieren, reicht kern parameter (mit hilfe -a im unserem skript) zu geben dyndbg=\"module sst_chrdev +p\"
b) gleiche idee aber statt module zu wählen, kann mann eine file und zeile auswählen wie z.B
dyndbg=\"file sst_chrdev.c line 40 +p; file sst_chrdev.c line 72 +p\"
2) Mein grundlegendes Verständnis davon, wie kmemleak funktioniert, ist, dass jede neue Speicherzuweisung und ihre Zeiger zusammen mit einer Vielzahl von Metainformationen wie Größe verfolgt werden.
Informationen wie z.B. der Größe verfolgt und in einer Baumstruktur (rbtree) gespeichert wird.
einen Memory Allocator existiert, bedeutet dies, dass der Kernel nicht mehr in der Lage ist, ihn zu zerstören und er wird als Orphan bezeichnet.
3) um detector standardmäßige auszuschalten, kann mann CONFIG_DEBUG_KMEMLEAK=n setzen oder entfernen im kconfig

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -239,6 +239,4 @@ source "drivers/peci/Kconfig"
source "drivers/hte/Kconfig" source "drivers/hte/Kconfig"
source "drivers/sst/Kconfig"
endmenu endmenu

View File

@ -189,4 +189,3 @@ obj-$(CONFIG_COUNTER) += counter/
obj-$(CONFIG_MOST) += most/ obj-$(CONFIG_MOST) += most/
obj-$(CONFIG_PECI) += peci/ obj-$(CONFIG_PECI) += peci/
obj-$(CONFIG_HTE) += hte/ obj-$(CONFIG_HTE) += hte/
obj-$(CONFIG_SST) += sst/

View File

@ -22,7 +22,6 @@
#include <net/route.h> #include <net/route.h>
#include <net/xdp.h> #include <net/xdp.h>
#include <net/net_failover.h> #include <net/net_failover.h>
#include <linux/sst.h>
static int napi_weight = NAPI_POLL_WEIGHT; static int napi_weight = NAPI_POLL_WEIGHT;
module_param(napi_weight, int, 0444); module_param(napi_weight, int, 0444);
@ -1675,25 +1674,8 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
struct send_queue *sq; struct send_queue *sq;
unsigned int received; unsigned int received;
unsigned int xdp_xmit = 0; unsigned int xdp_xmit = 0;
#ifdef CONFIG_SST_LOCKING
static unsigned long next_time = 0;
char *question = NULL;
#endif
virtnet_poll_cleantx(rq, budget); virtnet_poll_cleantx(rq, budget);
#ifdef CONFIG_SST_LOCKING
if (next_time == 0) {
next_time = msecs_to_jiffies(65000) + jiffies;
} else if (time_after_eq(jiffies, next_time)) {
pr_debug("sst: Sending a random question (0x%lx,0x%lx)\n", in_hardirq(), in_softirq());
next_time = msecs_to_jiffies((get_random_u8() % 100) * 1000 + 15000) + jiffies;
question = kmalloc(sizeof(char) * 100, GFP_NOWAIT);
if (question) {
snprintf(question, 100, sst_questions[(get_random_u8() % SST_MAX_QUESTIONS)]);
sst_produce_question(get_sst_info(), question);
}
}
#endif
received = virtnet_receive(rq, budget, &xdp_xmit); received = virtnet_receive(rq, budget, &xdp_xmit);

View File

@ -1,24 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
#
# Character device configuration
#
menuconfig SST
tristate "Modules for system software techniques"
default y
help
TODO
if SST
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_ASYNC_SOURCE
tristate "Enable async source of messages from the universe"
default n
help
This is needed for task a1.4
endif

View File

@ -1,6 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the SST's faulty drivers
#
obj-$(CONFIG_SST) += sst_chrdev.o boundedbuffer.o sst_common.o

View File

@ -1,42 +0,0 @@
#include "sst_internal.h"
#ifdef CONFIG_SST_BOUNDS
#define OFFSET (4 * BOUNDEDBUFFER_SIZE)
#else
#define OFFSET 0
#endif
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;
}
int is_empty(struct boundedbuffer *buffer) {
return buffer->next_out == buffer->next_in;
}
int produce(struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE data) {
if (is_full(buffer)) {
return -1;
}
buffer->data[buffer->next_in + OFFSET] = data;
buffer->next_in = (buffer->next_in + 1) % buffer->size;
return 0;
}
int consume(struct boundedbuffer *buffer, BOUNDEDBUFFER_STORAGE_TYPE *ret) {
if (is_empty(buffer)) {
return -1;
}
*ret = buffer->data[buffer->next_out + OFFSET];
buffer->next_out = (buffer->next_out + 1) % buffer->size;
return 0;
}

View File

@ -1,29 +0,0 @@
#ifndef __BOUNDEDBUFFER_H__
#define __BOUNDEDBUFFER_H__
/*
* For some reasons, our ring buffer (aka BSB ring buffer)
* can only hold size - 1 elements.
* If we want to store BOUNDEDBUFFER_SIZE elements, as desired,
* the buffer must be one element larger.
* Hence, BOUNDEDBUFFER_SIZE_REAL is used for allocating the actual buffer
* and used for the size member.
*/
#ifndef BOUNDEDBUFFER_SIZE
#error Buffer size not defined!
#endif
#define BOUNDEDBUFFER_SIZE_REAL (BOUNDEDBUFFER_SIZE + 1)
#define BOUNDEDBUFFER_SIZE_VIRT (BOUNDEDBUFFER_SIZE_REAL - 1)
struct boundedbuffer {
int next_in;
int next_out;
int size;
BOUNDEDBUFFER_STORAGE_TYPE data[BOUNDEDBUFFER_SIZE_REAL];
};
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__

View File

@ -1,136 +0,0 @@
#include "sst_internal.h"
#include "../../include/linux/slab.h"
#include <linux/module.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#define SST_CHRDEV "the-universe"
static int sst_chrdev_major = 0;
static struct device *my_universe = NULL;
static int universe_open(struct inode *inode, struct file *file) {
file->private_data = get_sst_info();
return 0;
}
static int universe_release(struct inode *inode, struct file *file) {
return 0;
}
static ssize_t universe_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos) {
struct sst_info *sst_info = (struct sst_info*)file->private_data;
char *answer = NULL;
int min = 0;
size_t len = 0;
if (sst_consume_answer(sst_info, &answer)) {
pr_debug("Cannot read from answers!\n");
kfree(answer);
return 0;
}
len = strlen(answer);
sst_debug("About to copy %lu bytes of your answer at 0x%lx to the userspace\n", len, (uintptr_t)answer);
min = min(len, count);
if (min != len) {
pr_err("Sorry, your buffer is %lu bytes too small.\n", len - min);
}
if (copy_to_user(buf, answer, min)) {
pr_err("User copy failed!\n");
kfree(answer);
return -EFAULT;
}
sst_debug("Copied %u bytes of your answer to the userspace: %s\n", min, answer);
*ppos += len;
kfree(answer);
return len;
}
static ssize_t universe_write(struct file *file, const char __user *buf, size_t count,
loff_t *ppos) {
struct sst_info *sst_info = (struct sst_info*)file->private_data;
char *buf_copy;
int err;
buf_copy = memdup_user_nul(buf, count);
if (IS_ERR(buf_copy)) {
return PTR_ERR(buf_copy);
}
err = sst_produce_question(sst_info, buf_copy);
if (err) {
pr_err("Weird! The universe is full.\n");
kfree(buf_copy);
return -ENOMEM;
}
sst_debug("Asked the universe a question...\n");
kfree(buf_copy);
return count;
}
static const struct file_operations universe_fops = {
.owner = THIS_MODULE,
.read = universe_read,
.write = universe_write,
.open = universe_open,
.release = universe_release,
};
static struct class universe_class = {
.name = SST_CHRDEV,
};
static int __init sst_chrdev_init(void) {
int err;
sst_chrdev_major = err = register_chrdev(0, SST_CHRDEV, &universe_fops);
if (err < 0) {
pr_err("Cannot register chrdev: %d\n", err);
goto out;
}
err = class_register(&universe_class);
if (err) {
pr_err("Cannot register universe class: %d\n", err);
goto out_chrdev;
}
my_universe = device_create(&universe_class, NULL, MKDEV(sst_chrdev_major, 0), NULL, SST_CHRDEV);
if (IS_ERR(my_universe)) {
err = PTR_ERR(my_universe);
pr_err("Cannot create device: %d\n", err);
goto out_class;
}
err = sst_init();
if (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:
unregister_chrdev(sst_chrdev_major, SST_CHRDEV);
out:
return err;
}
static void __exit sst_chrdev_exit(void) {
sst_destroy();
device_destroy(&universe_class, MKDEV(sst_chrdev_major, 0));
class_unregister(&universe_class);
unregister_chrdev(sst_chrdev_major, SST_CHRDEV);
pr_notice("Unloaded module %s\n", KBUILD_MODNAME);
}
module_init(sst_chrdev_init);
module_exit(sst_chrdev_exit);
MODULE_LICENSE("LGPL");

View File

@ -1,186 +0,0 @@
#include "sst_internal.h"
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/random.h>
#include <linux/slab.h>
static sst_info_t *cur_sst_info = NULL;
static char an_answer[] = "You shall ask a question!\n";
char *sst_questions[SST_MAX_QUESTIONS] = {
"What is the answer to the Ultimate Question of Life, The Universe, and Everything?",
"What do you get if you multiply six by nine?"
};
EXPORT_SYMBOL(sst_questions);
char *sst_answers[SST_MAX_ANSWERS] = {
"42!\n",
"Six by nine. Forty two.\n",
"Flash!, a-ah. Savior of the Universe. Flash!, a-ah.\n"
};
EXPORT_SYMBOL(sst_answers);
sst_info_t* get_sst_info(void) {
return cur_sst_info;
}
EXPORT_SYMBOL(get_sst_info);
static int control_thread_work(void *data) {
sst_info_t *info = (sst_info_t*)data;
int err, i;
#if 0
int sleep = 0;
#endif
size_t len_answer = 0, len_question = 0;
char *question = NULL, *answer = NULL, *my_answer = NULL;
sst_debug("Using data at 0x%lx\n", (uintptr_t)info);
while(1) {
wait_event_interruptible(info->wait, !is_empty(&info->questions));
if (kthread_should_stop()) {
break;
}
err = sst_consume_question(info, &question);
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);
}
len_question = strlen(question);
if (len_question > 2 && (question[len_question - 1] == '?' ||
(question[len_question - 1] == '\n' && question[len_question - 2] == '?'))) {
my_answer = sst_answers[0];
for (i = 0; i < SST_MAX_QUESTIONS; i++) {
if (strcmp(question, sst_questions[i]) == 0) {
my_answer = sst_answers[i];
break;
}
}
} else {
my_answer = an_answer;
}
len_answer = strlen(my_answer) + 1;
answer = kmalloc(len_answer, GFP_KERNEL);
if (!answer) {
pr_err("Cannot allocate memory for answer!\n");
kfree(question);
continue;
}
snprintf(answer, len_answer, "%s", my_answer);
if (sst_produce_answer(info, answer)) {
pr_err("Answers is full!\n");
kfree(answer);
} else {
sst_debug("The universe has an answer at 0x%lx for you!\n", (uintptr_t)answer);
}
#if 0
sleep = get_random_u8() % 90;
sst_debug("Randomly sleeping for %d secs. ZzzzZZzz\n", sleep);
ssleep(sleep);
#endif
}
return 0;
}
int sst_init(void) {
cur_sst_info = kmalloc(sizeof(*cur_sst_info), GFP_KERNEL);
if (!cur_sst_info) {
return -ENOMEM;
}
spin_lock_init(&cur_sst_info->lock_questions);
spin_lock_init(&cur_sst_info->lock_answers);
sema_init(&cur_sst_info->answers_rdy, 0);
init_waitqueue_head(&cur_sst_info->wait);
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)) {
kfree(cur_sst_info);
return -EFAULT;
}
wake_up_process(cur_sst_info->thread);
sst_debug("Created and started control thread (%d)\n", cur_sst_info->thread->pid);
return 0;
}
EXPORT_SYMBOL(sst_init);
void sst_destroy(void) {
sst_debug("Waiting for control thread (%d) to terminate...\n", cur_sst_info->thread->pid);
kthread_stop(cur_sst_info->thread);
sst_debug("Control thread (%d) terminated.\n", cur_sst_info->thread->pid);
kfree(cur_sst_info);
sst_debug("Freed private data for the universe at 0x%lx\n", (uintptr_t)cur_sst_info);
};
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);
if (!err) {
wake_up_interruptible(&info->wait);
}
return err;
}
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);
up(&info->answers_rdy);
return err;
}
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);
return err;
}
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;
}
spin_lock_irqsave(&info->lock_answers, flags);
err = consume(&info->answers, value);
spin_unlock_irqrestore(&info->lock_answers, flags);
return err;
}
EXPORT_SYMBOL(sst_consume_answer);

View File

@ -1,30 +0,0 @@
#ifndef __SST_INTERNAL_H__
#define __SST_INTERNAL_H__
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/printk.h>
#define sst_debug(format, ...) \
pr_debug("(file:%s,line:%d,pid:%d): " format, \
__FILE__, __LINE__, \
current->pid, ##__VA_ARGS__)
#include <linux/sst.h>
#define BOUNDEDBUFFER_SIZE 20
#define BOUNDEDBUFFER_STORAGE_TYPE char*
#include "boundedbuffer.h"
#include <linux/spinlock.h>
#include <linux/semaphore.h>
#include <linux/wait.h>
struct sst_info {
struct boundedbuffer questions;
struct semaphore answers_rdy;
struct boundedbuffer answers;
struct task_struct *thread;
wait_queue_head_t wait;
spinlock_t lock_questions;
spinlock_t lock_answers;
};
typedef struct sst_info sst_info_t;
#endif // __SST_INTERNAL_H__

View File

@ -1,17 +0,0 @@
#ifndef __SST_H__
#define __SST_H__
#define SST_MAX_QUESTIONS 2
extern char *sst_questions[SST_MAX_QUESTIONS];
#define SST_MAX_ANSWERS 3
extern char *sst_answers[SST_MAX_ANSWERS];
struct sst_info;
int sst_init(void);
void sst_destroy(void);
struct sst_info* get_sst_info(void);
int sst_produce_question(struct sst_info *info, char *value);
int sst_produce_answer(struct sst_info *info, char *value);
int sst_consume_question(struct sst_info *info, char **value);
int sst_consume_answer(struct sst_info *info, char **value);
#endif // __SST_H__

View File

@ -45,8 +45,6 @@
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
#include <linux/sst.h>
#include <linux/random.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/unistd.h> #include <asm/unistd.h>
@ -1842,10 +1840,6 @@ static __latent_entropy void run_timer_softirq(struct softirq_action *h)
*/ */
static void run_local_timers(void) static void run_local_timers(void)
{ {
#ifdef CONFIG_SST_LOCKING
static unsigned long next_time = 0;
char *answer = NULL;
#endif
struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);
hrtimer_run_queues(); hrtimer_run_queues();
@ -1858,19 +1852,6 @@ static void run_local_timers(void)
if (time_before(jiffies, base->next_expiry)) if (time_before(jiffies, base->next_expiry))
return; return;
} }
#ifdef CONFIG_SST_LOCKING
if (next_time == 0) {
next_time = msecs_to_jiffies(65000) + jiffies;
} else if (time_after_eq(jiffies, next_time)) {
pr_debug("sst: Sending a random answer\n");
next_time = msecs_to_jiffies((get_random_u8() % 100) * 1000 + 15000) + jiffies;
answer = kmalloc(sizeof(char) * 100, GFP_NOWAIT);
if (answer) {
snprintf(answer, 100, sst_answers[(get_random_u8() % SST_MAX_ANSWERS)]);
sst_produce_answer(get_sst_info(), answer);
}
}
#endif
raise_softirq(TIMER_SOFTIRQ); raise_softirq(TIMER_SOFTIRQ);
} }