Skip to content

Commit

Permalink
Merge pull request utsaslab#128 from ashmrtn/port-4.9
Browse files Browse the repository at this point in the history
Port CrashMonkey to 4.9 series kernels
  • Loading branch information
vijay03 authored Jan 27, 2019
2 parents aa80c0f + 9182e7d commit 6076523
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 46 deletions.
12 changes: 12 additions & 0 deletions code/bio_alias.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@
#define BIO_DISCARD_FLAG REQ_DISCARD
#define BIO_IS_WRITE(bio) (!!(bio_rw(bio) & REQ_WRITE))

#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) \
&& LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)

#define BI_RW bi_opf
#define BI_DISK bi_bdev->bd_disk
#define BI_SIZE bi_iter.bi_size
#define BI_SECTOR bi_iter.bi_sector
#define BIO_ENDIO(bio, err) bio_endio(bio)
#define BIO_IO_ERR(bio, err) bio_io_error(bio)
#define BIO_DISCARD_FLAG REQ_OP_DISCARD
#define BIO_IS_WRITE(bio) op_is_write(bio_op(bio))

#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) \
&& LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)

Expand Down
2 changes: 1 addition & 1 deletion code/cow_brd.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ static blk_qc_t brd_make_request(struct request_queue *q, struct bio *bio) {
goto out_err;
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
if (unlikely(bio->BI_RW & BIO_DISCARD_FLAG)) {
#else
if (unlikely(bio_op(bio) == BIO_DISCARD_FLAG)) {
Expand Down
217 changes: 173 additions & 44 deletions code/disk_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,18 @@ static struct hwm_device {
struct gendisk* gd;
bool log_on;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0))
struct block_device* target_dev;
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
struct gendisk* target_dev;
u8 target_partno;
struct block_device* target_bd;
Expand Down Expand Up @@ -334,8 +336,8 @@ static unsigned long long convert_flags(unsigned long long flags) {
#endif
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
// These are flags present in 4.4 but not 3.13.
if (flags & REQ_PM) {
res |= HWM_PM_FLAG;
Expand All @@ -352,6 +354,115 @@ static unsigned long long convert_flags(unsigned long long flags) {
if (flags & REQ_NO_TIMEOUT) {
res |= HWM_NO_TIMEOUT_FLAG;
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
if ((flags >> BIO_OP_SHIFT) == REQ_OP_WRITE) {
res |= HWM_WRITE_FLAG;
}
if ((flags >> BIO_OP_SHIFT) == REQ_OP_DISCARD) {
res |= HWM_DISCARD_FLAG;
}
if ((flags >> BIO_OP_SHIFT) == REQ_OP_SECURE_ERASE) {
res |= HWM_SECURE_FLAG;
}
if ((flags >> BIO_OP_SHIFT) == REQ_OP_WRITE_SAME) {
res |= HWM_WRITE_SAME_FLAG;
}
if ((flags >> BIO_OP_SHIFT) == REQ_OP_FLUSH) {
res |= HWM_FLUSH_FLAG;
}
if (flags & REQ_FAILFAST_DEV) {
res |= HWM_FAILFAST_DEV_FLAG;
}
if (flags & REQ_FAILFAST_TRANSPORT) {
res |= HWM_FAILFAST_TRANSPORT_FLAG;
}
if (flags & REQ_FAILFAST_DRIVER) {
res |= HWM_FAILFAST_DRIVER_FLAG;
}
if (flags & REQ_SYNC) {
res |= HWM_SYNC_FLAG;
}
if (flags & REQ_META) {
res |= HWM_META_FLAG;
}
if (flags & REQ_PRIO) {
res |= HWM_PRIO_FLAG;
}
if (flags & REQ_NOIDLE) {
res |= HWM_NOIDLE_FLAG;
}
if (flags & REQ_FUA) {
res |= HWM_FUA_FLAG;
}
if (flags & REQ_PREFLUSH) {
res |= HWM_FLUSH_FLAG;
}
if (flags & REQ_RAHEAD) {
res |= HWM_READAHEAD_FLAG;
}
if (flags & REQ_THROTTLED) {
res |= HWM_THROTTLED_FLAG;
}
if (flags & REQ_SORTED) {
res |= HWM_SORTED_FLAG;
}
if (flags & REQ_SOFTBARRIER) {
res |= HWM_SOFTBARRIER_FLAG;
}
if (flags & REQ_NOMERGE) {
res |= HWM_NOMERGE_FLAG;
}
if (flags & REQ_STARTED) {
res |= HWM_STARTED_FLAG;
}
if (flags & REQ_DONTPREP) {
res |= HWM_DONTPREP_FLAG;
}
if (flags & REQ_QUEUED) {
res |= HWM_QUEUED_FLAG;
}
if (flags & REQ_ELVPRIV) {
res |= HWM_ELVPRIV_FLAG;
}
if (flags & REQ_FAILED) {
res |= HWM_FAILED_FLAG;
}
if (flags & REQ_QUIET) {
res |= HWM_QUIET_FLAG;
}
if (flags & REQ_PREEMPT) {
res |= HWM_PREEMPT_FLAG;
}
if (flags & REQ_ALLOCED) {
res |= HWM_ALLOCED_FLAG;
}
if (flags & REQ_COPY_USER) {
res |= HWM_COPY_USER_FLAG;
}
if (flags & REQ_FLUSH_SEQ) {
res |= HWM_FLUSH_SEQ_FLAG;
}
if (flags & REQ_IO_STAT) {
res |= HWM_IO_STAT_FLAG;
}
if (flags & REQ_MIXED_MERGE) {
res |= HWM_MIXED_MERGE_FLAG;
}
if (flags & REQ_PM) {
res |= HWM_PM_FLAG;
}
if (flags & REQ_INTEGRITY) {
res |= HWM_INTEGRITY_FLAG;
}
if (flags & REQ_HASHED) {
res |= HWM_HASHED_FLAG;
}
if (flags & REQ_MQ_INFLIGHT) {
res |= HWM_MQ_INFLIGHT_FLAG;
}


#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) \
&& LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)

Expand Down Expand Up @@ -421,8 +532,15 @@ static bool should_log(struct bio *bio) {
(bio->BI_RW & REQ_FLUSH || bio->BI_RW & REQ_FUA ||
bio->BI_RW & REQ_FLUSH_SEQ || bio->BI_RW & REQ_WRITE ||
bio->BI_RW & REQ_DISCARD);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) \
&& LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0))
return
((bio_flags(bio) & REQ_FUA) || (bio_flags(bio) & REQ_PREFLUSH) ||
(bio_op(bio) == REQ_OP_FLUSH) || (bio_op(bio) == REQ_OP_WRITE) ||
(bio_op(bio) == REQ_OP_DISCARD) || (bio_op(bio) == REQ_OP_SECURE_ERASE) ||
(bio_op(bio) == REQ_OP_WRITE_SAME) || (bio_flags(bio) & BIO_DISCARD_FLAG));
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) \
&& LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0))
// Other REQ_OP_xx functions are odd numbers, meaning they set the
// REQ_OP_WRITE bit which we already check for (ex. REQ_OP_WRITE_SAME = 7).
return
Expand Down Expand Up @@ -462,15 +580,17 @@ static void print_rw_flags(unsigned long rw, unsigned long flags) {
// TODO(ashmrtn): Currently not thread safe/reentrant. Make it so.
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
static void disk_wrapper_bio(struct request_queue* q, struct bio* bio) {
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0))
static blk_qc_t disk_wrapper_bio(struct request_queue* q, struct bio* bio) {
#else
#error "Unsupported kernel version: CrashMonkey has not been tested with " \
Expand Down Expand Up @@ -574,14 +694,19 @@ static blk_qc_t disk_wrapper_bio(struct request_queue* q, struct bio* bio) {
hwm = (struct hwm_device*) q->queuedata;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
bio->bi_bdev = hwm->target_dev;
submit_bio(bio->BI_RW, bio);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0))
bio->bi_bdev = hwm->target_dev;
submit_bio(bio);
return BLK_QC_T_NONE;
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
bio->bi_disk = hwm->target_dev;
Expand Down Expand Up @@ -656,12 +781,14 @@ static int __init disk_wrapper_init(void) {

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0))
Device.target_dev = target_device;
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
Expand All @@ -685,12 +812,12 @@ static int __init disk_wrapper_init(void) {
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
// Field not present in kernel 4.15+.
flush_flags = flags_device->bd_queue->flush_flags;
#endif
Expand Down Expand Up @@ -723,12 +850,12 @@ static int __init disk_wrapper_init(void) {
// Make this queue have the same flags as the queue we're feeding into.
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
Device.gd->queue->flush_flags = flush_flags;
#endif
Device.gd->queue->queue_flags = queue_flags;
Expand All @@ -742,7 +869,7 @@ static int __init disk_wrapper_init(void) {
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
printk(KERN_INFO "hwm: working with queue with:\n\tflush flags 0x%lx\n",
Device.gd->queue->flush_flags);
#endif
Expand All @@ -760,16 +887,18 @@ static int __init disk_wrapper_init(void) {
static void __exit hello_cleanup(void) {
free_logs();
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) || \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0))
blkdev_put(Device.target_dev, FMODE_READ);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
blkdev_put(Device.target_bd, FMODE_READ);
#else
#error "Unsupported kernel version: CrashMonkey has not been tested with " \
Expand Down
2 changes: 1 addition & 1 deletion docs/CrashMonkey.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ ___
#### Setting Up a VM ####
The easiest (and recommended) way to start working on (or using) CrashMonkey is to setup a virtual machine and run everything in the VM. This is partly so that any bugs in the kernel module don't bring down your whole system and partly because it is easier. Take a look at our [VM setup guide](vmsetup.md) to get started.

**CrashMonkey is known to work on kernel versions 3.13.0-121-generic, 4.4.0-62-generic, 4.15.0-041500-generic, and 4.16.0-041600rc7-generic.**
**CrashMonkey is known to work on kernel versions 3.13.0-121-generic, 4.4.0-62-generic, 4.9.0-040900rc8-generic, 4.15.0-041500-generic, and 4.16.0-041600rc7-generic.**

#### Dependencies and Build ####
Before you begin compilation, ensure you have satisfied all dependencies mentioned in the [setup guide](../README.md/#setup)
Expand Down

0 comments on commit 6076523

Please sign in to comment.