2012-10-25 15:47:00

by Jonas Bonn

[permalink] [raw]
Subject: [PATCH 0/2] openrisc: more kernel_thread cleanup

Hi Al,

A couple of patches here that continue the cleanup outlined in the
kernel_thread discussion. Feel free to take these via your tree if
you feel that's appropriate; otherwise let me know and I'll throw
these into the openrisc tree.

/Jonas

Jonas Bonn (2):
openrisc: move sys_clone's stack determination to copy_thread
openrisc: determine regs directly in copy_thread

arch/openrisc/kernel/entry.S | 6 ++----
arch/openrisc/kernel/process.c | 9 +++++++--
arch/openrisc/kernel/sys_or32.c | 15 ++++-----------
3 files changed, 13 insertions(+), 17 deletions(-)

--
1.7.9.5


2012-10-25 15:46:59

by Jonas Bonn

[permalink] [raw]
Subject: [PATCH 1/2] openrisc: move sys_clone's stack determination to copy_thread

Signed-off-by: Jonas Bonn <[email protected]>
---
arch/openrisc/kernel/process.c | 6 +++++-
arch/openrisc/kernel/sys_or32.c | 8 +-------
2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c
index e0874b8..efbe4f8 100644
--- a/arch/openrisc/kernel/process.c
+++ b/arch/openrisc/kernel/process.c
@@ -170,7 +170,11 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
} else {
*userregs = *regs;

- userregs->sp = usp;
+ if (usp)
+ userregs->sp = usp; /* clone */
+ else
+ userregs->sp = regs->sp; /* fork/clone */
+
userregs->gpr[11] = 0; /* Result from fork() */

kregs->gpr[20] = 0; /* Userspace thread */
diff --git a/arch/openrisc/kernel/sys_or32.c b/arch/openrisc/kernel/sys_or32.c
index d6ddd3c..db46b82 100644
--- a/arch/openrisc/kernel/sys_or32.c
+++ b/arch/openrisc/kernel/sys_or32.c
@@ -46,12 +46,6 @@ asmlinkage long _sys_clone(unsigned long clone_flags, unsigned long newsp,
{
long ret;

- /* FIXME: Is alignment necessary? */
- /* newsp = ALIGN(newsp, 4); */
-
- if (!newsp)
- newsp = regs->sp;
-
ret = do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);

return ret;
@@ -60,7 +54,7 @@ asmlinkage long _sys_clone(unsigned long clone_flags, unsigned long newsp,
asmlinkage int _sys_fork(struct pt_regs *regs)
{
#ifdef CONFIG_MMU
- return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
+ return do_fork(SIGCHLD, 0, regs, 0, NULL, NULL);
#else
return -EINVAL;
#endif
--
1.7.9.5

2012-10-25 15:46:58

by Jonas Bonn

[permalink] [raw]
Subject: [PATCH 2/2] openrisc: determine regs directly in copy_thread

copy_thread can use current_pt_regs() to get the pt_regs data that
it needs so there's no need to pass this in as an argument.

As do_fork() doesn't use the regs argument for anything other than
to pass it straight through to copy_thread, we just pass in a NULL
argument in its place. The plan seems to be to eventually drop the
regs argument to do_fork altogether.

Signed-off-by: Jonas Bonn <[email protected]>
---
arch/openrisc/kernel/entry.S | 6 ++----
arch/openrisc/kernel/process.c | 3 ++-
arch/openrisc/kernel/sys_or32.c | 9 ++++-----
3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S
index cbd8f13..ea5439e 100644
--- a/arch/openrisc/kernel/entry.S
+++ b/arch/openrisc/kernel/entry.S
@@ -1073,15 +1073,13 @@ _fork_save_extra_regs_and_call:

ENTRY(sys_clone)
l.movhi r29,hi(_sys_clone)
- l.ori r29,r29,lo(_sys_clone)
l.j _fork_save_extra_regs_and_call
- l.addi r7,r1,0
+ l.ori r29,r29,lo(_sys_clone)

ENTRY(sys_fork)
l.movhi r29,hi(_sys_fork)
- l.ori r29,r29,lo(_sys_fork)
l.j _fork_save_extra_regs_and_call
- l.addi r3,r1,0
+ l.ori r29,r29,lo(_sys_fork)

ENTRY(sys_vfork)
l.movhi r29,hi(_sys_vfork)
diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c
index efbe4f8..87ca585 100644
--- a/arch/openrisc/kernel/process.c
+++ b/arch/openrisc/kernel/process.c
@@ -142,8 +142,9 @@ extern asmlinkage void ret_from_fork(void);

int
copy_thread(unsigned long clone_flags, unsigned long usp,
- unsigned long arg, struct task_struct *p, struct pt_regs *regs)
+ unsigned long arg, struct task_struct *p, struct pt_regs * unused)
{
+ struct pt_regs *regs = current_pt_regs();
struct pt_regs *userregs;
struct pt_regs *kregs;
unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
diff --git a/arch/openrisc/kernel/sys_or32.c b/arch/openrisc/kernel/sys_or32.c
index db46b82..a50826d 100644
--- a/arch/openrisc/kernel/sys_or32.c
+++ b/arch/openrisc/kernel/sys_or32.c
@@ -41,20 +41,19 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
*/

asmlinkage long _sys_clone(unsigned long clone_flags, unsigned long newsp,
- int __user *parent_tid, int __user *child_tid,
- struct pt_regs *regs)
+ int __user *parent_tid, int __user *child_tid)
{
long ret;

- ret = do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
+ ret = do_fork(clone_flags, newsp, 0, 0, parent_tid, child_tid);

return ret;
}

-asmlinkage int _sys_fork(struct pt_regs *regs)
+asmlinkage int _sys_fork()
{
#ifdef CONFIG_MMU
- return do_fork(SIGCHLD, 0, regs, 0, NULL, NULL);
+ return do_fork(SIGCHLD, 0, 0, 0, NULL, NULL);
#else
return -EINVAL;
#endif
--
1.7.9.5

2012-10-25 15:55:20

by Al Viro

[permalink] [raw]
Subject: Re: [PATCH 1/2] openrisc: move sys_clone's stack determination to copy_thread

On Thu, Oct 25, 2012 at 05:46:38PM +0200, Jonas Bonn wrote:
> Signed-off-by: Jonas Bonn <[email protected]>
> ---
> arch/openrisc/kernel/process.c | 6 +++++-
> arch/openrisc/kernel/sys_or32.c | 8 +-------
> 2 files changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c
> index e0874b8..efbe4f8 100644
> --- a/arch/openrisc/kernel/process.c
> +++ b/arch/openrisc/kernel/process.c
> @@ -170,7 +170,11 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
> } else {
> *userregs = *regs;
>
> - userregs->sp = usp;
> + if (usp)
> + userregs->sp = usp; /* clone */

OK

> + else
> + userregs->sp = regs->sp; /* fork/clone */

What for? userregs->sp will be equal to regs->sp at that point, unless
your compiler is very badly broken. You've copied *regs to *userregs
wholesale, just above that if...

2012-10-25 16:16:24

by Jonas Bonn

[permalink] [raw]
Subject: Re: [PATCH 1/2] openrisc: move sys_clone's stack determination to copy_thread

On Thu, 2012-10-25 at 16:55 +0100, Al Viro wrote:
> On Thu, Oct 25, 2012 at 05:46:38PM +0200, Jonas Bonn wrote:
> > + else
> > + userregs->sp = regs->sp; /* fork/clone */
>
> What for? userregs->sp will be equal to regs->sp at that point, unless
> your compiler is very badly broken. You've copied *regs to *userregs
> wholesale, just above that if...

So true... that makes it even simpler. Will resend.
/Jonas


Attachments:
signature.asc (198.00 B)
This is a digitally signed message part

2012-10-25 16:27:37

by Al Viro

[permalink] [raw]
Subject: Re: [PATCH 2/2] openrisc: determine regs directly in copy_thread

On Thu, Oct 25, 2012 at 05:46:39PM +0200, Jonas Bonn wrote:
> copy_thread can use current_pt_regs() to get the pt_regs data that
> it needs so there's no need to pass this in as an argument.
>
> As do_fork() doesn't use the regs argument for anything other than
> to pass it straight through to copy_thread, we just pass in a NULL
> argument in its place. The plan seems to be to eventually drop the
> regs argument to do_fork altogether.

Hmm... That's the plan, all right, but we need one more thing before
it's safe to pass NULL here.
if (!(clone_flags & CLONE_UNTRACED) && likely(user_mode(regs))) {
in do_fork() should (and can right now, no prereqs for that one) become
simply
if (!(clone_flags & CLONE_UNTRACED)) {
kernel_thread() *always* passes CLONE_UNTRACED, so it's not just "likely",
it's "always true if we get to evaluating that sucker in the first place".

FWIW, I think that merging that into mainline would be a good idea -
it would make life simpler and it's obviously safe. Another thing I probably
want to push to Linus, for pretty much the same reasons: generic variants
of fork/vfork/clone, selected by matching __ARCH_WANT_SYS_...; obviously
safe and allows to do that unification in per-arch trees. Less PITA
regarding the merge ordering that way...