On 2/15/19 3:31 AM, Arnaldo Carvalho de Melo wrote:
Em Fri, Feb 15, 2019 at 02:37:04AM +0900, Taeung Song escreveu:
Hi Arnaldo,
I found two duplicate function prototypes 'wq_calc_node_cpumask' using
pfunct.
Is this a bug ?
$ pfunct -P /home/taeung/git/linux/kernel/workqueue.o | grep
wq_calc_node_cpumask
void wq_calc_node_cpumask(const struct workqueue_attrs * attrs, int node,
int cpu_going_down, cpumask_t * cpumask);
bool wq_calc_node_cpumask(const struct workqueue_attrs * attrs, int node,
int cpu_going_down, cpumask_t * cpumask);
So, I checked it like below:
$ readelf -s ~/git/linux/vmlinux | grep wq_calc_node_cpumask
5887: ffffffff810815e0 143 FUNC LOCAL DEFAULT 1
wq_calc_node_cpumask
$ addr2line -e ~/git/linux/vmlinux ffffffff810815e0
/home/taeung/git/linux/kernel/workqueue.c:3650
$ cd ~/git/linux
$ grep wq_calc_node_cpumask
kernel/workqueue.c
3627: * wq_calc_node_cpumask - calculate a wq_attrs' cpumask for the
specified node
3648:static bool wq_calc_node_cpumask(const struct workqueue_attrs *attrs,
int node,
3766: if (wq_calc_node_cpumask(new_attrs, node, -1, tmp_attrs->cpumask)) {
3938: if (wq_calc_node_cpumask(wq->dfl_pwq->pool->attrs, node, cpu_off,
cpumask)) {
Or, the dwarf info of vmlinux was wrongly made up ?
[root@quaco perf]# pfunct --decl_info --prototypes ../build/v5.0-rc3+/kernel/workqueue.o | grep -B2 wq_calc_node_cpumask
/* Used at: /home/acme/git/linux/kernel/workqueue.c */
/* <3137e> /home/acme/git/linux/kernel/workqueue.c:3648 */
void wq_calc_node_cpumask(const struct workqueue_attrs * attrs, int node, int cpu_going_down, cpumask_t * cpumask);
--
/* Used at: /home/acme/git/linux/kernel/workqueue.c */
/* <1ff33> /home/acme/git/linux/kernel/workqueue.c:3648 */
bool wq_calc_node_cpumask(const struct workqueue_attrs * attrs, int node, int cpu_going_down, cpumask_t * cpumask);
[root@quaco perf]#
Seem there is a difference in that dwarf_dieoffset(), so:
[root@quaco perf]# readelf -wi ../build/v5.0-rc3+/kernel/workqueue.o | grep -B1 -A7 wq_calc_node_cpumask
<1><1ff33>: Abbrev Number: 49 (DW_TAG_subprogram)
<1ff34> DW_AT_name : (indirect string, offset: 0x498d): wq_calc_node_cpumask
<1ff38> DW_AT_decl_file : 1
<1ff39> DW_AT_decl_line : 3648
<1ff3b> DW_AT_decl_column : 13
<1ff3c> DW_AT_prototyped : 1
<1ff3c> DW_AT_type : <0x2bb>
<1ff40> DW_AT_inline : 1 (inlined)
<1ff41> DW_AT_sibling : <0x1ffb1>
[root@quaco perf]#
So, see that DW_AT_inline?
This is just a function that was not declared inline but was forced
inline and inlined twice in that file.
[root@quaco perf]# pfunct --cc_inlined ../build/v5.0-rc3+/kernel/workqueue.o | grep wq_calc_node_cpumask
wq_calc_node_cpumask
[root@quaco perf]#
[root@quaco perf]# pfunct --help | grep -- --cc_inlined
-H, --cc_inlined not declared inline, inlined by compiler
[root@quaco perf]#
- Arnaldo
Thank you so much !
I understood it.
But even though wq_calc_node_cpumask() was inlined by compiler,
(therefore, "DW_AT_inline : 1 (inlined)")
why are there its symbol and its code like below ?
The function can be compiled as two case ?
1) inlined case
2) normal function call case
so declared twice in that file ?
(as they seemed by "pfunct --decl_info")
$ readelf -s vmlinux | grep wq_calc_node_cpumask
5887: ffffffff810815e0 143 FUNC LOCAL DEFAULT 1
wq_calc_node_cpumask
$ objdump -d vmlinux | grep wq_calc_node_cpumask
ffffffff810815e0 <wq_calc_node_cpumask>:
...
And wq_update_unbound_numa() calls the function wq_calc_node_cpumask()
$ objdump -d vmlinux
...
ffffffff81082ec0 <wq_update_unbound_numa>:
...
ffffffff81082f69: e8 72 e6 ff ff callq ffffffff810815e0
<wq_calc_node_cpumask>
Thanks,
Taeung