Extract content of RPM package

This command has been included in the navi so you can use it directly.

rpm2cpio <rpm_file> | cpio -idmv

__must_check

__must_check 函数是指调用函数一定要处理该函数的返回值,否则编译器会给出警告。

Identity Paging / Identity Mapped Paging / 1:1 Paging

这三个术语是一样的。

A design choice where a portion of virtual addresses are mapped to physical addresses that have the same value.

This means that if paging is enabled with identity paging, 0xb8000 is 0xb8000.

vm_mmap() / vm_mmap_pgoff() Kernel

在 kernel 代码里调用 mmap

unsigned long vm_mmap(struct file *file, unsigned long addr,
	unsigned long len, unsigned long prot,
	unsigned long flag, unsigned long offset)
{
    // sanity checks...
	return vm_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
}

mmap 这个 syscall 的定义:

SYSCALL_DEFINE6(mmap)
    ksys_mmap_pgoff
        vm_mmap_pgoff

lockdep_assert_held_write() / Kernel

#define lockdep_assert_held_write(l)	\
	lockdep_assert(lockdep_is_held_type(l, 0))

try_cmpxchg64() Kernel

三个参数:

try_cmpxchg64(sptep, &old_spte, new_spte)

如果 ptr 值和 old_spte 相等, 则将 new 赋值给 ptr 且返回 old , 否则仅仅返回 ptr 指向的内容。

Fix another disk's boot partition grub

umount /dev/sdb1 # umount <current efi partition dev>
umount /dev/sdb2 # umount <current BOOT partition dev>
mount /dev/sdc2 /boot # mount another BOOT partition
mount /dev/sdc1 /boot/efi # mount another efi partition

Install fish shell on CS8/CS9

// On CS8
cd /etc/yum.repos.d/
sudo wget https://download.opensuse.org/repositories/shells:fish:release:3/CentOS_8/shells:fish:release:3.repo
sudo yum install fish

// On CS9
sudo dnf config-manager --add-repo https://download.opensuse.org/repositories/shells:/fish:/release:/3/CentOS-9_Stream/shells:fish:release:3.repo
sudo dnf install fish

Git show commit date

git show -s --format=%ci <commit id>

kvm_write_guest_cached() / kvm_write_guest_offset_cached() KVM

int kvm_write_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
				  void *data, unsigned int offset,
				  unsigned long len)
{
	struct kvm_memslots *slots = kvm_memslots(kvm);
	int r;
	gpa_t gpa = ghc->gpa + offset;

    // error checking..
	if (slots->generation != ghc->generation) {
		if (__kvm_gfn_to_hva_cache_init(slots, ghc, ghc->gpa, ghc->len))
			return -EFAULT;
	}

	if (kvm_is_error_hva(ghc->hva))
		return -EFAULT;

	if (unlikely(!ghc->memslot))
		return kvm_write_guest(kvm, gpa, data, len);

	r = __copy_to_user((void __user *)ghc->hva + offset, data, len);
	if (r)
		return -EFAULT;
	mark_page_dirty_in_slot(kvm, ghc->memslot, gpa >> PAGE_SHIFT);

	return 0;
}

int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
			   void *data, unsigned long len)
{
	return kvm_write_guest_offset_cached(kvm, ghc, data, 0, len);
}

kzalloc() Kernel

一言以蔽之,kcalloc() 的简化版本。

kzalloc() [LWN.net]

Detect kernel memory leak / kmemleak

If you encounter:

echo scan > /sys/kernel/debug/kmemleak
write: Operation not permitted

Check DEBUG_KMEMLEAK_DEFAULT_OFF in .config, unset it.

还有一种情况是 poll size 太小了,你可以在 dmesg 里看到:

kmemleak: Memory pool empty, consider increasing CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE
kmemleak: Kernel memory leak detector disabled

这个时候需要改 CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE,调大一点。注意别改太大,160000 就行,太大了会被 make menuconfig 改回默认的值。

使用很简单,跑完程序之后,直接执行:

echo scan > /sys/kernel/debug/kmemleak

会把当前所有可能的 memory leak 输出到 /sys/kernel/debug/kmemleak

如果要清除,那么:

# 这会把之前判定为 leak 的信息标记为 clear
echo clear > /sys/kernel/debug/kmemleak

Init 0 / shutdown the system

struct RamDiscardManager QEMU

commit: 8947d7fc4e77d36fae44411b1b63c513863f89a7: memory: Introduce RamDiscardManager for RAM memory regions

virtio-mem 相关的?

See a process's opened fd

/proc/<pid>/fd/

-mem-prealloc QEMU

因为对于 zero page 都是 COW 的策略,这样可以节省物理内存(zero page^)。如果指定了这个选项,那么

struct HostMemoryBackend {
    //...
    bool prealloc, is_mapped, share, reserve;
    //...
};

host_memory_backend_memory_complete
    if (backend->prealloc) {
        qemu_prealloc_mem()
            // 具体是怎么 touch 的还没有仔细看
            touch_all_pages
    //....

Linux kernel trace point

Using the Linux Kernel Tracepoints — The Linux Kernel documentation

trace_kvm_tdp_mmu_spte_changed(as_id, gfn, level, old_spte, new_spte);

KVM trace points

可以看到所有可用的 events 和 filter functions。

sudo cat /sys/kernel/debug/tracing/available_events | grep kvm:
sudo cat /sys/kernel/debug/tracing/available_filter_functions | grep -i kvm

如何使用?

yum install trace-cmd
# This command will generate a trace.dat
sudo trace-cmd record -e kvm_tdp_mmu_spte_changed -e <trace2> -e <trace3> # event name
# This command will check the exsitence of trace.dat and parse it
sudo trace-cmd report

How to clear a last report:

rm trace.dat

Notes about KVM trace - L