[RFC]: MIPS: new ftrace implementation

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

 



This series add DYNAMC_FTRACE_WITH_REGS support without depending _mcount
and -pg, and try to address following issue

+. _mcount stub size is 3 insns in vmlinux  and  4 insns in .ko, too much

+. complex handing MIPS32 and MIPS64 in _mcount, especially sp pointer in
MIPS32

+. _mcount is called with sp adjusted in Callee(the traced function), which
is hard for livepatch to restore the sp pointer


GCC
#########

+. gcc 8 add -fpatchable-function-entry=N[, M] support to insert N 
nops before real start, for more info, see gcc 8 manual

+. gcc/mips has two bug: 93242 (fixed in gcc 10), 99217 (with a fix, but
not accepted) about this option. With fixes applyed in gcc 8.3, vmlinux is OK


Design
#########

+. Caller A calls Callee B, with -fpatchable-function-entry=3, B has 
three nops at its entry

------------
	::

		A:

			jal	B
			nop
		......

		B:
			nop
			nop
			nop

		#B: real start 
			INSN_B_first

+. With ftrace initialized or module loaded, this three nop got
replaced,

------------
	::

		A:

			jal	B
			nop
		......

		B:
			lui	at, %hi(ftrace_regs_caller)
			nop
			li	t0, 0

		#B: real start 
			INSN_B_first

Obviously, ftrace_regs_caller is 64KB aligned, thanks He Jinyang
<hejinyang@xxxxxxxxxxx>
	
+. To enable tracing , take nop into "jalr at, at“,

------------
	::

		A:

			jal	B
			nop
		......

		B:
			lui	at, %hi(ftrace_regs_caller)
			jalr	at, at
			li	t0, 0

		#B: real start 
			INSN_B_first
	

+. To disable tracing, take "jalr at, at" into nop

------------
	::

		A:

			jal	B
			nop
		......

		B:
			lui	at, %hi(ftrace_regs_caller)
			nop
			li	t0, 0

		#B: real start 
			INSN_B_first
	
+. when tracing without regs, replace "li t0, 0' with "li t0, 1"

------------
	::

		A:

			jal	B
			nop
		......
		B:
			lui	at, %hi(ftrace_regs_caller)
			jalr	at, at
			li	t0, 1
		#B: real start 
			INSN_B_first

With only one instruction modified, it is atomic and no sync needed (
_mcount need sync between two writes) on both MIPS32 and MIPS64, I got 
this from ARM64.

we need transfrom from tracing disabled into tracing without regs, first
replace "li t0, 0" with "li t0, 1", then "nop" with "jalr at, at", still
no sync between


------------
	::

		A:

			jal	B
			nop
		......
		B:
			lui	at, %hi(ftrace_regs_caller)
			jalr	at, at
			li	t0, 1

		#B: real start 
			INSN_B_first

+. When B is ok to be patched, replace first four instruction with new 
function B'

------------
	::

		A:

			jal	B
			nop
		......
		B:
			lui	at, %hi(B')	// second, fill new B'high
			addiu	at, %lo(B')	// first, fill nop
						// third, fill new B' low
			jr	at		// at last, fill jr
		#B: real start 
			nop			//forth, fill nop
						//Watch Out! 
						//first instruction 
						// clobbered. we
						//need to save it somewhere
						//or we must use four nops

if tracing enabled, we need to disable tracing first, and we need sync 
before fill "jr"
	
Patches
###########

Patch 1 - Patch 3 

This make new MIPS/ftrace with DYNAMIC_FTRACE_WITH_REGS in parallel with 
old MIPS/Ftrace 

Patch 4

Add DYNAMC_FTRACE_WITH_REGS support 

Remaining Issues
################

+. reserve three nops or four nops for <= MIPS R5 ?

Without direct call, three nops is enough. With direct call, we need to 
hack ftrace to save the first instruction somewhere. Four nops is enough 
for all cases

MIPS R6 only need three nops without hacking, but this version does not
support MIPS R6

+. MIPS32 support, working on it

+. checking for gcc version, can previous two bug back porting to gcc 8.5?
We should check gcc's version

+. stack backstrace





[Index of Archives]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux