mirror of
https://github.com/caperren/school_archives.git
synced 2025-11-09 21:51:15 +00:00
411 lines
12 KiB
Diff
411 lines
12 KiB
Diff
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
|