From 8074328a9007b270216ed810399f010eb7726b28 Mon Sep 17 00:00:00 2001 From: borunfu Date: Fri, 27 Sep 2024 02:08:46 -0400 Subject: [PATCH 01/16] Makefile: support os vendors' kernel release naming rule The naming rule of Linux kernel versions. Take the CentOS kernel version 4.18.0-425.19.2 as an example. The meanings of each field are as follows. "4": This is the major version number. Kernels with different major version numbers may have significant differences in functions and features. "18": It is the minor version number. An increase in the minor version number generally indicates that the kernel has significant improvements and enhancements in functionality, but usually still maintains a certain degree of compatibility with the previous major version. "0": It is the revision version number or patch level. Changes in the revision version number usually mean that some minor fixes, optimizations, or functional fine-tunings have been made to the kernel. "425": This is the CentOS-specific kernel release version number. This release version number is added by CentOS, and it is usually associated with CentOS's system update and release cycle. Please *NOTE*, CentOS ensures the compatibility of KABI up to this level, that is, the kernels with the same release version are KABI compatible. "19": It is the update sequence number under this release version. "2": This is a more fine-grained revision number or patch level. In general, this kernel version number format is a common way of numbering Linux kernel versions. It combines the version information of the upstream kernel and OSV's own release management information so that users and system administrators can accurately identify and manage the kernel version used by the system. It should be noted that different Linux distributions may have some slight differences in the format and meaning of the kernel version number, but in general, they are numbered based on similar principles. Signed-off-by: Borun Fu --- Makefile | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1b0ffc1..69a7306 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,11 @@ ifneq ($(KERNEL_BUILD_PATH), $(wildcard $(KERNEL_BUILD_PATH))) KERNEL_BUILD_PATH := /lib/modules/$(KERNEL_VERSION)/build endif +KMAJOR := $(shell echo $(KERNEL_VERSION) | cut -d. -f1) +KMINOR := $(shell echo $(KERNEL_VERSION) | cut -d. -f2) +KPATCH := $(shell echo $(KERNEL_VERSION) | cut -d. -f3 | cut -d- -f1) +KRELEASE := $(shell echo $(KERNEL_VERSION) | cut -d- -f2 | cut -d. -f1) +KSUBRELEASE := $(shell echo $(KERNEL_VERSION) | cut -d- -f2 | cut -d. -f2) ifneq ($(KERNELRELEASE),) #common @@ -57,8 +62,20 @@ obj-m += sysak.o EXTRA_CFLAGS := -I$(MODULE_SRC) EXTRA_CFLAGS += -I$(MODULE_SRC)/include +EXTRA_CFLAGS += -DKMAJOR=${KMAJOR} -DKMINOR=${KMINOR} -DKPATCH=${KPATCH} -DKRELEASE=${KRELEASE} -DKSUBRELEASE=${KSUBRELEASE} ifneq ($(findstring iosdiag,$(TARGET_LIST)),) -EXTRA_CFLAGS += -I$(MODULE_SRC)/modules/iosdiag -I$(MODULE_SRC)/modules/iosdiag/include/$(KERNEL_VERSION) +IOSDIAG_MODULE_SRC := $(MODULE_SRC)/modules/iosdiag +EXTRA_CFLAGS += -I$(IOSDIAG_MODULE_SRC) +IOSDIAG_INCLUDE_DIR := $(IOSDIAG_MODULE_SRC)/include + +ifneq ($(wildcard $(IOSDIAG_INCLUDE_DIR)/$(KERNEL_VERSION)),) +EXTRA_CFLAGS += -I$(IOSDIAG_INCLUDE_DIR)/$(KERNEL_VERSION) +else ifneq ($(wildcard $(IOSDIAG_INCLUDE_DIR)/$(KMAJOR).$(KMINOR).$(KPATCH)-$(KRELEASE)),) +EXTRA_CFLAGS += -I$(IOSDIAG_INCLUDE_DIR)/$(KMAJOR).$(KMINOR).$(KPATCH)-$(KRELEASE) +else +EXTRA_CFLAGS += -I$(IOSDIAG_INCLUDE_DIR)/$(KMAJOR).$(KMINOR).$(KPATCH) +endif + endif else -- Gitee From fcaec7166ab5167bb28c61824fb404e337d16411 Mon Sep 17 00:00:00 2001 From: borunfu Date: Sat, 28 Sep 2024 22:34:44 -0400 Subject: [PATCH 02/16] blackbox: Adapt to centos kernel 4.18.0 Signed-off-by: Borun Fu --- common/blackbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/blackbox.c b/common/blackbox.c index ddc844b..62756a9 100644 --- a/common/blackbox.c +++ b/common/blackbox.c @@ -150,7 +150,7 @@ static ssize_t bbox_record_write(struct bbox_info *bbox, r_info->pid = data_info->task->pid; #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0) r_info->state = data_info->task->__state; -#elif LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) +#elif LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) && KRELEASE >= 372 r_info->state = data_info->task->__state; #else r_info->state = data_info->task->state; -- Gitee From a3d283c7dbaf41b92698eb191421f004ef152f3f Mon Sep 17 00:00:00 2001 From: Jianhua Fu Date: Tue, 24 Sep 2024 05:43:33 -0400 Subject: [PATCH 03/16] trace_sig: Adapt to centos kernel 4.18.0 Signed-off-by: Jianhua Fu --- modules/signal/trace_sig.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/signal/trace_sig.c b/modules/signal/trace_sig.c index 8b02dfa..d61af47 100755 --- a/modules/signal/trace_sig.c +++ b/modules/signal/trace_sig.c @@ -117,7 +117,9 @@ static void trace_sig_disable(void) unhook_tracepoint("signal_generate", signal_generate_trace, NULL); #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) synchronize_rcu(); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) || LINUX_VERSION_CODE <= KERNEL_VERSION(4, 17, 0) +#elif LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) + synchronize_rcu(); +#else synchronize_sched(); #endif bbox_free(tracesig_bid); -- Gitee From 170ff64cfb0b9c8dcfb2466fc3ca1795796e0db0 Mon Sep 17 00:00:00 2001 From: Borun Fu Date: Mon, 23 Sep 2024 04:53:46 -0400 Subject: [PATCH 04/16] memleak: Adapt to centos kernel 4.18.0 Signed-off-by: Borun Fu --- modules/memleak/mem.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/modules/memleak/mem.h b/modules/memleak/mem.h index 9ee4cce..62677b8 100755 --- a/modules/memleak/mem.h +++ b/modules/memleak/mem.h @@ -99,6 +99,31 @@ static inline void *slab_address(const struct slab *slab) return folio_address(slab_folio(slab)); } #endif + +#if LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) +struct memcg_cache_params { + struct kmem_cache *root_cache; + union { + struct { + struct memcg_cache_array __rcu *memcg_caches; + struct list_head __root_caches_node; + struct list_head children; + bool dying; + }; + struct { + struct mem_cgroup *memcg; + struct list_head children_node; + struct list_head kmem_caches_node; + void (*deact_fn)(struct kmem_cache *); + union { + struct rcu_head deact_rcu_head; + struct work_struct deact_work; + }; + }; + }; +}; +#endif + #include #include #include -- Gitee From 404e88f36eed5f6f97be9a8e6ea3ee3fcb3b950f Mon Sep 17 00:00:00 2001 From: Borun Fu Date: Tue, 24 Sep 2024 23:07:43 -0400 Subject: [PATCH 05/16] memleak: Fix macro typo Signed-off-by: Borun Fu --- modules/memleak/memleak.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/memleak/memleak.c b/modules/memleak/memleak.c index d693b59..bdf6aec 100755 --- a/modules/memleak/memleak.c +++ b/modules/memleak/memleak.c @@ -253,7 +253,7 @@ static int slab_tracepoint_init(void) if (ret) { pr_err("memleak register kmalloc node tracepoint error %d\n", ret); } -#ifdef CONFIG_NUMA +#ifdef CONFIG_TRACING ret = hook_tracepoint("kmem_cache_alloc_node", trace_slab_alloc_node, NULL); if (ret) { pr_err("memleak register kmem_cache_alloc node tracepoint error %d\n", ret); -- Gitee From b225a9c8ff86cc7aecdd3a6015715073d952ba91 Mon Sep 17 00:00:00 2001 From: borunfu Date: Sat, 28 Sep 2024 22:46:43 -0400 Subject: [PATCH 06/16] runlatency: Adapt to centos kernel 4.18.0 Signed-off-by: Borun Fu --- modules/sched/trace_runqlat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/sched/trace_runqlat.c b/modules/sched/trace_runqlat.c index 7879f77..c0a996c 100644 --- a/modules/sched/trace_runqlat.c +++ b/modules/sched/trace_runqlat.c @@ -284,7 +284,7 @@ static void probe_sched_switch(void *priv, bool preempt, if (READ_ONCE(info->pid) != prev->pid || #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0) prev->__state != TASK_RUNNING) -#elif LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) +#elif LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) && KRELEASE >= 372 prev->__state != TASK_RUNNING) #else prev->state != TASK_RUNNING) @@ -332,7 +332,7 @@ static void probe_sched_switch(void *priv, bool preempt, } else if (info->pid == prev->pid) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0) if (prev->__state == TASK_RUNNING) { -#elif LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) +#elif LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) && KRELEASE >= 372 if (prev->__state == TASK_RUNNING) { #else if (prev->state == TASK_RUNNING) { -- Gitee From 96ddcbab64d4e1bd5ce402c8fa759f0f51f81279 Mon Sep 17 00:00:00 2001 From: borunfu Date: Sat, 28 Sep 2024 22:37:10 -0400 Subject: [PATCH 07/16] task_ctl: Adapt to centos kernel 4.18.0 Signed-off-by: Borun Fu --- modules/task_ctl/task_ctrl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/task_ctl/task_ctrl.c b/modules/task_ctl/task_ctrl.c index 064bef7..e7331f3 100755 --- a/modules/task_ctl/task_ctrl.c +++ b/modules/task_ctl/task_ctrl.c @@ -66,7 +66,9 @@ static void task_ctl_disable(void) unhook_tracepoint("sys_enter", syscall_enter_trace, NULL); #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) synchronize_rcu(); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) || LINUX_VERSION_CODE <= KERNEL_VERSION(4, 17, 0) +#elif LINUX_VERSION_CODE <= KERNEL_VERSION(4, 18, 0) + synchronize_rcu(); +#else synchronize_sched(); #endif ctl_enabled = false; -- Gitee From 5a40c60b6d16c82d353420f5801fae3052dee419 Mon Sep 17 00:00:00 2001 From: Borun Fu Date: Mon, 23 Sep 2024 05:00:36 -0400 Subject: [PATCH 08/16] schedtrace: Adapt to centos kernel 4.18.0 Signed-off-by: Borun Fu --- modules/schedtrace/schedtrace.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/schedtrace/schedtrace.c b/modules/schedtrace/schedtrace.c index 88accb6..8694934 100644 --- a/modules/schedtrace/schedtrace.c +++ b/modules/schedtrace/schedtrace.c @@ -103,7 +103,11 @@ static void trace_sched_switch(void *priv, bool preempt, int i, size = 0; p = prev; +#if LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) && KRELEASE >= 372 + if (((pid_t)target_pid == p->pid) && (p->__state)) { +#else if (((pid_t)target_pid == p->pid) && (p->state)) { +#endif struct traceinfo *tf = &traceinfos; struct stack_trace *trace = tf->trace; int idx = tf->idx; @@ -231,9 +235,17 @@ int schedtrace_init(void) for_each_kernel_tracepoint(tracepoint_lookup, &mytp); #endif stack_save_tsk = (void *)kallsyms_lookup_name("save_stack_trace_tsk"); +#if LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) + /* + * save_stack_trace_tsk was removed by Redhat on CentOS 4.18. + * However, stack_save_regs defined but not used, ignore! + */ + if (!stack_save_tsk) { +#else stack_save_regs = (void *)kallsyms_lookup_name("save_stack_trace_regs"); if (!stack_save_tsk || !stack_save_regs) { +#endif ret = -EINVAL; pr_warn("stack_save not found\n"); goto fail; -- Gitee From 7ba7763ff9058ad14d8733a256803676d9e73357 Mon Sep 17 00:00:00 2001 From: Borun Fu Date: Tue, 24 Sep 2024 06:32:37 -0400 Subject: [PATCH 09/16] mmaptrace: Adapt to centos kernel 4.18.0 Signed-off-by: Borun Fu --- modules/mmaptrace/mmaptrace.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/mmaptrace/mmaptrace.c b/modules/mmaptrace/mmaptrace.c index da9aefb..9c71c46 100644 --- a/modules/mmaptrace/mmaptrace.c +++ b/modules/mmaptrace/mmaptrace.c @@ -47,7 +47,7 @@ LIST_HEAD(threadvma_list); DECLARE_RWSEM(threadslist_sem); DECLARE_RWSEM(vmalist_sem); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) static struct kprobe kp_mmap = { .symbol_name = "ksys_mmap_pgoff", }; @@ -337,6 +337,8 @@ static ssize_t mmaptrace_pid_store(void *priv, const char __user *buf, size_t co } #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) if (!mmap_read_trylock(mm)){ +#elif LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) + if (!mmap_read_trylock(mm)){ #else if (!down_read_trylock(&mm->mmap_sem)){ #endif @@ -350,6 +352,8 @@ static ssize_t mmaptrace_pid_store(void *priv, const char __user *buf, size_t co if (!new_vma){ #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) mmap_read_unlock(mm); +#elif LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) + mmap_read_unlock(mm); #else up_read(&mm->mmap_sem); #endif @@ -371,6 +375,8 @@ static ssize_t mmaptrace_pid_store(void *priv, const char __user *buf, size_t co } #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) mmap_read_unlock(mm); +#elif LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) + mmap_read_unlock(mm); #else up_read(&mm->mmap_sem); #endif -- Gitee From 2cad1591dc9d7ffc3d110efa5e04fea5a364f06d Mon Sep 17 00:00:00 2001 From: Borun Fu Date: Tue, 24 Sep 2024 06:34:57 -0400 Subject: [PATCH 10/16] ulockcheck: Adapt to centos kernel 4.18.0 Signed-off-by: Borun Fu --- modules/ulockcheck/ulockcheck.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/ulockcheck/ulockcheck.c b/modules/ulockcheck/ulockcheck.c index 29ff4ca..5083ba3 100644 --- a/modules/ulockcheck/ulockcheck.c +++ b/modules/ulockcheck/ulockcheck.c @@ -399,6 +399,8 @@ static ssize_t futexpid_store(void *priv, const char __user *buf, size_t count) } #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) if (!mmap_read_trylock(mm)){ +#elif LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) + if (!mmap_read_trylock(mm)){ #else if (!down_read_trylock(&mm->mmap_sem)){ #endif @@ -414,6 +416,8 @@ static ssize_t futexpid_store(void *priv, const char __user *buf, size_t count) if (!new_vma){ #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) mmap_read_unlock(mm); +#elif LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) + mmap_read_unlock(mm); #else up_read(&mm->mmap_sem); #endif @@ -432,6 +436,8 @@ static ssize_t futexpid_store(void *priv, const char __user *buf, size_t count) } #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) mmap_read_unlock(mm); +#elif LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) + mmap_read_unlock(mm); #else up_read(&mm->mmap_sem); #endif -- Gitee From a05c9dffa56542f038854f7eaf9cb31ccfbe71ff Mon Sep 17 00:00:00 2001 From: Borun Fu Date: Mon, 23 Sep 2024 22:20:39 -0400 Subject: [PATCH 11/16] memhunter: Adapt to centos kernel 4.18.0 Signed-off-by: Borun Fu --- modules/memhunter/common.c | 5 +++-- modules/memhunter/common.h | 23 +++++++++++++++++++++++ modules/memhunter/filecache.c | 4 +++- modules/memhunter/memcg.c | 12 ++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/modules/memhunter/common.c b/modules/memhunter/common.c index f69daaa..e795dca 100644 --- a/modules/memhunter/common.c +++ b/modules/memhunter/common.c @@ -15,14 +15,15 @@ #include #include #include + +#include "common.h" + #include #include #include #include #include -#include "common.h" - int prepend(char **buffer, int *buflen, const char *str, int namelen) { *buflen -= namelen; diff --git a/modules/memhunter/common.h b/modules/memhunter/common.h index f111575..3e0ddf6 100644 --- a/modules/memhunter/common.h +++ b/modules/memhunter/common.h @@ -11,6 +11,29 @@ #include #include #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 9) +#if LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) +struct memcg_cache_params { + struct kmem_cache *root_cache; + union { + struct { + struct memcg_cache_array __rcu *memcg_caches; + struct list_head __root_caches_node; + struct list_head children; + bool dying; + }; + struct { + struct mem_cgroup *memcg; + struct list_head children_node; + struct list_head kmem_caches_node; + void (*deact_fn)(struct kmem_cache *); + union { + struct rcu_head deact_rcu_head; + struct work_struct deact_work; + }; + }; + }; +}; +#endif #include #include #include diff --git a/modules/memhunter/filecache.c b/modules/memhunter/filecache.c index 29639fd..4d93105 100644 --- a/modules/memhunter/filecache.c +++ b/modules/memhunter/filecache.c @@ -16,6 +16,9 @@ #include #include #include + +#include "common.h" + #include #include #include @@ -23,7 +26,6 @@ #include #include #include -#include "common.h" static unsigned long totalCache = 0; static char * fileName = NULL; diff --git a/modules/memhunter/memcg.c b/modules/memhunter/memcg.c index b90043d..960c7bf 100644 --- a/modules/memhunter/memcg.c +++ b/modules/memhunter/memcg.c @@ -120,7 +120,11 @@ static void get_lru_page(struct memcg_item *item, struct lruvec *vec) return; } if(pgdat) +#if LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) && KRELEASE >= 348 + spin_lock_irqsave(&pgdat->__lruvec.lru_lock, flags); +#else spin_lock_irqsave(&pgdat->lru_lock, flags); +#endif #endif for_each_lru(lru) { struct list_head *list = &vec->lists[lru]; @@ -133,8 +137,12 @@ static void get_lru_page(struct memcg_item *item, struct lruvec *vec) spin_unlock_irqrestore(&lruzone->lru_lock, flags); #else if (pgdat) +#if LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) && KRELEASE >= 348 + spin_unlock_irqrestore(&pgdat->__lruvec.lru_lock, flags); +#else spin_unlock_irqrestore(&pgdat->lru_lock, flags); #endif +#endif } static void get_memcg_page(struct memcg_item *item) @@ -152,7 +160,11 @@ static void get_memcg_page(struct memcg_item *item) struct mem_cgroup_per_node *mz; int nid; for_each_node(nid) { +#if LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) + mz = item->memcg->nodeinfo[nid]; +#else mz = mem_cgroup_nodeinfo(item->memcg, nid); +#endif get_lru_page(item, &mz->lruvec); } #endif -- Gitee From 89fd63c47b76756aba11be971b711a0b9415a617 Mon Sep 17 00:00:00 2001 From: Borun Fu Date: Mon, 23 Sep 2024 06:33:27 -0400 Subject: [PATCH 12/16] iosdiag: Add header files for centos 4.18.0-425 Signed-off-by: Borun Fu --- modules/iosdiag/include/4.18.0-425/nvme.h | 63 ++++ .../iosdiag/include/4.18.0-425/virtio_blk.h | 330 ++++++++++++++++++ 2 files changed, 393 insertions(+) create mode 100644 modules/iosdiag/include/4.18.0-425/nvme.h create mode 100644 modules/iosdiag/include/4.18.0-425/virtio_blk.h diff --git a/modules/iosdiag/include/4.18.0-425/nvme.h b/modules/iosdiag/include/4.18.0-425/nvme.h new file mode 100644 index 0000000..3e554d7 --- /dev/null +++ b/modules/iosdiag/include/4.18.0-425/nvme.h @@ -0,0 +1,63 @@ +#ifndef _NVME_H +#define _NVME_H + +#include +#include +#include +#include +#include +#include +#include "iosdiag.h" + +struct nvme_queue { + struct nvme_dev *dev; + spinlock_t sq_lock; + void *sq_cmds; + /* only used for poll queues: */ + spinlock_t cq_poll_lock ____cacheline_aligned_in_smp; + struct nvme_completion *cqes; + dma_addr_t sq_dma_addr; + dma_addr_t cq_dma_addr; + u32 __iomem *q_db; + u32 q_depth; + u16 cq_vector; + u16 sq_tail; + u16 last_sq_tail; + u16 cq_head; + u16 qid; + u8 cq_phase; + u8 sqes; + unsigned long flags; +#define NVMEQ_ENABLED 0 +#define NVMEQ_SQ_CMB 1 +#define NVMEQ_DELETE_ERROR 2 +#define NVMEQ_POLLED 3 + u32 *dbbuf_sq_db; + u32 *dbbuf_cq_db; + u32 *dbbuf_sq_ei; + u32 *dbbuf_cq_ei; + struct completion delete_done; +}; + +static int get_sq_rq_idx(struct nvme_queue *nvmeq, struct request *rq) +{ + int tail = nvmeq->sq_tail; + struct nvme_command cmd; + + do { + if (tail >= nvmeq->q_depth) + break; + memcpy(&cmd, nvmeq->sq_cmds + (tail << nvmeq->sqes), sizeof(cmd)); + if (cmd.common.command_id == rq->tag) + return tail; + } while (--tail >= 0); + return -1; +} + +static unsigned long get_cmd_ctx(struct nvme_queue *nvmeq, + struct request *rq) +{ + //struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + return 0; +} +#endif diff --git a/modules/iosdiag/include/4.18.0-425/virtio_blk.h b/modules/iosdiag/include/4.18.0-425/virtio_blk.h new file mode 100644 index 0000000..a2edeca --- /dev/null +++ b/modules/iosdiag/include/4.18.0-425/virtio_blk.h @@ -0,0 +1,330 @@ +#ifndef _VIRTIO_BLK_H +#define _VIRTIO_BLK_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iosdiag.h" + +struct vring_desc_state_split { + void *data; /* Data for callback. */ + struct vring_desc *indir_desc; /* Indirect descriptor, if any. */ +}; + +struct vring_desc_state_packed { + void *data; /* Data for callback. */ + struct vring_packed_desc *indir_desc; /* Indirect descriptor, if any. */ + u16 num; /* Descriptor list length. */ + u16 last; /* The last desc state in a list. */ +}; + +struct vring_desc_extra { + dma_addr_t addr; /* Descriptor DMA addr. */ + u32 len; /* Descriptor length. */ + u16 flags; /* Descriptor flags. */ + u16 next; /* The next desc state in a list. */ +}; + +struct vring_virtqueue { + struct virtqueue vq; + + /* Is this a packed ring? */ + bool packed_ring; + + /* Is DMA API used? */ + bool use_dma_api; + + /* Can we use weak barriers? */ + bool weak_barriers; + + /* Other side has made a mess, don't try any more. */ + bool broken; + + /* Host supports indirect buffers */ + bool indirect; + + /* Host publishes avail event idx */ + bool event; + + /* Head of free buffer list. */ + unsigned int free_head; + /* Number we've added since last sync. */ + unsigned int num_added; + + /* Last used index we've seen. */ + u16 last_used_idx; + + /* Hint for event idx: already triggered no need to disable. */ + bool event_triggered; + + union { + /* Available for split ring */ + struct { + /* Actual memory layout for this queue. */ + struct vring vring; + + /* Last written value to avail->flags */ + u16 avail_flags_shadow; + + /* + * Last written value to avail->idx in + * guest byte order. + */ + u16 avail_idx_shadow; + + /* Per-descriptor state. */ + struct vring_desc_state_split *desc_state; + struct vring_desc_extra *desc_extra; + + /* DMA address and size information */ + dma_addr_t queue_dma_addr; + size_t queue_size_in_bytes; + } split; + + /* Available for packed ring */ + struct { + /* Actual memory layout for this queue. */ + struct { + unsigned int num; + struct vring_packed_desc *desc; + struct vring_packed_desc_event *driver; + struct vring_packed_desc_event *device; + } vring; + + /* Driver ring wrap counter. */ + bool avail_wrap_counter; + + /* Device ring wrap counter. */ + bool used_wrap_counter; + + /* Avail used flags. */ + u16 avail_used_flags; + + /* Index of the next avail descriptor. */ + u16 next_avail_idx; + + /* + * Last written value to driver->flags in + * guest byte order. + */ + u16 event_flags_shadow; + + /* Per-descriptor state. */ + struct vring_desc_state_packed *desc_state; + struct vring_desc_extra *desc_extra; + + /* DMA address and size information */ + dma_addr_t ring_dma_addr; + dma_addr_t driver_event_dma_addr; + dma_addr_t device_event_dma_addr; + size_t ring_size_in_bytes; + size_t event_size_in_bytes; + } packed; + }; + + /* How to notify other side. FIXME: commonalize hcalls! */ + bool(*notify) (struct virtqueue * vq); + + /* DMA, allocation, and size information */ + bool we_own_ring; + +#ifdef DEBUG + /* They're supposed to lock for us. */ + unsigned int in_use; + + /* Figure out if their kicks are too delayed. */ + bool last_add_time_valid; + ktime_t last_add_time; +#endif +}; + +#define VQ_NAME_LEN 16 +struct virtio_blk_vq { + struct virtqueue *vq; + spinlock_t lock; + char name[VQ_NAME_LEN]; +} ____cacheline_aligned_in_smp; + +struct virtio_blk { + struct virtio_device *vdev; + + /* The disk structure for the kernel. */ + struct gendisk *disk; + + /* Block layer tags. */ + struct blk_mq_tag_set tag_set; + + /* Process context for config space updates */ + struct work_struct config_work; + + /* What host tells us, plus 2 for header & tailer. */ + unsigned int sg_elems; + + /* Ida index - used to track minor number allocations. */ + int index; + + /* num of vqs */ + int num_vqs; + struct virtio_blk_vq *vqs; +}; + +struct virtblk_req { +#ifdef CONFIG_VIRTIO_BLK_SCSI + struct scsi_request sreq; /* for SCSI passthrough, must be first */ + u8 sense[SCSI_SENSE_BUFFERSIZE]; + struct virtio_scsi_inhdr in_hdr; +#endif + struct virtio_blk_outhdr out_hdr; + u8 status; + struct scatterlist sg[]; +}; +#define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq) + +struct blk_mq_ctxs { + struct kobject kobj; + struct blk_mq_ctx __percpu *queue_ctx; +}; + +struct blk_mq_ctx { + struct { + spinlock_t lock; + struct list_head rq_lists[HCTX_MAX_TYPES]; + } ____cacheline_aligned_in_smp; + + unsigned int cpu; + unsigned short index_hw[HCTX_MAX_TYPES]; + RH_KABI_BROKEN_INSERT(struct blk_mq_hw_ctx *hctxs[HCTX_MAX_TYPES]) + + /* incremented at dispatch time */ + unsigned long rq_dispatched[2]; + unsigned long rq_merged; + + /* incremented at completion time */ + unsigned long ____cacheline_aligned_in_smp rq_completed[2]; + + struct request_queue *queue; + struct blk_mq_ctxs *ctxs; + struct kobject kobj; +} ____cacheline_aligned_in_smp; + +struct blk_flush_queue { + RH_KABI_DEPRECATE(unsigned int, flush_queue_delayed:1) + unsigned int flush_pending_idx:1; + unsigned int flush_running_idx:1; + unsigned long flush_pending_since; + struct list_head flush_queue[2]; + struct list_head flush_data_in_flight; + struct request *flush_rq; + + /* + * flush_rq shares tag with this rq, both can't be active + * at the same time + */ + RH_KABI_DEPRECATE(struct request *, orig_rq) + spinlock_t mq_flush_lock; + RH_KABI_EXTEND(blk_status_t rq_status) + + /* key is obsolete already, just don't know how to mark it */ + RH_KABI_EXTEND(struct lock_class_key key) +}; + +static inline int enable_detect_flush_rq(void) +{ + return 1; +} + +static inline struct blk_mq_hw_ctx *blk_mq_map_queue_type(struct + request_queue *q, + enum hctx_type + type, + unsigned int cpu) +{ + return q->queue_hw_ctx[q->tag_set->map[type].mq_map[cpu]]; +} + +static inline struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue + *q, + unsigned int flags, + struct blk_mq_ctx + *ctx) +{ + enum hctx_type type = HCTX_TYPE_DEFAULT; + + /* + * The caller ensure that if REQ_HIPRI, poll must be enabled. + */ + if (flags & REQ_HIPRI) + type = HCTX_TYPE_POLL; + else if ((flags & REQ_OP_MASK) == REQ_OP_READ) + type = HCTX_TYPE_READ; + + return ctx->hctxs[type]; +} + +static inline struct blk_mq_hw_ctx *blk_mq_get_hctx_byrq(struct request + *rq) +{ + return blk_mq_map_queue(rq->q, rq->cmd_flags, rq->mq_ctx); +} + +static inline struct request *desc_state_data_to_req(struct virtqueue *vq, + int head) +{ + void *data = + (to_vvq(vq)->packed_ring ? to_vvq(vq)->packed.desc_state[head]. + data : to_vvq(vq)->split.desc_state[head].data); + return data ? blk_mq_rq_from_pdu(data) : NULL; +} + +static inline int get_rq_internal_tag(struct request *rq) +{ + return rq ? rq->internal_tag : -1; +} + +static inline unsigned long get_issue_driver_ns(struct request *rq) +{ + if (!rq) + return 0; + if (rq->io_start_time_ns) + return rq->io_start_time_ns; + if (rq->deadline > rq->timeout) + return jiffies_to_usecs(rq->deadline - rq->timeout) * 1000; + return 0; +} + +/* + * LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) + */ +static inline u64 get_check_hang_time_ns(void) +{ + return ktime_get_ns(); +} + +extern fn_queue_tag_busy_iter sym_blk_mq_queue_tag_busy_iter; +typedef void (*blk_mq_rq_iter) (struct request *, void *, bool); +static blk_mq_rq_iter fn_blk_mq_check_hang = NULL; +static bool blk_mq_check_rq_hang(struct blk_mq_hw_ctx *hctx, + struct request *rq, void *priv, + bool reserved) +{ + if (fn_blk_mq_check_hang) + fn_blk_mq_check_hang(rq, priv, reserved); + return true; +} + +static inline int iter_all_rq(struct request_queue *q, blk_mq_rq_iter fn, + void *data) +{ + fn_blk_mq_check_hang = fn; + + sym_blk_mq_queue_tag_busy_iter(q, blk_mq_check_rq_hang, data); + return 0; +} +#endif -- Gitee From a94e829406985387226f5e97dde3b48f0ac6a3c1 Mon Sep 17 00:00:00 2001 From: borunfu Date: Sat, 28 Sep 2024 23:18:11 -0400 Subject: [PATCH 13/16] iosdiag: Add header files for centos 4.18.0-372 Signed-off-by: Borun Fu --- modules/iosdiag/include/4.18.0-372/nvme.h | 63 ++++ .../iosdiag/include/4.18.0-372/virtio_blk.h | 329 ++++++++++++++++++ 2 files changed, 392 insertions(+) create mode 100644 modules/iosdiag/include/4.18.0-372/nvme.h create mode 100644 modules/iosdiag/include/4.18.0-372/virtio_blk.h diff --git a/modules/iosdiag/include/4.18.0-372/nvme.h b/modules/iosdiag/include/4.18.0-372/nvme.h new file mode 100644 index 0000000..3e554d7 --- /dev/null +++ b/modules/iosdiag/include/4.18.0-372/nvme.h @@ -0,0 +1,63 @@ +#ifndef _NVME_H +#define _NVME_H + +#include +#include +#include +#include +#include +#include +#include "iosdiag.h" + +struct nvme_queue { + struct nvme_dev *dev; + spinlock_t sq_lock; + void *sq_cmds; + /* only used for poll queues: */ + spinlock_t cq_poll_lock ____cacheline_aligned_in_smp; + struct nvme_completion *cqes; + dma_addr_t sq_dma_addr; + dma_addr_t cq_dma_addr; + u32 __iomem *q_db; + u32 q_depth; + u16 cq_vector; + u16 sq_tail; + u16 last_sq_tail; + u16 cq_head; + u16 qid; + u8 cq_phase; + u8 sqes; + unsigned long flags; +#define NVMEQ_ENABLED 0 +#define NVMEQ_SQ_CMB 1 +#define NVMEQ_DELETE_ERROR 2 +#define NVMEQ_POLLED 3 + u32 *dbbuf_sq_db; + u32 *dbbuf_cq_db; + u32 *dbbuf_sq_ei; + u32 *dbbuf_cq_ei; + struct completion delete_done; +}; + +static int get_sq_rq_idx(struct nvme_queue *nvmeq, struct request *rq) +{ + int tail = nvmeq->sq_tail; + struct nvme_command cmd; + + do { + if (tail >= nvmeq->q_depth) + break; + memcpy(&cmd, nvmeq->sq_cmds + (tail << nvmeq->sqes), sizeof(cmd)); + if (cmd.common.command_id == rq->tag) + return tail; + } while (--tail >= 0); + return -1; +} + +static unsigned long get_cmd_ctx(struct nvme_queue *nvmeq, + struct request *rq) +{ + //struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + return 0; +} +#endif diff --git a/modules/iosdiag/include/4.18.0-372/virtio_blk.h b/modules/iosdiag/include/4.18.0-372/virtio_blk.h new file mode 100644 index 0000000..836f55c --- /dev/null +++ b/modules/iosdiag/include/4.18.0-372/virtio_blk.h @@ -0,0 +1,329 @@ +#ifndef _VIRTIO_BLK_H +#define _VIRTIO_BLK_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iosdiag.h" + +struct vring_desc_state_split { + void *data; /* Data for callback. */ + struct vring_desc *indir_desc; /* Indirect descriptor, if any. */ +}; + +struct vring_desc_state_packed { + void *data; /* Data for callback. */ + struct vring_packed_desc *indir_desc; /* Indirect descriptor, if any. */ + u16 num; /* Descriptor list length. */ + u16 next; /* The next desc state in a list. */ + u16 last; /* The last desc state in a list. */ +}; + +struct vring_desc_extra { + dma_addr_t addr; /* Descriptor DMA addr. */ + u32 len; /* Descriptor length. */ + u16 flags; /* Descriptor flags. */ +}; + +struct vring_virtqueue { + struct virtqueue vq; + + /* Is this a packed ring? */ + bool packed_ring; + + /* Is DMA API used? */ + bool use_dma_api; + + /* Can we use weak barriers? */ + bool weak_barriers; + + /* Other side has made a mess, don't try any more. */ + bool broken; + + /* Host supports indirect buffers */ + bool indirect; + + /* Host publishes avail event idx */ + bool event; + + /* Head of free buffer list. */ + unsigned int free_head; + /* Number we've added since last sync. */ + unsigned int num_added; + + /* Last used index we've seen. */ + u16 last_used_idx; + + /* Hint for event idx: already triggered no need to disable. */ + bool event_triggered; + + union { + /* Available for split ring */ + struct { + /* Actual memory layout for this queue. */ + struct vring vring; + + /* Last written value to avail->flags */ + u16 avail_flags_shadow; + + /* + * Last written value to avail->idx in + * guest byte order. + */ + u16 avail_idx_shadow; + + /* Per-descriptor state. */ + struct vring_desc_state_split *desc_state; + + /* DMA address and size information */ + dma_addr_t queue_dma_addr; + size_t queue_size_in_bytes; + } split; + + /* Available for packed ring */ + struct { + /* Actual memory layout for this queue. */ + struct { + unsigned int num; + struct vring_packed_desc *desc; + struct vring_packed_desc_event *driver; + struct vring_packed_desc_event *device; + } vring; + + /* Driver ring wrap counter. */ + bool avail_wrap_counter; + + /* Device ring wrap counter. */ + bool used_wrap_counter; + + /* Avail used flags. */ + u16 avail_used_flags; + + /* Index of the next avail descriptor. */ + u16 next_avail_idx; + + /* + * Last written value to driver->flags in + * guest byte order. + */ + u16 event_flags_shadow; + + /* Per-descriptor state. */ + struct vring_desc_state_packed *desc_state; + struct vring_desc_extra_packed *desc_extra; + + /* DMA address and size information */ + dma_addr_t ring_dma_addr; + dma_addr_t driver_event_dma_addr; + dma_addr_t device_event_dma_addr; + size_t ring_size_in_bytes; + size_t event_size_in_bytes; + } packed; + }; + + /* How to notify other side. FIXME: commonalize hcalls! */ + bool(*notify) (struct virtqueue * vq); + + /* DMA, allocation, and size information */ + bool we_own_ring; + +#ifdef DEBUG + /* They're supposed to lock for us. */ + unsigned int in_use; + + /* Figure out if their kicks are too delayed. */ + bool last_add_time_valid; + ktime_t last_add_time; +#endif +}; + +#define VQ_NAME_LEN 16 +struct virtio_blk_vq { + struct virtqueue *vq; + spinlock_t lock; + char name[VQ_NAME_LEN]; +} ____cacheline_aligned_in_smp; + +struct virtio_blk { + struct virtio_device *vdev; + + /* The disk structure for the kernel. */ + struct gendisk *disk; + + /* Block layer tags. */ + struct blk_mq_tag_set tag_set; + + /* Process context for config space updates */ + struct work_struct config_work; + + /* What host tells us, plus 2 for header & tailer. */ + unsigned int sg_elems; + + /* Ida index - used to track minor number allocations. */ + int index; + + /* num of vqs */ + int num_vqs; + struct virtio_blk_vq *vqs; +}; + +struct virtblk_req { +#ifdef CONFIG_VIRTIO_BLK_SCSI + struct scsi_request sreq; /* for SCSI passthrough, must be first */ + u8 sense[SCSI_SENSE_BUFFERSIZE]; + struct virtio_scsi_inhdr in_hdr; +#endif + struct virtio_blk_outhdr out_hdr; + u8 status; + struct scatterlist sg[]; +}; +#define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq) + +struct blk_mq_ctxs { + struct kobject kobj; + struct blk_mq_ctx __percpu *queue_ctx; +}; + +struct blk_mq_ctx { + struct { + spinlock_t lock; + struct list_head rq_lists[HCTX_MAX_TYPES]; + } ____cacheline_aligned_in_smp; + + unsigned int cpu; + unsigned short index_hw[HCTX_MAX_TYPES]; + RH_KABI_BROKEN_INSERT(struct blk_mq_hw_ctx *hctxs[HCTX_MAX_TYPES]) + + /* incremented at dispatch time */ + unsigned long rq_dispatched[2]; + unsigned long rq_merged; + + /* incremented at completion time */ + unsigned long ____cacheline_aligned_in_smp rq_completed[2]; + + struct request_queue *queue; + struct blk_mq_ctxs *ctxs; + struct kobject kobj; +} ____cacheline_aligned_in_smp; + +struct blk_flush_queue { + RH_KABI_DEPRECATE(unsigned int, flush_queue_delayed:1) + unsigned int flush_pending_idx:1; + unsigned int flush_running_idx:1; + unsigned long flush_pending_since; + struct list_head flush_queue[2]; + struct list_head flush_data_in_flight; + struct request *flush_rq; + + /* + * flush_rq shares tag with this rq, both can't be active + * at the same time + */ + RH_KABI_DEPRECATE(struct request *, orig_rq) + spinlock_t mq_flush_lock; + RH_KABI_EXTEND(blk_status_t rq_status) + + /* key is obsolete already, just don't know how to mark it */ + RH_KABI_EXTEND(struct lock_class_key key) +}; + +static inline int enable_detect_flush_rq(void) +{ + return 1; +} + +static inline struct blk_mq_hw_ctx *blk_mq_map_queue_type(struct + request_queue *q, + enum hctx_type + type, + unsigned int cpu) +{ + return q->queue_hw_ctx[q->tag_set->map[type].mq_map[cpu]]; +} + +static inline struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue + *q, + unsigned int flags, + struct blk_mq_ctx + *ctx) +{ + enum hctx_type type = HCTX_TYPE_DEFAULT; + + /* + * The caller ensure that if REQ_HIPRI, poll must be enabled. + */ + if (flags & REQ_HIPRI) + type = HCTX_TYPE_POLL; + else if ((flags & REQ_OP_MASK) == REQ_OP_READ) + type = HCTX_TYPE_READ; + + return ctx->hctxs[type]; +} + +static inline struct blk_mq_hw_ctx *blk_mq_get_hctx_byrq(struct request + *rq) +{ + return blk_mq_map_queue(rq->q, rq->cmd_flags, rq->mq_ctx); +} + +static inline struct request *desc_state_data_to_req(struct virtqueue *vq, + int head) +{ + void *data = + (to_vvq(vq)->packed_ring ? to_vvq(vq)->packed.desc_state[head]. + data : to_vvq(vq)->split.desc_state[head].data); + return data ? blk_mq_rq_from_pdu(data) : NULL; +} + +static inline int get_rq_internal_tag(struct request *rq) +{ + return rq ? rq->internal_tag : -1; +} + +static inline unsigned long get_issue_driver_ns(struct request *rq) +{ + if (!rq) + return 0; + if (rq->io_start_time_ns) + return rq->io_start_time_ns; + if (rq->deadline > rq->timeout) + return jiffies_to_usecs(rq->deadline - rq->timeout) * 1000; + return 0; +} + +/* + * LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) + */ +static inline u64 get_check_hang_time_ns(void) +{ + return ktime_get_ns(); +} + +extern fn_queue_tag_busy_iter sym_blk_mq_queue_tag_busy_iter; +typedef void (*blk_mq_rq_iter) (struct request *, void *, bool); +static blk_mq_rq_iter fn_blk_mq_check_hang = NULL; +static bool blk_mq_check_rq_hang(struct blk_mq_hw_ctx *hctx, + struct request *rq, void *priv, + bool reserved) +{ + if (fn_blk_mq_check_hang) + fn_blk_mq_check_hang(rq, priv, reserved); + return true; +} + +static inline int iter_all_rq(struct request_queue *q, blk_mq_rq_iter fn, + void *data) +{ + fn_blk_mq_check_hang = fn; + + sym_blk_mq_queue_tag_busy_iter(q, blk_mq_check_rq_hang, data); + return 0; +} +#endif -- Gitee From afa4a4c6408d80d494af3dc58c4b709f4136f5a5 Mon Sep 17 00:00:00 2001 From: borunfu Date: Sat, 28 Sep 2024 23:32:49 -0400 Subject: [PATCH 14/16] iosdiag: Add header files for centos 4.18.0-348 Signed-off-by: Borun Fu --- modules/iosdiag/include/4.18.0-348/nvme.h | 63 ++++ .../iosdiag/include/4.18.0-348/virtio_blk.h | 326 ++++++++++++++++++ 2 files changed, 389 insertions(+) create mode 100644 modules/iosdiag/include/4.18.0-348/nvme.h create mode 100644 modules/iosdiag/include/4.18.0-348/virtio_blk.h diff --git a/modules/iosdiag/include/4.18.0-348/nvme.h b/modules/iosdiag/include/4.18.0-348/nvme.h new file mode 100644 index 0000000..3e554d7 --- /dev/null +++ b/modules/iosdiag/include/4.18.0-348/nvme.h @@ -0,0 +1,63 @@ +#ifndef _NVME_H +#define _NVME_H + +#include +#include +#include +#include +#include +#include +#include "iosdiag.h" + +struct nvme_queue { + struct nvme_dev *dev; + spinlock_t sq_lock; + void *sq_cmds; + /* only used for poll queues: */ + spinlock_t cq_poll_lock ____cacheline_aligned_in_smp; + struct nvme_completion *cqes; + dma_addr_t sq_dma_addr; + dma_addr_t cq_dma_addr; + u32 __iomem *q_db; + u32 q_depth; + u16 cq_vector; + u16 sq_tail; + u16 last_sq_tail; + u16 cq_head; + u16 qid; + u8 cq_phase; + u8 sqes; + unsigned long flags; +#define NVMEQ_ENABLED 0 +#define NVMEQ_SQ_CMB 1 +#define NVMEQ_DELETE_ERROR 2 +#define NVMEQ_POLLED 3 + u32 *dbbuf_sq_db; + u32 *dbbuf_cq_db; + u32 *dbbuf_sq_ei; + u32 *dbbuf_cq_ei; + struct completion delete_done; +}; + +static int get_sq_rq_idx(struct nvme_queue *nvmeq, struct request *rq) +{ + int tail = nvmeq->sq_tail; + struct nvme_command cmd; + + do { + if (tail >= nvmeq->q_depth) + break; + memcpy(&cmd, nvmeq->sq_cmds + (tail << nvmeq->sqes), sizeof(cmd)); + if (cmd.common.command_id == rq->tag) + return tail; + } while (--tail >= 0); + return -1; +} + +static unsigned long get_cmd_ctx(struct nvme_queue *nvmeq, + struct request *rq) +{ + //struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + return 0; +} +#endif diff --git a/modules/iosdiag/include/4.18.0-348/virtio_blk.h b/modules/iosdiag/include/4.18.0-348/virtio_blk.h new file mode 100644 index 0000000..015dba0 --- /dev/null +++ b/modules/iosdiag/include/4.18.0-348/virtio_blk.h @@ -0,0 +1,326 @@ +#ifndef _VIRTIO_BLK_H +#define _VIRTIO_BLK_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iosdiag.h" + +struct vring_desc_state_split { + void *data; /* Data for callback. */ + struct vring_desc *indir_desc; /* Indirect descriptor, if any. */ +}; + +struct vring_desc_state_packed { + void *data; /* Data for callback. */ + struct vring_packed_desc *indir_desc; /* Indirect descriptor, if any. */ + u16 num; /* Descriptor list length. */ + u16 next; /* The next desc state in a list. */ + u16 last; /* The last desc state in a list. */ +}; + +struct vring_desc_extra_packed { + dma_addr_t addr; /* Buffer DMA addr. */ + u32 len; /* Buffer length. */ + u16 flags; /* Descriptor flags. */ +}; + +struct vring_virtqueue { + struct virtqueue vq; + + /* Is this a packed ring? */ + bool packed_ring; + + /* Is DMA API used? */ + bool use_dma_api; + + /* Can we use weak barriers? */ + bool weak_barriers; + + /* Other side has made a mess, don't try any more. */ + bool broken; + + /* Host supports indirect buffers */ + bool indirect; + + /* Host publishes avail event idx */ + bool event; + + /* Head of free buffer list. */ + unsigned int free_head; + /* Number we've added since last sync. */ + unsigned int num_added; + + /* Last used index we've seen. */ + u16 last_used_idx; + + union { + /* Available for split ring */ + struct { + /* Actual memory layout for this queue. */ + struct vring vring; + + /* Last written value to avail->flags */ + u16 avail_flags_shadow; + + /* + * Last written value to avail->idx in + * guest byte order. + */ + u16 avail_idx_shadow; + + /* Per-descriptor state. */ + struct vring_desc_state_split *desc_state; + + /* DMA address and size information */ + dma_addr_t queue_dma_addr; + size_t queue_size_in_bytes; + } split; + + /* Available for packed ring */ + struct { + /* Actual memory layout for this queue. */ + struct { + unsigned int num; + struct vring_packed_desc *desc; + struct vring_packed_desc_event *driver; + struct vring_packed_desc_event *device; + } vring; + + /* Driver ring wrap counter. */ + bool avail_wrap_counter; + + /* Device ring wrap counter. */ + bool used_wrap_counter; + + /* Avail used flags. */ + u16 avail_used_flags; + + /* Index of the next avail descriptor. */ + u16 next_avail_idx; + + /* + * Last written value to driver->flags in + * guest byte order. + */ + u16 event_flags_shadow; + + /* Per-descriptor state. */ + struct vring_desc_state_packed *desc_state; + struct vring_desc_extra_packed *desc_extra; + + /* DMA address and size information */ + dma_addr_t ring_dma_addr; + dma_addr_t driver_event_dma_addr; + dma_addr_t device_event_dma_addr; + size_t ring_size_in_bytes; + size_t event_size_in_bytes; + } packed; + }; + + /* How to notify other side. FIXME: commonalize hcalls! */ + bool(*notify) (struct virtqueue * vq); + + /* DMA, allocation, and size information */ + bool we_own_ring; + +#ifdef DEBUG + /* They're supposed to lock for us. */ + unsigned int in_use; + + /* Figure out if their kicks are too delayed. */ + bool last_add_time_valid; + ktime_t last_add_time; +#endif +}; + +#define VQ_NAME_LEN 16 +struct virtio_blk_vq { + struct virtqueue *vq; + spinlock_t lock; + char name[VQ_NAME_LEN]; +} ____cacheline_aligned_in_smp; + +struct virtio_blk { + struct virtio_device *vdev; + + /* The disk structure for the kernel. */ + struct gendisk *disk; + + /* Block layer tags. */ + struct blk_mq_tag_set tag_set; + + /* Process context for config space updates */ + struct work_struct config_work; + + /* What host tells us, plus 2 for header & tailer. */ + unsigned int sg_elems; + + /* Ida index - used to track minor number allocations. */ + int index; + + /* num of vqs */ + int num_vqs; + struct virtio_blk_vq *vqs; +}; + +struct virtblk_req { +#ifdef CONFIG_VIRTIO_BLK_SCSI + struct scsi_request sreq; /* for SCSI passthrough, must be first */ + u8 sense[SCSI_SENSE_BUFFERSIZE]; + struct virtio_scsi_inhdr in_hdr; +#endif + struct virtio_blk_outhdr out_hdr; + u8 status; + struct scatterlist sg[]; +}; +#define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq) + +struct blk_mq_ctxs { + struct kobject kobj; + struct blk_mq_ctx __percpu *queue_ctx; +}; + +struct blk_mq_ctx { + struct { + spinlock_t lock; + struct list_head rq_lists[HCTX_MAX_TYPES]; + } ____cacheline_aligned_in_smp; + + unsigned int cpu; + unsigned short index_hw[HCTX_MAX_TYPES]; + RH_KABI_BROKEN_INSERT(struct blk_mq_hw_ctx *hctxs[HCTX_MAX_TYPES]) + + /* incremented at dispatch time */ + unsigned long rq_dispatched[2]; + unsigned long rq_merged; + + /* incremented at completion time */ + unsigned long ____cacheline_aligned_in_smp rq_completed[2]; + + struct request_queue *queue; + struct blk_mq_ctxs *ctxs; + struct kobject kobj; +} ____cacheline_aligned_in_smp; + +struct blk_flush_queue { + RH_KABI_DEPRECATE(unsigned int, flush_queue_delayed:1) + unsigned int flush_pending_idx:1; + unsigned int flush_running_idx:1; + unsigned long flush_pending_since; + struct list_head flush_queue[2]; + struct list_head flush_data_in_flight; + struct request *flush_rq; + + /* + * flush_rq shares tag with this rq, both can't be active + * at the same time + */ + RH_KABI_DEPRECATE(struct request *, orig_rq) + spinlock_t mq_flush_lock; + RH_KABI_EXTEND(blk_status_t rq_status) + + /* key is obsolete already, just don't know how to mark it */ + RH_KABI_EXTEND(struct lock_class_key key) +}; + +static inline int enable_detect_flush_rq(void) +{ + return 1; +} + +static inline struct blk_mq_hw_ctx *blk_mq_map_queue_type(struct + request_queue *q, + enum hctx_type + type, + unsigned int cpu) +{ + return q->queue_hw_ctx[q->tag_set->map[type].mq_map[cpu]]; +} + +static inline struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue + *q, + unsigned int flags, + struct blk_mq_ctx + *ctx) +{ + enum hctx_type type = HCTX_TYPE_DEFAULT; + + /* + * The caller ensure that if REQ_HIPRI, poll must be enabled. + */ + if (flags & REQ_HIPRI) + type = HCTX_TYPE_POLL; + else if ((flags & REQ_OP_MASK) == REQ_OP_READ) + type = HCTX_TYPE_READ; + + return ctx->hctxs[type]; +} + +static inline struct blk_mq_hw_ctx *blk_mq_get_hctx_byrq(struct request + *rq) +{ + return blk_mq_map_queue(rq->q, rq->cmd_flags, rq->mq_ctx); +} + +static inline struct request *desc_state_data_to_req(struct virtqueue *vq, + int head) +{ + void *data = + (to_vvq(vq)->packed_ring ? to_vvq(vq)->packed.desc_state[head]. + data : to_vvq(vq)->split.desc_state[head].data); + return data ? blk_mq_rq_from_pdu(data) : NULL; +} + +static inline int get_rq_internal_tag(struct request *rq) +{ + return rq ? rq->internal_tag : -1; +} + +static inline unsigned long get_issue_driver_ns(struct request *rq) +{ + if (!rq) + return 0; + if (rq->io_start_time_ns) + return rq->io_start_time_ns; + if (rq->deadline > rq->timeout) + return jiffies_to_usecs(rq->deadline - rq->timeout) * 1000; + return 0; +} + +/* + * LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) + */ +static inline u64 get_check_hang_time_ns(void) +{ + return ktime_get_ns(); +} + +extern fn_queue_tag_busy_iter sym_blk_mq_queue_tag_busy_iter; +typedef void (*blk_mq_rq_iter) (struct request *, void *, bool); +static blk_mq_rq_iter fn_blk_mq_check_hang = NULL; +static bool blk_mq_check_rq_hang(struct blk_mq_hw_ctx *hctx, + struct request *rq, void *priv, + bool reserved) +{ + if (fn_blk_mq_check_hang) + fn_blk_mq_check_hang(rq, priv, reserved); + return true; +} + +static inline int iter_all_rq(struct request_queue *q, blk_mq_rq_iter fn, + void *data) +{ + fn_blk_mq_check_hang = fn; + + sym_blk_mq_queue_tag_busy_iter(q, blk_mq_check_rq_hang, data); + return 0; +} +#endif -- Gitee From ef6398c4b87f1cc30f416dcac62099db20699331 Mon Sep 17 00:00:00 2001 From: borunfu Date: Sat, 28 Sep 2024 23:44:31 -0400 Subject: [PATCH 15/16] iosdiag: Add header files for centos 4.18.0-305 Signed-off-by: Borun Fu --- modules/iosdiag/include/4.18.0-305/nvme.h | 63 ++++ .../iosdiag/include/4.18.0-305/virtio_blk.h | 326 ++++++++++++++++++ 2 files changed, 389 insertions(+) create mode 100644 modules/iosdiag/include/4.18.0-305/nvme.h create mode 100644 modules/iosdiag/include/4.18.0-305/virtio_blk.h diff --git a/modules/iosdiag/include/4.18.0-305/nvme.h b/modules/iosdiag/include/4.18.0-305/nvme.h new file mode 100644 index 0000000..3e554d7 --- /dev/null +++ b/modules/iosdiag/include/4.18.0-305/nvme.h @@ -0,0 +1,63 @@ +#ifndef _NVME_H +#define _NVME_H + +#include +#include +#include +#include +#include +#include +#include "iosdiag.h" + +struct nvme_queue { + struct nvme_dev *dev; + spinlock_t sq_lock; + void *sq_cmds; + /* only used for poll queues: */ + spinlock_t cq_poll_lock ____cacheline_aligned_in_smp; + struct nvme_completion *cqes; + dma_addr_t sq_dma_addr; + dma_addr_t cq_dma_addr; + u32 __iomem *q_db; + u32 q_depth; + u16 cq_vector; + u16 sq_tail; + u16 last_sq_tail; + u16 cq_head; + u16 qid; + u8 cq_phase; + u8 sqes; + unsigned long flags; +#define NVMEQ_ENABLED 0 +#define NVMEQ_SQ_CMB 1 +#define NVMEQ_DELETE_ERROR 2 +#define NVMEQ_POLLED 3 + u32 *dbbuf_sq_db; + u32 *dbbuf_cq_db; + u32 *dbbuf_sq_ei; + u32 *dbbuf_cq_ei; + struct completion delete_done; +}; + +static int get_sq_rq_idx(struct nvme_queue *nvmeq, struct request *rq) +{ + int tail = nvmeq->sq_tail; + struct nvme_command cmd; + + do { + if (tail >= nvmeq->q_depth) + break; + memcpy(&cmd, nvmeq->sq_cmds + (tail << nvmeq->sqes), sizeof(cmd)); + if (cmd.common.command_id == rq->tag) + return tail; + } while (--tail >= 0); + return -1; +} + +static unsigned long get_cmd_ctx(struct nvme_queue *nvmeq, + struct request *rq) +{ + //struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + return 0; +} +#endif diff --git a/modules/iosdiag/include/4.18.0-305/virtio_blk.h b/modules/iosdiag/include/4.18.0-305/virtio_blk.h new file mode 100644 index 0000000..015dba0 --- /dev/null +++ b/modules/iosdiag/include/4.18.0-305/virtio_blk.h @@ -0,0 +1,326 @@ +#ifndef _VIRTIO_BLK_H +#define _VIRTIO_BLK_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iosdiag.h" + +struct vring_desc_state_split { + void *data; /* Data for callback. */ + struct vring_desc *indir_desc; /* Indirect descriptor, if any. */ +}; + +struct vring_desc_state_packed { + void *data; /* Data for callback. */ + struct vring_packed_desc *indir_desc; /* Indirect descriptor, if any. */ + u16 num; /* Descriptor list length. */ + u16 next; /* The next desc state in a list. */ + u16 last; /* The last desc state in a list. */ +}; + +struct vring_desc_extra_packed { + dma_addr_t addr; /* Buffer DMA addr. */ + u32 len; /* Buffer length. */ + u16 flags; /* Descriptor flags. */ +}; + +struct vring_virtqueue { + struct virtqueue vq; + + /* Is this a packed ring? */ + bool packed_ring; + + /* Is DMA API used? */ + bool use_dma_api; + + /* Can we use weak barriers? */ + bool weak_barriers; + + /* Other side has made a mess, don't try any more. */ + bool broken; + + /* Host supports indirect buffers */ + bool indirect; + + /* Host publishes avail event idx */ + bool event; + + /* Head of free buffer list. */ + unsigned int free_head; + /* Number we've added since last sync. */ + unsigned int num_added; + + /* Last used index we've seen. */ + u16 last_used_idx; + + union { + /* Available for split ring */ + struct { + /* Actual memory layout for this queue. */ + struct vring vring; + + /* Last written value to avail->flags */ + u16 avail_flags_shadow; + + /* + * Last written value to avail->idx in + * guest byte order. + */ + u16 avail_idx_shadow; + + /* Per-descriptor state. */ + struct vring_desc_state_split *desc_state; + + /* DMA address and size information */ + dma_addr_t queue_dma_addr; + size_t queue_size_in_bytes; + } split; + + /* Available for packed ring */ + struct { + /* Actual memory layout for this queue. */ + struct { + unsigned int num; + struct vring_packed_desc *desc; + struct vring_packed_desc_event *driver; + struct vring_packed_desc_event *device; + } vring; + + /* Driver ring wrap counter. */ + bool avail_wrap_counter; + + /* Device ring wrap counter. */ + bool used_wrap_counter; + + /* Avail used flags. */ + u16 avail_used_flags; + + /* Index of the next avail descriptor. */ + u16 next_avail_idx; + + /* + * Last written value to driver->flags in + * guest byte order. + */ + u16 event_flags_shadow; + + /* Per-descriptor state. */ + struct vring_desc_state_packed *desc_state; + struct vring_desc_extra_packed *desc_extra; + + /* DMA address and size information */ + dma_addr_t ring_dma_addr; + dma_addr_t driver_event_dma_addr; + dma_addr_t device_event_dma_addr; + size_t ring_size_in_bytes; + size_t event_size_in_bytes; + } packed; + }; + + /* How to notify other side. FIXME: commonalize hcalls! */ + bool(*notify) (struct virtqueue * vq); + + /* DMA, allocation, and size information */ + bool we_own_ring; + +#ifdef DEBUG + /* They're supposed to lock for us. */ + unsigned int in_use; + + /* Figure out if their kicks are too delayed. */ + bool last_add_time_valid; + ktime_t last_add_time; +#endif +}; + +#define VQ_NAME_LEN 16 +struct virtio_blk_vq { + struct virtqueue *vq; + spinlock_t lock; + char name[VQ_NAME_LEN]; +} ____cacheline_aligned_in_smp; + +struct virtio_blk { + struct virtio_device *vdev; + + /* The disk structure for the kernel. */ + struct gendisk *disk; + + /* Block layer tags. */ + struct blk_mq_tag_set tag_set; + + /* Process context for config space updates */ + struct work_struct config_work; + + /* What host tells us, plus 2 for header & tailer. */ + unsigned int sg_elems; + + /* Ida index - used to track minor number allocations. */ + int index; + + /* num of vqs */ + int num_vqs; + struct virtio_blk_vq *vqs; +}; + +struct virtblk_req { +#ifdef CONFIG_VIRTIO_BLK_SCSI + struct scsi_request sreq; /* for SCSI passthrough, must be first */ + u8 sense[SCSI_SENSE_BUFFERSIZE]; + struct virtio_scsi_inhdr in_hdr; +#endif + struct virtio_blk_outhdr out_hdr; + u8 status; + struct scatterlist sg[]; +}; +#define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq) + +struct blk_mq_ctxs { + struct kobject kobj; + struct blk_mq_ctx __percpu *queue_ctx; +}; + +struct blk_mq_ctx { + struct { + spinlock_t lock; + struct list_head rq_lists[HCTX_MAX_TYPES]; + } ____cacheline_aligned_in_smp; + + unsigned int cpu; + unsigned short index_hw[HCTX_MAX_TYPES]; + RH_KABI_BROKEN_INSERT(struct blk_mq_hw_ctx *hctxs[HCTX_MAX_TYPES]) + + /* incremented at dispatch time */ + unsigned long rq_dispatched[2]; + unsigned long rq_merged; + + /* incremented at completion time */ + unsigned long ____cacheline_aligned_in_smp rq_completed[2]; + + struct request_queue *queue; + struct blk_mq_ctxs *ctxs; + struct kobject kobj; +} ____cacheline_aligned_in_smp; + +struct blk_flush_queue { + RH_KABI_DEPRECATE(unsigned int, flush_queue_delayed:1) + unsigned int flush_pending_idx:1; + unsigned int flush_running_idx:1; + unsigned long flush_pending_since; + struct list_head flush_queue[2]; + struct list_head flush_data_in_flight; + struct request *flush_rq; + + /* + * flush_rq shares tag with this rq, both can't be active + * at the same time + */ + RH_KABI_DEPRECATE(struct request *, orig_rq) + spinlock_t mq_flush_lock; + RH_KABI_EXTEND(blk_status_t rq_status) + + /* key is obsolete already, just don't know how to mark it */ + RH_KABI_EXTEND(struct lock_class_key key) +}; + +static inline int enable_detect_flush_rq(void) +{ + return 1; +} + +static inline struct blk_mq_hw_ctx *blk_mq_map_queue_type(struct + request_queue *q, + enum hctx_type + type, + unsigned int cpu) +{ + return q->queue_hw_ctx[q->tag_set->map[type].mq_map[cpu]]; +} + +static inline struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue + *q, + unsigned int flags, + struct blk_mq_ctx + *ctx) +{ + enum hctx_type type = HCTX_TYPE_DEFAULT; + + /* + * The caller ensure that if REQ_HIPRI, poll must be enabled. + */ + if (flags & REQ_HIPRI) + type = HCTX_TYPE_POLL; + else if ((flags & REQ_OP_MASK) == REQ_OP_READ) + type = HCTX_TYPE_READ; + + return ctx->hctxs[type]; +} + +static inline struct blk_mq_hw_ctx *blk_mq_get_hctx_byrq(struct request + *rq) +{ + return blk_mq_map_queue(rq->q, rq->cmd_flags, rq->mq_ctx); +} + +static inline struct request *desc_state_data_to_req(struct virtqueue *vq, + int head) +{ + void *data = + (to_vvq(vq)->packed_ring ? to_vvq(vq)->packed.desc_state[head]. + data : to_vvq(vq)->split.desc_state[head].data); + return data ? blk_mq_rq_from_pdu(data) : NULL; +} + +static inline int get_rq_internal_tag(struct request *rq) +{ + return rq ? rq->internal_tag : -1; +} + +static inline unsigned long get_issue_driver_ns(struct request *rq) +{ + if (!rq) + return 0; + if (rq->io_start_time_ns) + return rq->io_start_time_ns; + if (rq->deadline > rq->timeout) + return jiffies_to_usecs(rq->deadline - rq->timeout) * 1000; + return 0; +} + +/* + * LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) + */ +static inline u64 get_check_hang_time_ns(void) +{ + return ktime_get_ns(); +} + +extern fn_queue_tag_busy_iter sym_blk_mq_queue_tag_busy_iter; +typedef void (*blk_mq_rq_iter) (struct request *, void *, bool); +static blk_mq_rq_iter fn_blk_mq_check_hang = NULL; +static bool blk_mq_check_rq_hang(struct blk_mq_hw_ctx *hctx, + struct request *rq, void *priv, + bool reserved) +{ + if (fn_blk_mq_check_hang) + fn_blk_mq_check_hang(rq, priv, reserved); + return true; +} + +static inline int iter_all_rq(struct request_queue *q, blk_mq_rq_iter fn, + void *data) +{ + fn_blk_mq_check_hang = fn; + + sym_blk_mq_queue_tag_busy_iter(q, blk_mq_check_rq_hang, data); + return 0; +} +#endif -- Gitee From e0dc6ed037256ec22e240675bd41b939027b8391 Mon Sep 17 00:00:00 2001 From: Borun Fu Date: Mon, 23 Sep 2024 06:33:27 -0400 Subject: [PATCH 16/16] iosdiag: Adapt to centos kernel 4.18.0 Signed-off-by: Borun Fu --- modules/iosdiag/iosdiag.c | 10 ++++++++++ modules/iosdiag/rq_hang.c | 4 ++++ modules/iosdiag/scsi.c | 4 ++++ modules/iosdiag/virtio_blk.c | 2 +- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/iosdiag/iosdiag.c b/modules/iosdiag/iosdiag.c index 5b42a5b..774c162 100644 --- a/modules/iosdiag/iosdiag.c +++ b/modules/iosdiag/iosdiag.c @@ -184,10 +184,18 @@ static int sq_check_rq_hang(struct request_queue *q, int rq_hang_threshold) struct request *rq, *tmp; LIST_HEAD(rq_list); int rq_store_idx = 0; +#if LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) + spinlock_t *queue_lock = &q->queue_lock; +#else spinlock_t *queue_lock = q->queue_lock; +#endif spin_lock_irqsave(queue_lock, flags); +#if LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) + list_for_each_entry_safe(rq, tmp, &q->requeue_list, queuelist) { +#else list_for_each_entry_safe(rq, tmp, &q->queue_head, queuelist) { +#endif duration = div_u64(now - rq->start_time_ns, NSEC_PER_MSEC); if (duration >= rq_hang_threshold && rq_store_idx < MAX_STORE_RQ_CNT) { g_rq_store[rq_store_idx].rq = rq; @@ -199,6 +207,7 @@ static int sq_check_rq_hang(struct request_queue *q, int rq_hang_threshold) } spin_unlock_irqrestore(queue_lock, flags); +#if LINUX_VERSION_CODE != KERNEL_VERSION(4, 18, 0) spin_lock_irqsave(queue_lock, flags); list_for_each_entry_safe(rq, tmp, &q->timeout_list, timeout_list) { duration = div_u64(now - rq->start_time_ns, NSEC_PER_MSEC); @@ -211,6 +220,7 @@ static int sq_check_rq_hang(struct request_queue *q, int rq_hang_threshold) continue; } spin_unlock_irqrestore(queue_lock, flags); +#endif while(!list_empty(&rq_list)) { struct rq_store *rqs; rqs = list_first_entry(&rq_list, struct rq_store, list); diff --git a/modules/iosdiag/rq_hang.c b/modules/iosdiag/rq_hang.c index 12a22cf..07b0bbe 100644 --- a/modules/iosdiag/rq_hang.c +++ b/modules/iosdiag/rq_hang.c @@ -312,7 +312,11 @@ static void get_rq_info(struct rq_hang_info *rq_hi, struct request *rq) rq_hi->cpu = rq->mq_ctx->cpu; #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0) else +#if LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) + pr_err("%s failed to get request cpuid\n", __func__); +#else rq_hi->cpu = rq->cpu; +#endif #endif rq_hi->io_start_ns = rq->start_time_ns; rq_hi->io_issue_driver_ns = get_issue_driver_ns(rq); diff --git a/modules/iosdiag/scsi.c b/modules/iosdiag/scsi.c index d9288b8..d775595 100644 --- a/modules/iosdiag/scsi.c +++ b/modules/iosdiag/scsi.c @@ -22,7 +22,11 @@ void get_scsi_info(struct scsi_info *scsi_i, struct request *rq) } #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0) else +#if LINUX_VERSION_CODE == KERNEL_VERSION(4, 18, 0) + pr_err("%s failed to get request cmd\n", __func__); +#else cmd = rq->special; +#endif #endif if (!cmd) diff --git a/modules/iosdiag/virtio_blk.c b/modules/iosdiag/virtio_blk.c index 9b85661..88b7c4a 100644 --- a/modules/iosdiag/virtio_blk.c +++ b/modules/iosdiag/virtio_blk.c @@ -12,7 +12,7 @@ static struct vring *get_vring_by_vq(struct virtqueue *vq) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0) return &to_vvq(vq)->vring; #else if (to_vvq(vq)->packed_ring) -- Gitee