Skip to content

Commit 9b3d91e

Browse files
Merge branch 'no_kernel_modifications'
2 parents e7a6173 + cb26953 commit 9b3d91e

File tree

13 files changed

+211
-63
lines changed

13 files changed

+211
-63
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This library provides an optimized memory-mapped I/O path inside the Linux kerne
44

55
## Prerequisites
66

7-
FastMap runs on a modified version of Linux 4.14. To build and run this version of FastMap you can clone this kernel with:
7+
The main branch of FastMap runs on a modified version of Linux 4.14. To build and run this version of FastMap you can clone this kernel with:
88
```bash
99
git clone https://github.com/tpapagian/linux-4.14.72-spf.git -b fastmap
1010
```
@@ -13,6 +13,9 @@ The modifications are minimal as they contain only some exported symbols and the
1313

1414
After that, you should configure, build, and install this kernel using specific instructions based on your setup.
1515

16+
The no kernel modifications branch consists of a patchset so that FastMap can run on any Linux 4.14 kernel without any modifications being necessary. It should work properly,
17+
however it has not been tested as thoroughly as the main branch.
18+
1619
## Building FastMap
1720

1821
In order to build FastMap simply run ```make``` on the top-level directory. This will build the driver (located in the driver directory) and the associated userspace tools (located in the ioctl directory). After that, it will also install the FastMap module and run ```depmod```.

driver/Kbuild

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ dmap-objs := main.o \
2121
dmapfs_mmap.o \
2222
dmapfs_super.o \
2323
lpfifo_non_atomic.o \
24-
dfifo_non_atomic.o
24+
dfifo_non_atomic.o \
25+
kernel_syms.o

driver/dmap.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,17 @@ struct pr_vma_data
161161
unsigned long magic2; // -----
162162
};
163163

164+
/*
165+
* Struct used to encapsulate
166+
* fastmap structs required in vm_area_struct,
167+
* stored in vm_private_data member
168+
*/
169+
struct fastmap_info {
170+
bool is_fastmap;
171+
struct pr_vma_data *pvd;
172+
struct pr_vma_entry *pve;
173+
};
174+
164175
struct raw_device_data
165176
{
166177
int inuse;

driver/dmapfs_file.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ static ssize_t wrapfs_read(struct file *file, char __user *buf, size_t count, lo
237237

238238
lower_file = wrapfs_lower_file(file);
239239

240-
pvd = ((struct wrapfs_file_info*)file->private_data)->pvd;
240+
pvd = ((struct wrapfs_file_info*)file->private_data)->fmap_info->pvd;
241241

242242
if(
243243
(pvd != NULL)
@@ -313,7 +313,7 @@ static ssize_t wrapfs_write(struct file *file, const char __user *buf, size_t co
313313
unsigned int radix_tree_id;
314314
#endif
315315

316-
struct pr_vma_data *pvd = ((struct wrapfs_file_info*)file->private_data)->pvd;
316+
struct pr_vma_data *pvd = ((struct wrapfs_file_info*)file->private_data)->fmap_info->pvd;
317317

318318
if(
319319
(pvd != NULL)
@@ -376,7 +376,7 @@ static long dmap_priority_ioctl(struct file *file, unsigned int cmd, unsigned lo
376376
{
377377
#if 0
378378
int retval = 0;
379-
struct pr_vma_data *pvd = ((struct wrapfs_file_info*)file->private_data)->pvd;
379+
struct pr_vma_data *pvd = ((struct wrapfs_file_info*)file->private_data)->fmap_info->pvd;
380380
struct dmap_page_prio __user *__dpp_p;
381381
struct dmap_page_prio __dpp_d;
382382

@@ -487,6 +487,12 @@ static int wrapfs_open(struct inode *inode, struct file *file)
487487
goto out_err;
488488
}
489489

490+
((struct wrapfs_file_info *)file->private_data)->fmap_info = kzalloc(sizeof(struct fastmap_info), GFP_KERNEL);
491+
if(!((struct wrapfs_file_info *)file->private_data)->fmap_info){
492+
err = -ENOMEM;
493+
goto out_err;
494+
}
495+
490496
/* open lower object and link wrapfs's file struct to lower's */
491497
wrapfs_get_lower_path(file->f_path.dentry, &lower_path);
492498
lower_file = dentry_open(&lower_path, file->f_flags, current_cred());
@@ -527,7 +533,7 @@ static int wrapfs_open(struct inode *inode, struct file *file)
527533

528534
// set it to the private data of the file
529535
DMAP_BGON( (pvd->magic1 != PVD_MAGIC_1) || (pvd->magic2 != PVD_MAGIC_2) );
530-
((struct wrapfs_file_info*)file->private_data)->pvd = pvd;
536+
((struct wrapfs_file_info*)file->private_data)->fmap_info->pvd = pvd;
531537
}
532538

533539
if (IS_ERR(lower_file)) {
@@ -588,11 +594,11 @@ static int wrapfs_file_release(struct inode *inode, struct file *file)
588594

589595
lower_file = wrapfs_lower_file(file);
590596

591-
pvd = ((struct wrapfs_file_info*)file->private_data)->pvd;
597+
pvd = ((struct wrapfs_file_info*)file->private_data)->fmap_info->pvd;
592598
if(pvd != NULL && pvd->is_mmap == true && pvd->is_valid == true && atomic64_read(&pvd->mmaped) == 1){
593599

594600
if(lower_file)
595-
((struct wrapfs_file_info*)file->private_data)->pvd->bk.filp = lower_file;
601+
((struct wrapfs_file_info*)file->private_data)->fmap_info->pvd->bk.filp = lower_file;
596602
else
597603
DMAP_BGON(1);
598604

@@ -613,12 +619,12 @@ static int wrapfs_file_release(struct inode *inode, struct file *file)
613619

614620
for(i = 0; i < MAX_OPEN_FDS; ++i){
615621
if(pvd->open_fds[i] != NULL && pvd->open_fds[i]->f_inode != NULL){
616-
((struct wrapfs_file_info*)file->private_data)->pvd->bk.filp = pvd->open_fds[i];
622+
((struct wrapfs_file_info*)file->private_data)->fmap_info->pvd->bk.filp = pvd->open_fds[i];
617623
break;
618624
}
619625
}
620626

621-
((struct wrapfs_file_info*)file->private_data)->pvd = NULL;
627+
((struct wrapfs_file_info*)file->private_data)->fmap_info->pvd = NULL;
622628
}else if(pvd != NULL){
623629
for(i = 0; i < MAX_OPEN_FDS; ++i)
624630
if(pvd->open_fds[i] == lower_file){
@@ -644,7 +650,7 @@ static int wrapfs_fsync(struct file *file, loff_t start, loff_t end, int datasyn
644650
struct dentry *dentry = file->f_path.dentry;
645651
struct pr_vma_data *pvd;
646652

647-
pvd = ((struct wrapfs_file_info*)file->private_data)->pvd;
653+
pvd = ((struct wrapfs_file_info*)file->private_data)->fmap_info->pvd;
648654
if(pvd == NULL)
649655
goto mmap_fsync;
650656

@@ -712,7 +718,7 @@ wrapfs_read_iter(struct kiocb *iocb, struct iov_iter *iter)
712718
struct file *file = iocb->ki_filp, *lower_file;
713719

714720
#ifdef DEBUG_DIRECT_RW
715-
struct pr_vma_data *pvd = ((struct wrapfs_file_info*)file->private_data)->pvd;
721+
struct pr_vma_data *pvd = ((struct wrapfs_file_info*)file->private_data)->fmap_info->pvd;
716722
if(pvd != NULL){
717723
DMAP_BGON( (pvd->magic1 != PVD_MAGIC_1) || (pvd->magic2 != PVD_MAGIC_2) );
718724
WARN(atomic64_read(&pvd->cnt) > 0, "[%s:%s:%d][%ld]\n", __FILE__, __func__, __LINE__, atomic64_read(&pvd->cnt));
@@ -750,7 +756,7 @@ wrapfs_write_iter(struct kiocb *iocb, struct iov_iter *iter)
750756
struct file *file = iocb->ki_filp, *lower_file;
751757

752758
#ifdef DEBUG_DIRECT_RW
753-
struct pr_vma_data *pvd = ((struct wrapfs_file_info*)file->private_data)->pvd;
759+
struct pr_vma_data *pvd = ((struct wrapfs_file_info*)file->private_data)->fmap_info->pvd;
754760
if(pvd != NULL){
755761
DMAP_BGON( (pvd->magic1 != PVD_MAGIC_1) || (pvd->magic2 != PVD_MAGIC_2) );
756762
WARN(atomic64_read(&pvd->cnt) > 0, "[%s:%s:%d][%ld]\n", __FILE__, __func__, __LINE__, atomic64_read(&pvd->cnt));

driver/helpers.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ void zap_page_from_address_space(struct vm_area_struct *vma, unsigned long addre
3939

4040
DMAP_BGON(vma->vm_mm == NULL);
4141

42+
pvmw.pte = NULL;
43+
pvmw.ptl = NULL;
44+
4245
/* If the pte returned is valid, the lock will also be held. */
4346
while(page_vma_mapped_walk(&pvmw)){
4447
if(pvmw.pte){

driver/kernel_syms.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include <linux/kallsyms.h>
2+
#include <linux/fs.h>
3+
#include <linux/mm_types.h>
4+
#include <linux/types.h>
5+
#include <linux/compiler_types.h>
6+
#include <linux/rmap.h>
7+
8+
/* Auxiliary function pointers here */
9+
10+
void (*flush_tlb_mm_range_ksym)(struct mm_struct *mm, unsigned long start,
11+
unsigned long end, unsigned long vmflag);
12+
13+
ssize_t (*vfs_read_ksym)(struct file *file, char __user *buf,
14+
size_t count, loff_t *pos);
15+
16+
ssize_t (*vfs_write_ksym)(struct file *file, const char __user *buf,
17+
size_t count, loff_t *pos);
18+
19+
void (*wake_up_page_bit_ksym)(struct page *page, int bit_nr);
20+
21+
bool (*page_vma_mapped_walk_ksym)(struct page_vma_mapped_walk *pvmw);
22+
23+
int acquire_ksyms(void)
24+
{
25+
/*
26+
* Try to find all necessary symbols,
27+
* return -1 if any lookup fails
28+
*/
29+
flush_tlb_mm_range_ksym = (void *)kallsyms_lookup_name("flush_tlb_mm_range");
30+
if(!flush_tlb_mm_range_ksym)
31+
return -1;
32+
33+
vfs_read_ksym = (void *)kallsyms_lookup_name("vfs_read");
34+
if(!vfs_read_ksym)
35+
return -1;
36+
37+
vfs_write_ksym = (void *)kallsyms_lookup_name("vfs_write");
38+
if(!vfs_write_ksym)
39+
return -1;
40+
41+
wake_up_page_bit_ksym = (void *)kallsyms_lookup_name("wake_up_page_bit");
42+
if(!wake_up_page_bit_ksym)
43+
return -1;
44+
45+
page_vma_mapped_walk_ksym = (void *)kallsyms_lookup_name("page_vma_mapped_walk");
46+
if(!page_vma_mapped_walk_ksym)
47+
return -1;
48+
49+
return 0;
50+
}
51+
52+
/*
53+
* Provide the unexported kernel symbols
54+
* by calling the appropriate initialized
55+
* function pointer
56+
*/
57+
void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
58+
unsigned long end, unsigned long vmflag)
59+
{
60+
flush_tlb_mm_range_ksym(mm, start, end, vmflag);
61+
}
62+
63+
ssize_t vfs_read(struct file *file, char __user *buf,
64+
size_t count, loff_t *pos)
65+
{
66+
return vfs_read_ksym(file, buf, count, pos);
67+
}
68+
69+
ssize_t vfs_write(struct file *file, const char __user *buf,
70+
size_t count, loff_t *pos)
71+
{
72+
return vfs_write_ksym(file, buf, count, pos);
73+
}
74+
75+
void wake_up_page_bit(struct page *page, int bit_nr)
76+
{
77+
wake_up_page_bit_ksym(page, bit_nr);
78+
}
79+
80+
bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
81+
{
82+
return page_vma_mapped_walk_ksym(pvmw);
83+
}

driver/main.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ extern void write_bio_tagged_page(struct tagged_page *evicted_page);
102102
extern void write_dirty_pages(struct pr_vma_data *pvd, void (*__page_cleanup)(struct tagged_page *));
103103

104104
extern void ino_cache_init(void);
105+
extern int acquire_ksyms(void);
105106

106107
#ifdef USE_HUGEPAGES
107108
struct page *hugepages[16];
@@ -183,6 +184,7 @@ static int raw_open(struct inode *inode, struct file *filp)
183184
const int minor = iminor(inode);
184185
struct block_device *bdev;
185186
struct pr_vma_data *pvd;
187+
struct fastmap_info *fmap_info;
186188
int cpu, err;
187189

188190
if (minor == 0)
@@ -216,6 +218,15 @@ static int raw_open(struct inode *inode, struct file *filp)
216218
file_inode(filp)->i_mapping = bdev->bd_inode->i_mapping;
217219

218220
//filp->private_data = &raw_devices[minor];
221+
222+
/* Allocate fastmap_info struct first */
223+
fmap_info = kzalloc(sizeof(struct fastmap_info), GFP_KERNEL);
224+
DMAP_BGON(fmap_info == NULL);
225+
/*
226+
* Since kzalloc is used all fmap_info members are initialized
227+
* to 0, therefore there is no need to set is_fastmap and pve
228+
* to false and NULL respectively
229+
*/
219230
pvd = kzalloc(sizeof(struct pr_vma_data), GFP_KERNEL);
220231
DMAP_BGON(pvd == NULL);
221232

@@ -250,7 +261,9 @@ static int raw_open(struct inode *inode, struct file *filp)
250261

251262
pvd->magic2 = PVD_MAGIC_2;
252263

253-
filp->private_data = pvd;
264+
fmap_info->pvd = pvd;
265+
266+
filp->private_data = fmap_info;
254267

255268
mutex_unlock(&raw_mutex);
256269

@@ -282,7 +295,7 @@ static int raw_release(struct inode *inode, struct file *filp)
282295

283296
printk(KERN_ERR "[%s:%s:%d] Calling release\n", __FILE__, __func__, __LINE__);
284297

285-
pvd = (struct pr_vma_data *)filp->private_data;
298+
pvd = ((struct fastmap_info *)filp->private_data)->pvd;
286299
if(pvd != NULL){
287300

288301

@@ -858,7 +871,7 @@ int dmap_fsync(struct file *file, loff_t start, loff_t end, int datasync)
858871
{
859872
#if 1
860873
struct mm_struct *mm = current->mm;
861-
struct pr_vma_data *pvd = (struct pr_vma_data *)file->private_data;
874+
struct pr_vma_data *pvd = ((struct fastmap_info *)file->private_data)->pvd;
862875

863876
printk(KERN_ERR "Calling msync() .....\n");
864877
down_write(&mm->mmap_sem);
@@ -1214,6 +1227,12 @@ static int __init raw_init(void)
12141227

12151228
memset(&dimmap_buffer, 0, sizeof(dimmap_buffer_t));
12161229

1230+
/* Try to find the unexported kernel symbols which we need */
1231+
if(acquire_ksyms() == -1){
1232+
printk(KERN_ERR "Could not translate all necessary kernel symbols\n");
1233+
return -EINVAL;
1234+
}
1235+
12171236
/* Loadtime buffer parameters */
12181237
init_ld_params(&dimmap_buffer.ld_params);
12191238
dimmap_buffer.ld_params.mmap_buf_size = perma_mmap_buf_size >> 0;

driver/mmap_banked_buffer.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ void cleanup_mmap_buffer_data_banked_buffer_t(banked_buffer_t *buf)
8181

8282
printk(KERN_INFO "Cleaning up data structures for the banked buffer\n");
8383
cleanup_mmap_buffer_data(buf->banks);
84-
kfree(buf->banks);
8584
kfree(buf);
8685
}
8786

0 commit comments

Comments
 (0)