Thread (59 messages) 59 messages, 5 authors, 2021-03-08

RE: [PATCH v5 20/22] powerpc/syscall: Avoid storing 'current' in another pointer

From: David Laight <hidden>
Date: 2021-02-09 17:18:29
Also in: lkml

From: Christophe Leroy <redacted>
Sent: 09 February 2021 17:04

Le 09/02/2021 à 15:31, David Laight a écrit :
quoted
From: Segher Boessenkool
quoted
Sent: 09 February 2021 13:51

On Tue, Feb 09, 2021 at 12:36:20PM +1000, Nicholas Piggin wrote:
quoted
What if you did this?
quoted
+static inline struct task_struct *get_current(void)
+{
+	register struct task_struct *task asm ("r2");
+
+	return task;
+}
Local register asm variables are *only* guaranteed to live in that
register as operands to an asm.  See
   https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local-Register-Variables
("The only supported use" etc.)

You can do something like

static inline struct task_struct *get_current(void)
{
	register struct task_struct *task asm ("r2");

	asm("" : "+r"(task));

	return task;
}

which makes sure that "task" actually is in r2 at the point of that asm.
If "r2" always contains current (and is never assigned by the compiler)
why not use a global register variable for it?

The change proposed by Nick doesn't solve the issue.

The problem is that at the begining of the function we have:

	unsigned long *ti_flagsp = &current_thread_info()->flags;

When the function uses ti_flagsp for the first time, it does use 112(r2)

Then the function calls some other functions.

Most likely because the function could update 'current', GCC copies r2 into r30, so that if r2 get
changed by the called function, ti_flagsp is still based on the previous value of current.

Allthough we know r2 wont change, GCC doesn't know it. And in order to save r2 into r30, it needs to
save r30 in the stack.


By using &current_thread_info()->flags directly instead of this intermediaite ti_flagsp pointer, GCC
uses r2 instead instead of doing a copy.
Does marking current_thread_info() 'pure' (I think that the right one)
work - so that gcc knows its result doesn't depend on external data
and that it doesn't change external data.

Although I'm not 100% how well those attributes actually work.
Nick, I don't understand the reason why you need that 'ti_flagsp' local var.
Probably to save typing.

I sometimes reload locals after function calls.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help