mirror of
https://github.com/eunomia-bpf/bpf-developer-tutorial.git
synced 2026-02-04 02:34:16 +08:00
113 lines
3.2 KiB
C
113 lines
3.2 KiB
C
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
|
/* Copyright (c) 2021 Hengqi Chen */
|
|
|
|
#ifndef __CORE_FIXES_BPF_H
|
|
#define __CORE_FIXES_BPF_H
|
|
|
|
#include <vmlinux.h>
|
|
#include <bpf/bpf_core_read.h>
|
|
|
|
/**
|
|
* commit 2f064a59a1 ("sched: Change task_struct::state") changes
|
|
* the name of task_struct::state to task_struct::__state
|
|
* see:
|
|
* https://github.com/torvalds/linux/commit/2f064a59a1
|
|
*/
|
|
struct task_struct___o {
|
|
volatile long int state;
|
|
} __attribute__((preserve_access_index));
|
|
|
|
struct task_struct___x {
|
|
unsigned int __state;
|
|
} __attribute__((preserve_access_index));
|
|
|
|
static __always_inline __s64 get_task_state(void *task)
|
|
{
|
|
struct task_struct___x *t = task;
|
|
|
|
if (bpf_core_field_exists(t->__state))
|
|
return BPF_CORE_READ(t, __state);
|
|
return BPF_CORE_READ((struct task_struct___o *)task, state);
|
|
}
|
|
|
|
/**
|
|
* commit 309dca309fc3 ("block: store a block_device pointer in struct bio")
|
|
* adds a new member bi_bdev which is a pointer to struct block_device
|
|
* see:
|
|
* https://github.com/torvalds/linux/commit/309dca309fc3
|
|
*/
|
|
struct bio___o {
|
|
struct gendisk *bi_disk;
|
|
} __attribute__((preserve_access_index));
|
|
|
|
struct bio___x {
|
|
struct block_device *bi_bdev;
|
|
} __attribute__((preserve_access_index));
|
|
|
|
static __always_inline struct gendisk *get_gendisk(void *bio)
|
|
{
|
|
struct bio___x *b = bio;
|
|
|
|
if (bpf_core_field_exists(b->bi_bdev))
|
|
return BPF_CORE_READ(b, bi_bdev, bd_disk);
|
|
return BPF_CORE_READ((struct bio___o *)bio, bi_disk);
|
|
}
|
|
|
|
/**
|
|
* commit d5869fdc189f ("block: introduce block_rq_error tracepoint")
|
|
* adds a new tracepoint block_rq_error and it shares the same arguments
|
|
* with tracepoint block_rq_complete. As a result, the kernel BTF now has
|
|
* a `struct trace_event_raw_block_rq_completion` instead of
|
|
* `struct trace_event_raw_block_rq_complete`.
|
|
* see:
|
|
* https://github.com/torvalds/linux/commit/d5869fdc189f
|
|
*/
|
|
struct trace_event_raw_block_rq_complete___x {
|
|
dev_t dev;
|
|
sector_t sector;
|
|
unsigned int nr_sector;
|
|
} __attribute__((preserve_access_index));
|
|
|
|
struct trace_event_raw_block_rq_completion___x {
|
|
dev_t dev;
|
|
sector_t sector;
|
|
unsigned int nr_sector;
|
|
} __attribute__((preserve_access_index));
|
|
|
|
static __always_inline bool has_block_rq_completion()
|
|
{
|
|
if (bpf_core_type_exists(struct trace_event_raw_block_rq_completion___x))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* commit d152c682f03c ("block: add an explicit ->disk backpointer to the
|
|
* request_queue") and commit f3fa33acca9f ("block: remove the ->rq_disk
|
|
* field in struct request") make some changes to `struct request` and
|
|
* `struct request_queue`. Now, to get the `struct gendisk *` field in a CO-RE
|
|
* way, we need both `struct request` and `struct request_queue`.
|
|
* see:
|
|
* https://github.com/torvalds/linux/commit/d152c682f03c
|
|
* https://github.com/torvalds/linux/commit/f3fa33acca9f
|
|
*/
|
|
struct request_queue___x {
|
|
struct gendisk *disk;
|
|
} __attribute__((preserve_access_index));
|
|
|
|
struct request___x {
|
|
struct request_queue___x *q;
|
|
struct gendisk *rq_disk;
|
|
} __attribute__((preserve_access_index));
|
|
|
|
static __always_inline struct gendisk *get_disk(void *request)
|
|
{
|
|
struct request___x *r = request;
|
|
|
|
if (bpf_core_field_exists(r->rq_disk))
|
|
return BPF_CORE_READ(r, rq_disk);
|
|
return BPF_CORE_READ(r, q, disk);
|
|
}
|
|
|
|
#endif /* __CORE_FIXES_BPF_H */
|