Re: posix-cpu-timers revamp



Roland, I'm very much having to read between the lines of what you've
written. And, obviously, getting it wrong at least half the time. :-)

So you've cleared part of my understanding with your latest email.
Here's what I've gotten from it:

struct task_cputime {
cputime_t utime; /* User time. */
cputime_t stime; /* System time. */
unsigned long long sched_runtime; /* Scheduler time. */
};

This is for both SMP and UP, defined before signal_struct in sched.h
(since that structure refers to this one). Following that:

struct thread_group_cputime;

Which is a forward reference to the real definition later in the file.
The inline functions depend on signal_struct and task_struct, so they
have to come after:

#ifdef SMP

struct thread_group_cputime {
struct task_cputime *totals;
};

< ... inline functions ... >

#else /* SMP */

struct thread_group_cputime {
struct task_cputime totals;
};

< ... inline functions ... >

#endif

The SMP version is percpu, the UP version is just a substructure. In
signal_struct itself, delete utime & stime, add
struct thread_group_cputime cputime;

The inline functions include the ones you defined for UP plus equivalent
ones for SMP. The SMP inlines check the percpu pointer
(sig->cputime.totals) and don't update if it's NULL. One small
correction to one of your inlines, in thread_group_cputime:
*cputime = sig->cputime;
should be
*cputime = sig->cputime.totals;

A representative inline for SMP is:

static inline void account_group_system_time(struct task_struct *task,
cputime_t cputime)
{
struct task_cputime *times;

if (!sig->cputime.totals)
return;
times = per_cpu_ptr(sig->cputime.totals, get_cpu());
times->stime = cputime_add(times->stime, cputime);
put_cpu_no_resched();
}

To deal with the need for bookkeeping with multiple threads in the SMP
case (where there isn't a per-cpu structure until it's needed), I'll
allocate the per-cpu structure in __exit_signal() where the relevant
fields are updated. I'll also allocate it where I do now, in
do_setitimer(), when needed. The allocation will be a "return 0" for UP
and a call to "thread_group_times_alloc_smp()" (which lives in sched.c)
for SMP.

I'll also optimize run_posix_cpu_timers() as you suggest, and eliminate
rlim_expires.

Expect a new patch fairly soon.
--
Frank Mayhar <fmayhar@xxxxxxxxxx>
Google, Inc.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



Relevant Pages

  • [PATCH 01/15] mm: poison struct page for ptlock
    ... The split ptlock patch enlarged the default SMP PREEMPT struct page from ...
    (Linux-Kernel)
  • ULE/yielding patch for testing.
    ... On SMP it's hard to compare since ULE can do as many as 30x as many switches per second on my 8way system. ... retrieving revision 1.136 ... yield(struct thread *td, struct yield_args *uap) ... +#ifdef SMP ...
    (freebsd-current)
  • Re: ULE/yielding patch for testing.
    ... On SMP it's hard to compare since ULE can do as many as 30x as ... with: panic: Invalid priority 128 on timeshare runq ... yield(struct thread *td, struct yield_args *uap) ... +#ifdef SMP ...
    (freebsd-current)
  • [patch] SMP alternatives for i386
    ... This patch implements SMP alternatives, ... +/* Replace instructions with better alternatives for this CPU type. ... +struct smp_alt_module { ...
    (Linux-Kernel)
  • [patch 04/32] xen: Add Xen interface header files
    ... Define macros and inline functions for doing hypercalls into the ... * separately from the Linux kernel or incorporated into other ... +struct cpu_user_regs { ... A virtual IRQ may be bound to at most one event channel per vcpu. ...
    (Linux-Kernel)