crash查看percpu变量在每个cpu上的基地址和内容

查看percpu变量在每个cpu上的基地址 

crash> kmem -o
PER-CPU OFFSET VALUES:
  CPU 0: ffff88807f600000
  CPU 1: ffff88807fa00000
  CPU 2: ffff88813d600000
  CPU 3: ffff88813da00000
  CPU 4: ffff8881bd600000
  CPU 5: ffff8881bda00000
  CPU 6: ffff88823d600000
  CPU 7: ffff88823da00000

查看一个全局的percpu变量的具体值

查看call_single_queue在每个cpu上的地址: 



static DEFINE_PER_CPU_SHARED_ALIGNED(struct llist_head, call_single_queue);

查看这个percpu变量在每个cpu上的地址

crash> p call_single_queue
PER-CPU DATA TYPE:
  struct llist_head call_single_queue;
PER-CPU ADDRESSES:
  [0]: ffff0102ffddb740
  [1]: ffff0102ffdfe740
  [2]: ffff0102ffe21740
  [3]: ffff0102ffe44740
  [4]: ffff0102ffe67740
  [5]: ffff0102ffe8a740
  [6]: ffff0102ffead740
  [7]: ffff0102ffed0740
  [8]: ffff0102ffef3740
  [9]: ffff0102fff16740
  [10]: ffff0102fff39740
  [11]: ffff0102fff5c740
....

查看某个地址上对应结构体的内容用struct命令:

NAME
  struct - structure contents

SYNOPSIS
  struct struct_name[.member[,member]][-o][-l offset][-rfuxdp]
         [address | symbol][:cpuspec] [count | -c count

例如:struct 结构体名 地址:#percpu 读取第#percpu个 percpu 的内容

或者*指令:

crash> help *

NAME
  * - pointer-to short-cut

SYNOPSIS
  * (struct or union command arguments)

DESCRIPTION
  This command is a short-cut command that replaces the requirement to enter
  "struct" or "union" command names.  For details on the arguments to
  those commands, enter "help struct" or "help union".

EXAMPLES
  Dump the page structure at address c02943c0:
 
    crash> *page c02943c0
    struct page {
      next = 0xc0fae740, 
      prev = 0xc0018fb0, 
      inode = 0x0, 
      offset = 0x3f000, 
      next_hash = 0xc02d6310, 
      count = {
        counter = 0x1
      }, 
      flags = 0x310, 
      wait = 0xc02943d8, 
      pprev_hash = 0x0, 
      buffers = 0x0
    }

crash> struct llist_head 0xffff0102ffddb740
struct llist_head {
  first = 0xffff0102ffde1a80
}

或者:
crash> *llist_head 0xffff0102ffddb740
struct llist_head {
  first = 0xffff0102ffde1a80
}

查看某个,或某几个cpu的内容:

crash> p call_single_queue:0,1,2
per_cpu(call_single_queue, 0) = $12 = {
  first = 0xffff0102ffde1a80
}
per_cpu(call_single_queue, 1) = $13 = {
  first = 0x0
}
per_cpu(call_single_queue, 2) = $14 = {
  first = 0x0
}

读取percpu变量的内容

有如下结构体和per cpu变量cfd_data:

struct call_function_data {
	call_single_data_t	__percpu *csd;
	cpumask_var_t		cpumask;
	cpumask_var_t		cpumask_ipi;
};

static DEFINE_PER_CPU_ALIGNED(struct call_function_data, cfd_data);

需要读取31号cpu的cfd_data,中的csd中的第0号cpu的内容。

首先需要获取31号cpu的cfd_data的内容:

crash> p cfd_data:31
per_cpu(cfd_data, 31) = $15 = {
  csd = 0xffff80001180fa80,
  cpumask = {{
      bits = {18446744071562067967, 18446744073709551615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    }},
  cpumask_ipi = {{
      bits = {18446744071562067966, 18446744073709551615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    }}
}

在读取csd = 0xffff80001180fa80 变量下第0号cpu具体内容:

crash> struct call_single_data_t 0xffff80001180fa80:0
[0]: ffff0102ffde1a80
struct call_single_data_t {
  node = {
    llist = {
      next = 0xffff00ff8a973a08
    },
    {
      u_flags = 17,
      a_flags = {
        counter = 17
      }
    },
    src = 0,
    dst = 0
  },
  func = 0xffff8000103500d0 <tlb_remove_table_smp_sync>,
  info = 0x0
}

或者:
crash> *call_single_data_t 0xffff80001180fa80:0

crash工具学习 —— percpu相关的一些用法 - 摩斯电码 - 博客园 (cnblogs.com)

crash、kdump工具学习 - 摩斯电码 - 博客园 (cnblogs.com)

p和struct的区别

p  #SYMBOL变量
默认打变量/符号的内容,如果是结构体也会打印所有结构体的内容,如果是percpu 则打印percpu所有的地址

p #SYMBOL:#N
打印percpu 对应N的内容,如果是a则打印所有的。


struct struct_name[.member[,member]]  [address | symbol][:cpuspec]
 打印结构体struct_name的内容,或者某个,某些成员。 需要提供地址address或者变量符号名symbol。
 如果对应的地址或变量是percpu的,需要提供:cpuspec索引cpu,如果是a则全部。
 
 例如:
 crash> p cfd_data:0
per_cpu(cfd_data, 0) = $6 = {
  csd = 0xffff80001180d100,  //cfd是percpu
  cpumask = {{
      bits = {18446744073709551614, 18446744073709551615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    }},
  cpumask_ipi = {{
      bits = {18446744073709551614, 18446744073709551615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    }}
}
crash> struct call_single_data_t 0xffff80001180d100    //直接显示percpu将出错,需要提供cpuspec
struct call_single_data_t struct: page excluded: kernel virtual address: ffff80001180d100  type: "gdb_readmem_callback"

crash> struct call_single_data_t 0xffff80001180d100:0
[0]: ffff0102ffddf100
struct call_single_data_t {
  node = {
    llist = {
      next = 0x0
    },
    {
      u_flags = 0,
      a_flags = {
        counter = 0
      }
    },
    src = 0,
    dst = 0
  },
  func = 0x0,
  info = 0x0
}

struct 可以达到部分p的功能。 

struct 可以达到部分p的功能。
如果需要显示对应变量,地址为结构体:
crash> struct call_function_data cfd_data:0
[0]: ffff0102ffddb780
struct call_function_data {
  csd = 0xffff80001180d100,
  cpumask = {{
      bits = {18446744073709551614, 18446744073709551615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    }},
  cpumask_ipi = {{
      bits = {18446744073709551614, 18446744073709551615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    }}
}

*号命令。可以实现p或struct功能

*号命令。可以实现p或struct功能

crash> *call_function_data cfd_data:0
[0]: ffff0102ffddb780
struct call_function_data {
  csd = 0xffff80001180d100,
  cpumask = {{
      bits = {18446744073709551614, 18446744073709551615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    }},
  cpumask_ipi = {{
      bits = {18446744073709551614, 18446744073709551615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    }}
}

  • 19
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

古井无波 2024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值