Merge changes from linux-2.6 by hand
This commit is contained in:
@@ -843,6 +843,7 @@ fastcall NORET_TYPE void do_exit(long code)
|
||||
group_dead = atomic_dec_and_test(&tsk->signal->live);
|
||||
if (group_dead) {
|
||||
del_timer_sync(&tsk->signal->real_timer);
|
||||
exit_itimers(tsk->signal);
|
||||
acct_process(code);
|
||||
}
|
||||
exit_mm(tsk);
|
||||
|
@@ -848,7 +848,7 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
|
||||
{
|
||||
unsigned long new_flags = p->flags;
|
||||
|
||||
new_flags &= ~PF_SUPERPRIV;
|
||||
new_flags &= ~(PF_SUPERPRIV | PF_NOFREEZE);
|
||||
new_flags |= PF_FORKNOEXEC;
|
||||
if (!(clone_flags & CLONE_PTRACE))
|
||||
p->ptrace = 0;
|
||||
|
@@ -424,6 +424,7 @@ static void cleanup_timers(struct list_head *head,
|
||||
cputime_t ptime = cputime_add(utime, stime);
|
||||
|
||||
list_for_each_entry_safe(timer, next, head, entry) {
|
||||
put_task_struct(timer->task);
|
||||
timer->task = NULL;
|
||||
list_del_init(&timer->entry);
|
||||
if (cputime_lt(timer->expires.cpu, ptime)) {
|
||||
@@ -436,6 +437,7 @@ static void cleanup_timers(struct list_head *head,
|
||||
|
||||
++head;
|
||||
list_for_each_entry_safe(timer, next, head, entry) {
|
||||
put_task_struct(timer->task);
|
||||
timer->task = NULL;
|
||||
list_del_init(&timer->entry);
|
||||
if (cputime_lt(timer->expires.cpu, utime)) {
|
||||
@@ -448,6 +450,7 @@ static void cleanup_timers(struct list_head *head,
|
||||
|
||||
++head;
|
||||
list_for_each_entry_safe(timer, next, head, entry) {
|
||||
put_task_struct(timer->task);
|
||||
timer->task = NULL;
|
||||
list_del_init(&timer->entry);
|
||||
if (timer->expires.sched < sched_time) {
|
||||
|
@@ -1157,7 +1157,7 @@ retry_delete:
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called by __exit_signal, only when there are no more
|
||||
* This is called by do_exit or de_thread, only when there are no more
|
||||
* references to the shared signal_struct.
|
||||
*/
|
||||
void exit_itimers(struct signal_struct *sig)
|
||||
|
@@ -71,7 +71,7 @@ DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
|
||||
|
||||
/* Fake initialization required by compiler */
|
||||
static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
|
||||
static int maxbatch = 10;
|
||||
static int maxbatch = 10000;
|
||||
|
||||
#ifndef __HAVE_ARCH_CMPXCHG
|
||||
/*
|
||||
@@ -109,6 +109,10 @@ void fastcall call_rcu(struct rcu_head *head,
|
||||
rdp = &__get_cpu_var(rcu_data);
|
||||
*rdp->nxttail = head;
|
||||
rdp->nxttail = &head->next;
|
||||
|
||||
if (unlikely(++rdp->count > 10000))
|
||||
set_need_resched();
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
@@ -140,6 +144,12 @@ void fastcall call_rcu_bh(struct rcu_head *head,
|
||||
rdp = &__get_cpu_var(rcu_bh_data);
|
||||
*rdp->nxttail = head;
|
||||
rdp->nxttail = &head->next;
|
||||
rdp->count++;
|
||||
/*
|
||||
* Should we directly call rcu_do_batch() here ?
|
||||
* if (unlikely(rdp->count > 10000))
|
||||
* rcu_do_batch(rdp);
|
||||
*/
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
@@ -157,6 +167,7 @@ static void rcu_do_batch(struct rcu_data *rdp)
|
||||
next = rdp->donelist = list->next;
|
||||
list->func(list);
|
||||
list = next;
|
||||
rdp->count--;
|
||||
if (++count >= maxbatch)
|
||||
break;
|
||||
}
|
||||
|
@@ -397,20 +397,8 @@ void __exit_signal(struct task_struct *tsk)
|
||||
flush_sigqueue(&tsk->pending);
|
||||
if (sig) {
|
||||
/*
|
||||
* We are cleaning up the signal_struct here. We delayed
|
||||
* calling exit_itimers until after flush_sigqueue, just in
|
||||
* case our thread-local pending queue contained a queued
|
||||
* timer signal that would have been cleared in
|
||||
* exit_itimers. When that called sigqueue_free, it would
|
||||
* attempt to re-take the tasklist_lock and deadlock. This
|
||||
* can never happen if we ensure that all queues the
|
||||
* timer's signal might be queued on have been flushed
|
||||
* first. The shared_pending queue, and our own pending
|
||||
* queue are the only queues the timer could be on, since
|
||||
* there are no other threads left in the group and timer
|
||||
* signals are constrained to threads inside the group.
|
||||
* We are cleaning up the signal_struct here.
|
||||
*/
|
||||
exit_itimers(sig);
|
||||
exit_thread_group_keys(sig);
|
||||
kmem_cache_free(signal_cachep, sig);
|
||||
}
|
||||
|
@@ -570,6 +570,7 @@ void getnstimeofday(struct timespec *tv)
|
||||
tv->tv_sec = x.tv_sec;
|
||||
tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(getnstimeofday);
|
||||
#endif
|
||||
|
||||
#if (BITS_PER_LONG < 64)
|
||||
|
Reference in New Issue
Block a user