Skip to content

Commit 8646e94

Browse files
committed
Prj2 finished
1 parent 10930e4 commit 8646e94

File tree

13 files changed

+607
-17
lines changed

13 files changed

+607
-17
lines changed

Project 2/VATranslate/jni/Android.mk

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
LOCAL_PATH := $(call my-dir)
2+
3+
include $(CLEAR_VARS)
4+
LOCAL_SRC_FILES := VATranslate.c # your source code
5+
LOCAL_MODULE := VATranslate # output file name
6+
LOCAL_CFLAGS += -pie -fPIE # These two line mustn’t be
7+
LOCAL_LDFLAGS += -pie -fPIE # change.
8+
LOCAL_FORCE_STATIC_EXECUTABLE := true
9+
10+
include $(BUILD_EXECUTABLE)
+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#include <stdlib.h>
2+
#include <string.h>
3+
#include <stdio.h>
4+
#include <errno.h>
5+
#include <sys/types.h>
6+
#include <sys/mman.h>
7+
#define __NR_get_pagetable_layout 233
8+
#define __NR_expose_page_table 378
9+
10+
#define PGD_SIZE ((1 << 11) * sizeof(unsigned long))
11+
#define PTE_SIZE ((1 << 20) * sizeof(unsigned long))
12+
13+
// The structure "pagetable_layout_info" stores the information of pagetable layout
14+
struct pagetable_layout_info
15+
{
16+
uint32_t pgdir_shift;
17+
uint32_t page_shift;
18+
};
19+
20+
// for a hex byte c, return hex byte (c-8)
21+
char lower(char c)
22+
{
23+
if (c >= 'a')
24+
return c - 'a' + '2';
25+
if (c >= 'A')
26+
return c - 'A' + '2';
27+
return c - 8;
28+
}
29+
30+
// convert a hex string up to 8 bytes to unsigned long
31+
unsigned long strtolu(char *str)
32+
{
33+
unsigned long res;
34+
35+
// check if the value of the string exceeds (2^31)-1
36+
int flag = (strlen(str) == 8) && (str[0] >= '8');
37+
if (flag)
38+
str[0] = lower(str[0]);
39+
40+
// convert hex to unsigned long
41+
res = strtol(str, NULL, 16);
42+
res |= (flag << 31);
43+
44+
return res;
45+
}
46+
47+
void display_pagetable_layout(struct pagetable_layout_info* layout)
48+
{
49+
printf("============================================================\n");
50+
printf("Android pagetable layout:\n");
51+
printf(" pgdir_shift = %u\n", layout->pgdir_shift);
52+
printf(" page_shift = %u\n", layout->page_shift);
53+
printf("============================================================\n");
54+
}
55+
56+
void get_pagetable_layout()
57+
{
58+
struct pagetable_layout_info pgtbl_info;
59+
60+
// invoke system call get_pagetable_layout()
61+
if (syscall(__NR_get_pagetable_layout, &pgtbl_info, sizeof(struct pagetable_layout_info)))
62+
{
63+
printf("Failed to get pagetable layout.\n\n");
64+
return;
65+
}
66+
67+
display_pagetable_layout(&pgtbl_info);
68+
}
69+
70+
void expose_page_table(pid_t pid, unsigned long fake_pgd, unsigned long page_table_addr, unsigned long begin_vaddr, unsigned long end_vaddr)
71+
{
72+
unsigned long physical_addr, v_pgd, v_pte, v_offset, pageFrame;
73+
unsigned long *p;
74+
75+
// invoke system call expose_page_table()
76+
if (syscall(__NR_expose_page_table, pid, fake_pgd, page_table_addr, begin_vaddr, end_vaddr))
77+
{
78+
printf("Failed to expose pagetable layout.\n");
79+
return;
80+
}
81+
82+
// segment the virtual address
83+
v_pgd = (begin_vaddr >> 21) & 0x7FF;
84+
v_pte = (begin_vaddr >> PAGE_SHIFT) & 0x1FF;
85+
v_offset = begin_vaddr & 0xFFF;
86+
87+
// calculate physical address
88+
p = (unsigned long*)((unsigned long*)fake_pgd)[v_pgd];
89+
pageFrame = p[v_pte] & 0xFFFFF000;
90+
if (!pageFrame)
91+
{
92+
printf("Invalid physical address!");
93+
}
94+
physical_addr = pageFrame + v_offset;
95+
96+
// print calculation details
97+
printf("Virtual Address Translation:\n");
98+
printf(" virtual address = 0x%08lx\n", begin_vaddr);
99+
printf(" pgd: 0x%03lx\tpte: 0x%03lx\toffset: 0x%03lx\n", v_pgd, v_pte, v_offset);
100+
printf(" pgd_base[0x%lx] = 0x%08lx\tpte[0x%lx] = 0x%08lx\n", v_pgd, (unsigned long)p, v_pte, pageFrame);
101+
printf(" physical address = 0x%08lx\n", physical_addr);
102+
}
103+
104+
int main(int argc, char *argv[])
105+
{
106+
pid_t pid;
107+
unsigned long fake_pgd, page_table_addr, begin_vaddr, end_vaddr;
108+
109+
// invoke system call
110+
get_pagetable_layout();
111+
112+
// check paramaters
113+
if (argc != 3)
114+
{
115+
printf("Unmatched parameters for VATranslate!\n");
116+
printf("The correct format should be:\n");
117+
printf("./VATranslate #PID #VA\n");
118+
return -EAGAIN;
119+
}
120+
pid = atoi(argv[1]);
121+
begin_vaddr =strtolu(argv[2]);
122+
end_vaddr = begin_vaddr + 1;
123+
124+
// allocate user-space memory
125+
fake_pgd = (unsigned long)malloc(2 * PAGE_SIZE);
126+
if (!fake_pgd)
127+
return -EFAULT;
128+
page_table_addr = (unsigned long)mmap(NULL, 1 << 22, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
129+
if (!page_table_addr)
130+
return -EFAULT;
131+
// invoke system call
132+
expose_page_table(pid, fake_pgd, page_table_addr, begin_vaddr, end_vaddr);
133+
134+
// free user-space memory
135+
free((void*)fake_pgd);
136+
munmap((void*)page_table_addr, 1 << 22);
137+
return 0;
138+
}

Project 2/kernel/goldfish/include/linux/mm_types.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ struct page {
117117
#endif
118118
};
119119
};
120-
121120
/* Remainder is not double word aligned */
122121
union {
123122
unsigned long private; /* Mapping-private opaque data:
@@ -159,6 +158,7 @@ struct page {
159158
*/
160159
void *shadow;
161160
#endif
161+
unsigned long PG_referenced;
162162
}
163163
/*
164164
* The struct page can be forced to be double word aligned so that atomic ops

Project 2/kernel/goldfish/mm/swap.c

+3-7
Original file line numberDiff line numberDiff line change
@@ -361,13 +361,9 @@ void activate_page(struct page *page)
361361
*/
362362
void mark_page_accessed(struct page *page)
363363
{
364-
if (!PageActive(page) && !PageUnevictable(page) &&
365-
PageReferenced(page) && PageLRU(page)) {
364+
if (!PageActive(page) && !PageUnevictable(page) && PageLRU(page))
366365
activate_page(page);
367-
ClearPageReferenced(page);
368-
} else if (!PageReferenced(page)) {
369-
SetPageReferenced(page);
370-
}
366+
page->PG_referenced = 0;
371367
}
372368
EXPORT_SYMBOL(mark_page_accessed);
373369

@@ -465,7 +461,7 @@ static void lru_deactivate_fn(struct page *page, void *arg)
465461
lru = page_lru_base_type(page);
466462
del_page_from_lru_list(zone, page, lru + active);
467463
ClearPageActive(page);
468-
ClearPageReferenced(page);
464+
//ClearPageReferenced(page);
469465
add_page_to_lru_list(zone, page, lru);
470466

471467
if (PageWriteback(page) || PageDirty(page)) {

Project 2/kernel/goldfish/mm/vmscan.c

+26-9
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252

5353
#include "internal.h"
5454

55+
#define PG_REFERENCED_SHRINK_THRESHOLD 2
56+
5557
#define CREATE_TRACE_POINTS
5658
#include <trace/events/vmscan.h>
5759

@@ -215,7 +217,7 @@ static int debug_shrinker_show(struct seq_file *s, void *unused)
215217

216218
down_read(&shrinker_rwsem);
217219
list_for_each_entry(shrinker, &shrinker_list, list) {
218-
char name[64];
220+
//char name[64];
219221
int num_objs;
220222

221223
num_objs = shrinker->shrink(shrinker, &sc);
@@ -748,11 +750,11 @@ static enum page_references page_check_references(struct page *page,
748750
struct mem_cgroup_zone *mz,
749751
struct scan_control *sc)
750752
{
751-
int referenced_ptes, referenced_page;
752-
unsigned long vm_flags;
753+
int referenced_ptes;
754+
unsigned long vm_flags, referenced_time;
753755

754756
referenced_ptes = page_referenced(page, 1, mz->mem_cgroup, &vm_flags);
755-
referenced_page = TestClearPageReferenced(page);
757+
referenced_time = (page->PG_referenced)++;
756758

757759
/* Lumpy reclaim - ignore references */
758760
if (sc->reclaim_mode & RECLAIM_MODE_LUMPYRECLAIM)
@@ -782,9 +784,9 @@ static enum page_references page_check_references(struct page *page,
782784
* so that recently deactivated but used pages are
783785
* quickly recovered.
784786
*/
785-
SetPageReferenced(page);
787+
--(page->PG_referenced);
786788

787-
if (referenced_page || referenced_ptes > 1)
789+
if (referenced_time < 1 || referenced_ptes > 1)
788790
return PAGEREF_ACTIVATE;
789791

790792
/*
@@ -797,7 +799,7 @@ static enum page_references page_check_references(struct page *page,
797799
}
798800

799801
/* Reclaim if clean, defer dirty pages to writeback */
800-
if (referenced_page && !PageSwapBacked(page))
802+
if (referenced_time < 1 && !PageSwapBacked(page))
801803
return PAGEREF_RECLAIM_CLEAN;
802804

803805
return PAGEREF_RECLAIM;
@@ -1030,6 +1032,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
10301032
* Is there need to periodically free_page_list? It would
10311033
* appear not as the counts should be low
10321034
*/
1035+
printk(KERN_INFO "Freeing a page.\n");
10331036
list_add(&page->lru, &free_pages);
10341037
continue;
10351038

@@ -1737,6 +1740,7 @@ static void shrink_active_list(unsigned long nr_to_scan,
17371740
isolate_mode_t isolate_mode = ISOLATE_ACTIVE;
17381741
struct zone *zone = mz->zone;
17391742

1743+
printk(KERN_INFO "Function shrink_active_list() called!\n");
17401744
lru_add_drain();
17411745

17421746
reset_reclaim_mode(sc);
@@ -1781,6 +1785,7 @@ static void shrink_active_list(unsigned long nr_to_scan,
17811785
}
17821786
}
17831787

1788+
// Totally nonsense, page_referenced() will always return 0.
17841789
if (page_referenced(page, 0, mz->mem_cgroup, &vm_flags)) {
17851790
nr_rotated += hpage_nr_pages(page);
17861791
/*
@@ -1797,7 +1802,16 @@ static void shrink_active_list(unsigned long nr_to_scan,
17971802
continue;
17981803
}
17991804
}
1800-
1805+
1806+
++(page->PG_referenced);
1807+
if (page->PG_referenced < PG_REFERENCED_SHRINK_THRESHOLD)
1808+
{
1809+
printk(KERN_INFO "Reserve a page with PG_referenced = %lu.\n", page->PG_referenced);
1810+
list_add(&page->lru, &l_active);
1811+
continue;
1812+
}
1813+
1814+
printk(KERN_INFO "De-activating a page!\n");
18011815
ClearPageActive(page); /* we are de-activating */
18021816
list_add(&page->lru, &l_inactive);
18031817
}
@@ -2643,7 +2657,8 @@ static bool pgdat_balanced(pg_data_t *pgdat, unsigned long balanced_pages,
26432657
{
26442658
unsigned long present_pages = 0;
26452659
int i;
2646-
2660+
2661+
//schedule_timeout(HZ/10);
26472662
for (i = 0; i <= classzone_idx; i++)
26482663
present_pages += pgdat->node_zones[i].present_pages;
26492664

@@ -2747,6 +2762,8 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
27472762
struct shrink_control shrink = {
27482763
.gfp_mask = sc.gfp_mask,
27492764
};
2765+
printk(KERN_INFO "Function balance_pgdat() invoked!\n");
2766+
27502767
loop_again:
27512768
total_scanned = 0;
27522769
sc.nr_reclaimed = 0;
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
LOCAL_PATH := $(call my-dir)
2+
3+
include $(CLEAR_VARS)
4+
LOCAL_SRC_FILES := memory_monitor.c # your source code
5+
LOCAL_MODULE := memory_monitor # output file name
6+
LOCAL_CFLAGS += -pie -fPIE # These two line mustn’t be
7+
LOCAL_LDFLAGS += -pie -fPIE # change.
8+
LOCAL_FORCE_STATIC_EXECUTABLE := true
9+
10+
include $(BUILD_EXECUTABLE)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include <stdlib.h>
2+
#include <string.h>
3+
#include <stdio.h>
4+
5+
/*
6+
* This program investigates the file /proc/meminfo
7+
* and prints out the 5th and 6th line in it.
8+
* The two specific lines contains the current size of
9+
* active and inactive memory. The examine() function
10+
* will be called every 1 second to continuously
11+
* monitor the memory status.
12+
*/
13+
14+
void examine()
15+
{
16+
char s[256];
17+
freopen("/proc/meminfo", "r", stdin);
18+
fgets(s, 256, stdin);
19+
fgets(s, 256, stdin);
20+
fgets(s, 256, stdin);
21+
fgets(s, 256, stdin);
22+
fgets(s, 256, stdin);
23+
fgets(s, 256, stdin);
24+
printf("%s", s);
25+
fgets(s, 256, stdin);
26+
printf("%s", s);
27+
}
28+
29+
int main(int argc, char *argv[])
30+
{
31+
int i;
32+
for (i = 0; i <= 20; ++i)
33+
{
34+
printf("After %d second(s):\n", i);
35+
examine();
36+
sleep(1);
37+
}
38+
return 0;
39+
}

Project 2/occupy_mem/jni/Android.mk

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
LOCAL_PATH := $(call my-dir)
2+
3+
include $(CLEAR_VARS)
4+
LOCAL_SRC_FILES := occupy_mem.c # your source code
5+
LOCAL_MODULE := occupy_mem # output file name
6+
LOCAL_CFLAGS += -pie -fPIE # These two line mustn’t be
7+
LOCAL_LDFLAGS += -pie -fPIE # change.
8+
LOCAL_FORCE_STATIC_EXECUTABLE := true
9+
10+
include $(BUILD_EXECUTABLE)

0 commit comments

Comments
 (0)