Re: pfunct: duplicate function prototypes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





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



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux