Added OS II assignments

This commit is contained in:
2018-06-08 00:50:59 -07:00
parent 43b3555da8
commit 06c37d59e1
76 changed files with 103393 additions and 0 deletions

View File

@@ -0,0 +1,410 @@
diff -Naur -x '*.o' -x '*.ko' -x '*.order' -x '*.builtin' -x '*.cmd' -x '*.mod.c' linux-yocto-3.19.2_untouched/mm/slob.c linux-yocto-3.19.2/mm/slob.c
--- linux-yocto-3.19.2_untouched/mm/slob.c 2018-05-04 15:15:00.445347537 -0700
+++ linux-yocto-3.19.2/mm/slob.c 2018-06-06 17:07:53.244403545 -0700
@@ -68,6 +68,9 @@
#include <linux/list.h>
#include <linux/kmemleak.h>
+#include <linux/linkage.h>
+#include <linux/syscalls.h>
+
#include <trace/events/kmem.h>
#include <linux/atomic.h>
@@ -101,6 +104,8 @@
static LIST_HEAD(free_slob_medium);
static LIST_HEAD(free_slob_large);
+size_t num_pages = 0;
+
/*
* slob_page_free: true for pages on free_slob_pages list.
*/
@@ -211,55 +216,117 @@
free_pages((unsigned long)b, order);
}
-/*
- * Allocate a slob block within a given slob_page sp.
- */
static void *slob_page_alloc(struct page *sp, size_t size, int align)
{
- slob_t *prev, *cur, *aligned = NULL;
- int delta = 0, units = SLOB_UNITS(size);
+ slob_t *prev, *cur, *aligned = NULL, *best = NULL, *best_prev = NULL;
+ int delta = 0;
+ int units = SLOB_UNITS(size);
+ slobidx_t avail;
+ /* Find best fit block on page that can fit what needs to be allocated */
for (prev = NULL, cur = sp->freelist; ; prev = cur, cur = slob_next(cur)) {
- slobidx_t avail = slob_units(cur);
+ avail = slob_units(cur);
+ /* Use aligned blocks if requested */
if (align) {
aligned = (slob_t *)ALIGN((unsigned long)cur, align);
delta = aligned - cur;
}
- if (avail >= units + delta) { /* room enough? */
- slob_t *next;
+
+ /* If the current block is the best option seen yet, store it */
+ if(avail >= units + delta && (!best || avail < slob_units(best))) {
+ best = cur;
+ best_prev = prev;
+ }
+
+ /* If this is the last block, exit loop */
+ if (slob_last(cur)) {
+ break;
+ }
+
+ }
+
+ /* Allocate the best block found above, if found */
+ if (best != NULL){
+ slob_t *next;
- if (delta) { /* need to fragment head to align? */
- next = slob_next(cur);
- set_slob(aligned, avail - delta, next);
- set_slob(cur, delta, aligned);
- prev = cur;
- cur = aligned;
- avail = slob_units(cur);
- }
+ /* Align if necessary */
+ if (align) {
+ aligned = (slob_t *)ALIGN((unsigned long)best, align);
+ delta = aligned - best;
+ }
+
+ /* Get the amount of space available */
+ avail = slob_units(best);
- next = slob_next(cur);
- if (avail == units) { /* exact fit? unlink. */
- if (prev)
- set_slob(prev, slob_units(prev), next);
- else
- sp->freelist = next;
- } else { /* fragment */
- if (prev)
- set_slob(prev, slob_units(prev), cur + units);
- else
- sp->freelist = cur + units;
- set_slob(cur + units, avail - units, next);
+
+ if (delta) { /* need to fragment head to align? */
+ next = slob_next(best);
+ set_slob(aligned, (avail - delta), next);
+ set_slob(best, delta, aligned);
+ best_prev = best;
+ best = aligned;
+ avail = slob_units(best);
+ }
+
+ next = slob_next(best);
+
+ /* exact fit? unlink. */
+ if (avail == units) {
+ if (best_prev)
+ set_slob(best_prev, slob_units(best_prev), next);
+ else
+ sp->freelist = next;
+ } else { /* fragment */
+ if (best_prev){
+ set_slob(best_prev, slob_units(best_prev), best + units);
}
+ else{
+ sp->freelist = best + units;
+ }
+ set_slob(best + units, avail - units, next);
+ }
+
+ sp->units -= units;
+ if (!sp->units)
+ clear_slob_page_free(sp);
+ return best;
+ }
+
+ return NULL;
+}
+
+
+static int find_closest_block_size_in_page(struct page *sp, size_t size, int align)
+{
+ slob_t *prev, *cur, *aligned = NULL, *best = NULL;
+ int delta = 0, units = SLOB_UNITS(size);
- sp->units -= units;
- if (!sp->units)
- clear_slob_page_free(sp);
- return cur;
+ for (prev = NULL, cur = sp->freelist; ; prev = cur, cur = slob_next(cur)) {
+ slobidx_t avail = slob_units(cur);
+
+ /* Align if necessary */
+ if (align) {
+ aligned = (slob_t *)ALIGN((unsigned long)cur, align);
+ delta = aligned - cur;
}
- if (slob_last(cur))
- return NULL;
+
+ /* Keep track of the better block if we've found one */
+ if(avail >= units + delta && (!best || avail < slob_units(best))){
+ best = cur;
+ }
+
+ /* If we're at the end, return the best block, or -1 if not found*/
+ if (slob_last(cur)) {
+ if(best){
+ return slob_units(best);
+ }else{
+ return -1;
+ }
+ }
+
}
+ return -1;
}
/*
@@ -267,11 +334,12 @@
*/
static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
{
- struct page *sp;
- struct list_head *prev;
- struct list_head *slob_list;
+ struct page *sp = NULL, *best_pg = NULL;
+ struct list_head *slob_list = NULL;
slob_t *b = NULL;
unsigned long flags;
+ slobidx_t best_fit = 0;
+ slobidx_t cur_fit;
if (size < SLOB_BREAK1)
slob_list = &free_slob_small;
@@ -281,53 +349,67 @@
slob_list = &free_slob_large;
spin_lock_irqsave(&slob_lock, flags);
- /* Iterate through each partially free page, try to find room */
+
+ /* Iterate through each page for find a spot if possible */
list_for_each_entry(sp, slob_list, lru) {
#ifdef CONFIG_NUMA
- /*
- * If there's a node specification, search for a partial
- * page with a matching node id in the freelist.
- */
- if (node != NUMA_NO_NODE && page_to_nid(sp) != node)
- continue;
+ /*
+ * If there's a node specification, search for a partial
+ * page with a matching node id in the freelist.
+ */
+ if (node != NUMA_NO_NODE && page_to_nid(sp) != node)
+ continue;
#endif
- /* Enough room on this page? */
- if (sp->units < SLOB_UNITS(size))
- continue;
-
- /* Attempt to alloc */
- prev = sp->lru.prev;
- b = slob_page_alloc(sp, size, align);
- if (!b)
- continue;
-
- /* Improve fragment distribution and reduce our average
- * search time by starting our next search here. (see
- * Knuth vol 1, sec 2.5, pg 449) */
- if (prev != slob_list->prev &&
- slob_list->next != prev->next)
- list_move_tail(slob_list, prev->next);
- break;
+ /* Enough room on this page? */
+ if (sp->units < SLOB_UNITS(size))
+ continue;
+
+ /* Find out if there's space for this in the current page */
+ cur_fit = find_closest_block_size_in_page(sp, size, align);
+
+ /* If not, continue*/
+ if(cur_fit == -1){
+ continue;
+ }
+
+ /* Stop if we've found something that perfectly matches */
+ if (cur_fit == SLOB_UNITS(size)) {
+ best_pg = sp;
+ break;
+ }
+
+ /* Store the current best fit block, if it's better than previous */
+ if (best_fit > cur_fit || best_pg == NULL) {
+ best_pg = sp;
+ best_fit = cur_fit;
+ }
+ }
+
+ /* Attempt to allocate */
+ if(best_pg != NULL){
+ b = slob_page_alloc(best_pg, size, align);
}
+
spin_unlock_irqrestore(&slob_lock, flags);
- /* Not enough space: must allocate a new page */
+ /* Make a new page if we never found a spot */
if (!b) {
- b = slob_new_pages(gfp & ~__GFP_ZERO, 0, node);
- if (!b)
- return NULL;
- sp = virt_to_page(b);
- __SetPageSlab(sp);
-
- spin_lock_irqsave(&slob_lock, flags);
- sp->units = SLOB_UNITS(PAGE_SIZE);
- sp->freelist = b;
- INIT_LIST_HEAD(&sp->lru);
- set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
- set_slob_page_free(sp, slob_list);
- b = slob_page_alloc(sp, size, align);
- BUG_ON(!b);
- spin_unlock_irqrestore(&slob_lock, flags);
+ b = slob_new_pages(gfp & ~__GFP_ZERO, 0, node);
+ if (!b)
+ return NULL;
+ sp = virt_to_page(b);
+ __SetPageSlab(sp);
+
+ spin_lock_irqsave(&slob_lock, flags);
+ sp->units = SLOB_UNITS(PAGE_SIZE);
+ sp->freelist = b;
+ INIT_LIST_HEAD(&sp->lru);
+ set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
+ set_slob_page_free(sp, slob_list);
+ b = slob_page_alloc(sp, size, align);
+ BUG_ON(!b);
+ spin_unlock_irqrestore(&slob_lock, flags);
+ num_pages++;
}
if (unlikely((gfp & __GFP_ZERO) && b))
memset(b, 0, size);
@@ -362,6 +444,7 @@
__ClearPageSlab(sp);
page_mapcount_reset(sp);
slob_free_pages(b, 0);
+ num_pages--;
return;
}
@@ -640,3 +723,31 @@
{
slab_state = FULL;
}
+
+asmlinkage long sys_slob_free(void) {
+ struct list_head *temp;
+ struct page *sp;
+ unsigned long free_units = 0;
+
+ temp = &free_slob_small;
+ list_for_each_entry(sp, temp, lru) {
+ free_units += sp->units;
+ }
+ temp = &free_slob_medium;
+ list_for_each_entry(sp, temp, lru) {
+ free_units += sp->units;
+ }
+ temp = &free_slob_large;
+ list_for_each_entry(sp, temp, lru) {
+ free_units += sp->units;
+ }
+
+ return free_units;
+}
+
+asmlinkage long sys_slob_used(void) {
+ long slob_total_used;
+
+ slob_total_used = SLOB_UNITS(PAGE_SIZE) * num_pages;
+ return slob_total_used;
+}
\ No newline at end of file
diff -Naur -x '*.o' -x '*.ko' -x '*.order' -x '*.builtin' -x '*.cmd' -x '*.mod.c' linux-yocto-3.19.2_untouched/include/linux/syscalls.h linux-yocto-3.19.2/include/linux/syscalls.h
--- linux-yocto-3.19.2_untouched/include/linux/syscalls.h 2018-05-04 15:14:59.075324834 -0700
+++ linux-yocto-3.19.2/include/linux/syscalls.h 2018-06-06 16:32:02.518020727 -0700
@@ -882,4 +882,6 @@
const char __user *const __user *argv,
const char __user *const __user *envp, int flags);
+asmlinkage long sys_slob_free(void);
+asmlinkage long sys_slob_used(void);
#endif
diff -Naur -x '*.o' -x '*.ko' -x '*.order' -x '*.builtin' -x '*.cmd' -x '*.mod.c' linux-yocto-3.19.2_untouched/arch/x86/syscalls/syscall_32.tbl linux-yocto-3.19.2/arch/x86/syscalls/syscall_32.tbl
--- linux-yocto-3.19.2_untouched/arch/x86/syscalls/syscall_32.tbl 2018-05-04 15:14:40.077010007 -0700
+++ linux-yocto-3.19.2/arch/x86/syscalls/syscall_32.tbl 2018-06-06 16:31:26.578421117 -0700
@@ -365,3 +365,6 @@
356 i386 memfd_create sys_memfd_create
357 i386 bpf sys_bpf
358 i386 execveat sys_execveat stub32_execveat
+
+400 i386 slob_free sys_slob_free
+401 i386 slob_used sys_slob_used
\ No newline at end of file
--- linux-yocto-3.19.2_untouched/.config 2018-05-04 15:15:03.830403632 -0700
+++ linux-yocto-3.19.2/.config 2018-06-05 17:11:02.799939154 -0700
@@ -146,7 +146,6 @@
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_SWAP_ENABLED=y
-CONFIG_MEMCG_KMEM=y
# CONFIG_CGROUP_PERF is not set
CONFIG_CGROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
@@ -211,12 +210,10 @@
CONFIG_PERF_EVENTS=y
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLUB_DEBUG=y
CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
-CONFIG_SLUB=y
-# CONFIG_SLOB is not set
-CONFIG_SLUB_CPU_PARTIAL=y
+# CONFIG_SLUB is not set
+CONFIG_SLOB=y
# CONFIG_SYSTEM_TRUSTED_KEYRING is not set
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
@@ -251,7 +248,6 @@
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
-CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
CONFIG_HAVE_CMPXCHG_LOCAL=y
CONFIG_HAVE_CMPXCHG_DOUBLE=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
@@ -275,7 +271,6 @@
# CONFIG_GCOV_KERNEL is not set
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
@@ -3787,8 +3782,6 @@
# CONFIG_PAGE_EXTENSION is not set
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_SLUB_DEBUG_ON is not set
-# CONFIG_SLUB_STATS is not set
CONFIG_HAVE_DEBUG_KMEMLEAK=y
# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_STACK_USAGE is not set