Oh, testers for this patch will be welcome.. it runs fine on my system,
but I have not tested the CPU hotplug corner cases.

Mathieu

* Peter Zijlstra ([EMAIL PROTECTED]) wrote:
> From: Mathieu Desnoyers <[EMAIL PROTECTED]>
> 
> This patch adds the ability to protect critical sections from migration to
> another CPU without disabling preemption.
> 
> This will be useful to minimize the amount of preemption disabling for the -rt
> patch. It will help leveraging improvements brought by the local_t types in
> asm/local.h (see Documentation/local_ops.txt). Note that the updates done to
> variables protected by migrate_disable must be either atomic or protected from
> concurrent updates done by other threads.
> 
> Typical use:
> 
> migrate_disable();
> local_inc(&__get_cpu_var(&my_local_t_var));
> migrate_enable();
> 
> Which will increment the variable atomically wrt the local CPU.
> 
> Changes:
> 
> Do a check_migrate() upon migrate_enable() to answer to the migration
> thread waiting for us to exit the migration disabled critical section. Use a
> NEED_MIGRATE thread flag for this.
> 
> Note: (or we could say FIXME)
> Is we ever want to check migration pending in assembly code, we will have to
> make sure we test the right thread flag bits on each architectures. Care 
> should
> also be taken to check that the thread flags used won't trigger false 
> positives
> in non selective asm thread flag checks.
> 
> Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]>
> Signed-off-by: Peter Zijlstra <[EMAIL PROTECTED]>
> ---
>  include/asm-alpha/thread_info.h     |    3 +
>  include/asm-arm/thread_info.h       |    5 +
>  include/asm-arm26/thread_info.h     |    5 +
>  include/asm-avr32/thread_info.h     |    4 +
>  include/asm-blackfin/thread_info.h  |    4 +
>  include/asm-cris/thread_info.h      |    4 +
>  include/asm-frv/thread_info.h       |    4 +
>  include/asm-h8300/thread_info.h     |    4 +
>  include/asm-i386/thread_info.h      |    6 +-
>  include/asm-ia64/thread_info.h      |    4 +
>  include/asm-m32r/thread_info.h      |    4 +
>  include/asm-m68k/thread_info.h      |    2 
>  include/asm-m68knommu/thread_info.h |    3 +
>  include/asm-mips/thread_info.h      |    4 +
>  include/asm-parisc/thread_info.h    |    4 +
>  include/asm-powerpc/thread_info.h   |    4 +
>  include/asm-s390/thread_info.h      |    4 +
>  include/asm-sh/thread_info.h        |    4 +
>  include/asm-sh64/thread_info.h      |    4 +
>  include/asm-sparc/thread_info.h     |    4 +
>  include/asm-sparc64/thread_info.h   |    5 +
>  include/asm-um/thread_info.h        |    4 +
>  include/asm-v850/thread_info.h      |    4 +
>  include/asm-x86_64/thread_info.h    |    4 +
>  include/asm-xtensa/thread_info.h    |    4 +
>  include/linux/preempt.h             |   44 +++++++++++++++++
>  kernel/sched.c                      |   91 
> +++++++++++++++++++++++++++++++++---
>  lib/smp_processor_id.c              |    6 +-
>  28 files changed, 230 insertions(+), 12 deletions(-)
> 
> Index: linux-2.6/include/asm-i386/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-i386/thread_info.h
> +++ linux-2.6/include/asm-i386/thread_info.h
> @@ -31,8 +31,7 @@ struct thread_info {
>       unsigned long           status;         /* thread-synchronous flags */
>       __u32                   cpu;            /* current CPU */
>       int                     preempt_count;  /* 0 => preemptable, <0 => BUG 
> */
> -
> -
> +     int                     migrate_count;/* 0: can migrate, <0: BUG */
>       mm_segment_t            addr_limit;     /* thread address space:
>                                                  0-0xBFFFFFFF for user-thead
>                                                  0-0xFFFFFFFF for 
> kernel-thread
> @@ -74,6 +73,7 @@ struct thread_info {
>       .flags          = 0,                    \
>       .cpu            = 0,                    \
>       .preempt_count  = 1,                    \
> +     .migrate_count = 0,                     \
>       .addr_limit     = KERNEL_DS,            \
>       .restart_block = {                      \
>               .fn = do_no_restart_syscall,    \
> @@ -134,6 +134,7 @@ static inline struct thread_info *curren
>  #define TIF_SECCOMP          8       /* secure computing */
>  #define TIF_RESTORE_SIGMASK  9       /* restore signal mask in do_signal() */
>  #define TIF_NEED_RESCHED_DELAYED 10  /* reschedule on return to userspace */
> +#define TIF_NEED_MIGRATE     11      /* migration necessary */
>  #define TIF_MEMDIE           16
>  #define TIF_DEBUG            17      /* uses debug registers */
>  #define TIF_IO_BITMAP                18      /* uses I/O bitmap */
> @@ -151,6 +152,7 @@ static inline struct thread_info *curren
>  #define _TIF_SYSCALL_AUDIT   (1<<TIF_SYSCALL_AUDIT)
>  #define _TIF_SECCOMP         (1<<TIF_SECCOMP)
>  #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  #define _TIF_DEBUG           (1<<TIF_DEBUG)
>  #define _TIF_IO_BITMAP               (1<<TIF_IO_BITMAP)
>  #define _TIF_FREEZE          (1<<TIF_FREEZE)
> Index: linux-2.6/include/linux/preempt.h
> ===================================================================
> --- linux-2.6.orig/include/linux/preempt.h
> +++ linux-2.6/include/linux/preempt.h
> @@ -15,6 +15,8 @@
>    extern void notrace sub_preempt_count(unsigned int val);
>    extern void notrace mask_preempt_count(unsigned int mask);
>    extern void notrace unmask_preempt_count(unsigned int mask);
> +  extern void fastcall add_migrate_count(int val);
> +  extern void fastcall sub_migrate_count(int val);
>  #else
>  # define add_preempt_count(val)      do { preempt_count() += (val); } while 
> (0)
>  # define sub_preempt_count(val)      do { preempt_count() -= (val); } while 
> (0)
> @@ -22,6 +24,8 @@
>               do { preempt_count() |= (mask); } while (0)
>  # define unmask_preempt_count(mask) \
>               do { preempt_count() &= ~(mask); } while (0)
> +# define add_migrate_count(val) do { migrate_count() += (val); } while (0)
> +# define sub_migrate_count(val) do { migrate_count() -= (val); } while (0)
>  #endif
>  
>  #ifdef CONFIG_CRITICAL_TIMING
> @@ -35,7 +39,12 @@
>  #define inc_preempt_count() add_preempt_count(1)
>  #define dec_preempt_count() sub_preempt_count(1)
>  
> -#define preempt_count()              (current_thread_info()->preempt_count)
> +#define preempt_count() (current_thread_info()->preempt_count)
> +
> +#define inc_migrate_count() add_migrate_count(1)
> +#define dec_migrate_count() sub_migrate_count(1)
> +
> +#define migrate_count() (current_thread_info()->migrate_count)
>  
>  #ifdef CONFIG_PREEMPT
>  
> @@ -80,6 +89,36 @@ do { \
>       preempt_check_resched(); \
>  } while (0)
>  
> +#define migrate_disable() \
> +do { \
> +     inc_migrate_count(); \
> +     barrier(); \
> +} while (0)
> +
> +#define migrate_enable_no_check() \
> +do { \
> +     barrier(); \
> +     dec_migrate_count(); \
> +} while (0)
> +
> +#ifdef CONFIG_SMP
> +extern void do_check_migrate(void);
> +#define check_migrate() \
> +do { \
> +     if (unlikely(test_thread_flag(TIF_NEED_MIGRATE))) \
> +             do_check_migrate(); \
> +} while (0)
> +#else
> +#define check_migrate()
> +#endif
> +
> +#define migrate_enable() \
> +do { \
> +     migrate_enable_no_check(); \
> +     barrier(); \
> +     check_migrate(); \
> +} while (0)
> +
>  #else
>  
>  #define preempt_disable()            do { } while (0)
> @@ -91,6 +130,9 @@ do { \
>  
>  #define preempt_schedule_irq()               do { } while (0)
>  
> +#define migrate_disable()            do { } while (0)
> +#define migrate_enable()             do { } while (0)
> +
>  #endif
>  
>  #endif /* __LINUX_PREEMPT_H */
> Index: linux-2.6/kernel/sched.c
> ===================================================================
> --- linux-2.6.orig/kernel/sched.c
> +++ linux-2.6/kernel/sched.c
> @@ -1175,7 +1175,8 @@ migrate_task(struct task_struct *p, int 
>        * If the task is not on a runqueue (and not running), then
>        * it is sufficient to simply update the task's cpu field.
>        */
> -     if (!p->se.on_rq && !task_running(rq, p)) {
> +     if (!p->se.on_rq && !task_running(rq, p)
> +                     && !task_thread_info(p)->migrate_count) {
>               set_task_cpu(p, dest_cpu);
>               return 0;
>       }
> @@ -1506,6 +1507,29 @@ static void balance_rt_tasks(struct rq *
>  
>  #endif
>  
> +void fastcall add_migrate_count(int val)
> +{
> +     /*
> +      * Underflow?
> +      */
> +     if (DEBUG_LOCKS_WARN_ON((migrate_count() < 0)))
> +             return;
> +     migrate_count() += val;
> +}
> +EXPORT_SYMBOL(add_migrate_count);
> +
> +void fastcall sub_migrate_count(int val)
> +{
> +     /*
> +      * Underflow?
> +      */
> +     if (DEBUG_LOCKS_WARN_ON(val > migrate_count()))
> +             return;
> +
> +     migrate_count() -= val;
> +}
> +EXPORT_SYMBOL(sub_migrate_count);
> +
>  /*
>   * find_idlest_cpu - find the idlest cpu among the cpus in group.
>   */
> @@ -1696,7 +1720,10 @@ try_to_wake_up(struct task_struct *p, un
>  #ifdef CONFIG_SMP
>       if (unlikely(task_running(rq, p)))
>               goto out_activate;
> -
> +#ifdef CONFIG_PREEMPT
> +     if (task_thread_info(p)->migrate_count)
> +             goto out_activate;
> +#endif
>       new_cpu = cpu;
>  
>       schedstat_inc(rq, ttwu_cnt);
> @@ -1970,6 +1997,7 @@ void sched_fork(struct task_struct *p, i
>  #ifdef CONFIG_PREEMPT
>       /* Want to start with kernel preemption disabled. */
>       task_thread_info(p)->preempt_count = 1;
> +     task_thread_info(p)->migrate_count = 0;
>  #endif
>       put_cpu();
>  }
> @@ -2435,6 +2463,10 @@ static void sched_migrate_task(struct ta
>       if (!cpu_isset(dest_cpu, p->cpus_allowed)
>           || unlikely(cpu_is_offline(dest_cpu)))
>               goto out;
> +#ifdef CONFIG_PREEMPT
> +     if (task_thread_info(p)->migrate_count)
> +             goto out;
> +#endif
>  
>       /* force the process onto the specified CPU */
>       if (migrate_task(p, dest_cpu, &req)) {
> @@ -2496,6 +2528,7 @@ int can_migrate_task(struct task_struct 
>        * 1) running (obviously), or
>        * 2) cannot be migrated to this CPU due to cpus_allowed, or
>        * 3) are cache-hot on their current CPU.
> +      * 4) migration preemption is non 0 for this non running task.
>        */
>       if (!cpu_isset(this_cpu, p->cpus_allowed))
>               return 0;
> @@ -2503,6 +2536,10 @@ int can_migrate_task(struct task_struct 
>  
>       if (task_running(rq, p))
>               return 0;
> +#ifdef CONFIG_PREEMPT
> +     if (task_thread_info(p)->migrate_count)
> +             return 0;
> +#endif
>  
>       /*
>        * Aggressive migration if too many balance attempts have failed:
> @@ -3822,6 +3859,27 @@ EXPORT_SYMBOL(schedule);
>  
>  #ifdef CONFIG_PREEMPT
>  
> +#ifdef CONFIG_SMP
> +/*
> + * Wake up the migration thread to deal with our pending migration.
> + * If we have been moved since, we will just wake up the migration thread 
> from
> + * the wrong CPU, which does not hurt anyone. (that's why we use
> + * raw_smp_processor_id()).
> + */
> +void __sched do_check_migrate(void)
> +{
> +     struct rq *rq;
> +
> +     if (migrate_count())
> +             return;
> +
> +     clear_thread_flag(TIF_NEED_MIGRATE);
> +     rq = cpu_rq(raw_smp_processor_id());
> +     wake_up_process(rq->migration_thread);
> +}
> +EXPORT_SYMBOL(do_check_migrate);
> +#endif
> +
>  /*
>   * Global flag to turn preemption off on a CONFIG_PREEMPT kernel:
>   */
> @@ -5478,7 +5536,7 @@ EXPORT_SYMBOL_GPL(set_cpus_allowed);
>   * So we race with normal scheduler movements, but that's OK, as long
>   * as the task is no longer on this CPU.
>   *
> - * Returns non-zero if task was successfully migrated.
> + * Returns non-zero if task is on dest_cpu when this function ends.
>   */
>  static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
>  {
> @@ -5500,13 +5558,19 @@ static int __migrate_task(struct task_st
>  
>       double_rq_lock(rq_src, rq_dest);
>       /* Already moved. */
> -     if (task_cpu(p) != src_cpu)
> +     if (task_cpu(p) != src_cpu) {
> +             ret = 1;
>               goto out;
> +     }
>       /* Affinity changed (again). */
>       if (!cpu_isset(dest_cpu, p->cpus_allowed))
>               goto out;
>  
>       on_rq = p->se.on_rq;
> +#ifdef CONFIG_PREEMPT
> +     if (!on_rq && task_thread_info(p)->migrate_count)
> +             goto out;
> +#endif
>       if (on_rq)
>               deactivate_task(rq_src, p, 0);
>  
> @@ -5532,6 +5596,7 @@ static int migration_thread(void *data)
>  {
>       int cpu = (long)data;
>       struct rq *rq;
> +     int migrated;
>  
>       rq = cpu_rq(cpu);
>       BUG_ON(rq->migration_thread != current);
> @@ -5567,10 +5632,22 @@ static int migration_thread(void *data)
>               list_del_init(head->next);
>  
>               spin_unlock(&rq->lock);
> -             __migrate_task(req->task, cpu, req->dest_cpu);
> +             migrated = __migrate_task(req->task, cpu, req->dest_cpu);
>               local_irq_enable();
> -
> -             complete(&req->done);
> +             if (!migrated) {
> +                     /*
> +                      * If the process has not been migrated, let it run
> +                      * until it reaches a migration_check() so it can
> +                      * wake us up.
> +                      */
> +                     spin_lock_irq(&rq->lock);
> +                     head = &rq->migration_queue;
> +                     list_add(&req->list, head);
> +                     set_tsk_thread_flag(req->task, TIF_NEED_MIGRATE);
> +                     spin_unlock_irq(&rq->lock);
> +                     wake_up_process(req->task);
> +             } else
> +                     complete(&req->done);
>       }
>       __set_current_state(TASK_RUNNING);
>       return 0;
> Index: linux-2.6/include/asm-alpha/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-alpha/thread_info.h
> +++ linux-2.6/include/asm-alpha/thread_info.h
> @@ -21,6 +21,7 @@ struct thread_info {
>       mm_segment_t            addr_limit;     /* thread address space */
>       unsigned                cpu;            /* current CPU */
>       int                     preempt_count; /* 0 => preemptable, <0 => BUG */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>  
>       int bpt_nsaved;
>       unsigned long bpt_addr[2];              /* breakpoint handling  */
> @@ -77,6 +78,7 @@ register struct thread_info *__current_t
>  #define TIF_UAC_SIGBUS               8
>  #define TIF_MEMDIE           9
>  #define TIF_RESTORE_SIGMASK  10      /* restore signal mask in do_signal */
> +#define TIF_NEED_MIGRATE     11      /* migration necessary */
>  
>  #define _TIF_SYSCALL_TRACE   (1<<TIF_SYSCALL_TRACE)
>  #define _TIF_NOTIFY_RESUME   (1<<TIF_NOTIFY_RESUME)
> @@ -84,6 +86,7 @@ register struct thread_info *__current_t
>  #define _TIF_NEED_RESCHED    (1<<TIF_NEED_RESCHED)
>  #define _TIF_POLLING_NRFLAG  (1<<TIF_POLLING_NRFLAG)
>  #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  
>  /* Work to do on interrupt/exception return.  */
>  #define _TIF_WORK_MASK               (_TIF_NOTIFY_RESUME     \
> Index: linux-2.6/include/asm-arm/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-arm/thread_info.h
> +++ linux-2.6/include/asm-arm/thread_info.h
> @@ -51,6 +51,7 @@ struct cpu_context_save {
>  struct thread_info {
>       unsigned long           flags;          /* low level flags */
>       int                     preempt_count;  /* 0 => preemptable, <0 => bug 
> */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>       mm_segment_t            addr_limit;     /* address limit */
>       struct task_struct      *task;          /* main task structure */
>       struct exec_domain      *exec_domain;   /* execution domain */
> @@ -72,6 +73,7 @@ struct thread_info {
>       .exec_domain    = &default_exec_domain,                         \
>       .flags          = 0,                                            \
>       .preempt_count  = 1,                                            \
> +     .migrate_count = 0,                                             \
>       .addr_limit     = KERNEL_DS,                                    \
>       .cpu_domain     = domain_val(DOMAIN_USER, DOMAIN_MANAGER) |     \
>                         domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) |   \
> @@ -138,6 +140,7 @@ extern void iwmmxt_task_switch(struct th
>   *  TIF_NOTIFY_RESUME        - resumption notification requested
>   *  TIF_SIGPENDING   - signal pending
>   *  TIF_NEED_RESCHED - rescheduling necessary
> + *  TIF_NEED_MIGRATE - migration necessary
>   *  TIF_USEDFPU              - FPU was used by this task this quantum (SMP)
>   *  TIF_POLLING_NRFLAG       - true if poll_idle() is polling 
> TIF_NEED_RESCHED
>   */
> @@ -145,6 +148,7 @@ extern void iwmmxt_task_switch(struct th
>  #define TIF_SIGPENDING               1
>  #define TIF_NEED_RESCHED     2
>  #define TIF_NEED_RESCHED_DELAYED 3
> +#define TIF_NEED_MIGRATE     4
>  #define TIF_SYSCALL_TRACE    8
>  #define TIF_POLLING_NRFLAG   16
>  #define TIF_USING_IWMMXT     17
> @@ -155,6 +159,7 @@ extern void iwmmxt_task_switch(struct th
>  #define _TIF_SIGPENDING              (1 << TIF_SIGPENDING)
>  #define _TIF_NEED_RESCHED    (1 << TIF_NEED_RESCHED)
>  #define _TIF_NEED_RESCHED_DELAYED (1<<TIF_NEED_RESCHED_DELAYED)
> +#define _TIF_NEED_MIGRATE    (1 << TIF_NEED_MIGRATE)
>  #define _TIF_SYSCALL_TRACE   (1 << TIF_SYSCALL_TRACE)
>  #define _TIF_POLLING_NRFLAG  (1 << TIF_POLLING_NRFLAG)
>  #define _TIF_USING_IWMMXT    (1 << TIF_USING_IWMMXT)
> Index: linux-2.6/include/asm-arm26/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-arm26/thread_info.h
> +++ linux-2.6/include/asm-arm26/thread_info.h
> @@ -45,6 +45,7 @@ struct cpu_context_save {
>  struct thread_info {
>       unsigned long           flags;          /* low level flags */
>       int                     preempt_count;  /* 0 => preemptable, <0 => bug 
> */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>       mm_segment_t            addr_limit;     /* address limit */
>       struct task_struct      *task;          /* main task structure */
>       struct exec_domain      *exec_domain;   /* execution domain */
> @@ -60,6 +61,7 @@ struct thread_info {
>       .exec_domain    &default_exec_domain,   \
>       .flags          0,                      \
>       .preempt_count  0,                      \
> +     .migrate_count 0,                       \
>       .addr_limit     KERNEL_DS,              \
>       .restart_block  = {                             \
>               .fn     = do_no_restart_syscall,        \
> @@ -113,12 +115,14 @@ extern void free_thread_info(struct thre
>   *  TIF_NOTIFY_RESUME        - resumption notification requested
>   *  TIF_SIGPENDING   - signal pending
>   *  TIF_NEED_RESCHED - rescheduling necessary
> + *  TIF_NEED_MIGRATE - migration necessary
>   *  TIF_USEDFPU              - FPU was used by this task this quantum (SMP)
>   *  TIF_POLLING_NRFLAG       - true if poll_idle() is polling 
> TIF_NEED_RESCHED
>   */
>  #define TIF_NOTIFY_RESUME    0
>  #define TIF_SIGPENDING               1
>  #define TIF_NEED_RESCHED     2
> +#define TIF_NEED_MIGRATE     3
>  #define TIF_SYSCALL_TRACE    8
>  #define TIF_USED_FPU         16
>  #define TIF_POLLING_NRFLAG   17
> @@ -127,6 +131,7 @@ extern void free_thread_info(struct thre
>  #define _TIF_NOTIFY_RESUME   (1 << TIF_NOTIFY_RESUME)
>  #define _TIF_SIGPENDING              (1 << TIF_SIGPENDING)
>  #define _TIF_NEED_RESCHED    (1 << TIF_NEED_RESCHED)
> +#define _TIF_NEED_MIGRATE    (1 << TIF_NEED_MIGRATE)
>  #define _TIF_SYSCALL_TRACE   (1 << TIF_SYSCALL_TRACE)
>  #define _TIF_USED_FPU                (1 << TIF_USED_FPU)
>  #define _TIF_POLLING_NRFLAG  (1 << TIF_POLLING_NRFLAG)
> Index: linux-2.6/include/asm-avr32/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-avr32/thread_info.h
> +++ linux-2.6/include/asm-avr32/thread_info.h
> @@ -25,6 +25,7 @@ struct thread_info {
>       unsigned long           flags;          /* low level flags */
>       __u32                   cpu;
>       __s32                   preempt_count;  /* 0 => preemptable, <0 => BUG 
> */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>       struct restart_block    restart_block;
>       __u8                    supervisor_stack[0];
>  };
> @@ -36,6 +37,7 @@ struct thread_info {
>       .flags          = 0,                                            \
>       .cpu            = 0,                                            \
>       .preempt_count  = 1,                                            \
> +     .migrate_count = 0,                                             \
>       .restart_block  = {                                             \
>               .fn     = do_no_restart_syscall                         \
>       }                                                               \
> @@ -84,6 +86,7 @@ static inline struct thread_info *curren
>  #define TIF_MEMDIE           7
>  #define TIF_RESTORE_SIGMASK  8       /* restore signal mask in do_signal */
>  #define TIF_CPU_GOING_TO_SLEEP       9       /* CPU is entering sleep 0 mode 
> */
> +#define TIF_NEED_MIGRATE      10       /* migration necessary */
>  #define TIF_USERSPACE                31      /* true if FS sets userspace */
>  
>  #define _TIF_SYSCALL_TRACE   (1 << TIF_SYSCALL_TRACE)
> @@ -96,6 +99,7 @@ static inline struct thread_info *curren
>  #define _TIF_MEMDIE          (1 << TIF_MEMDIE)
>  #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
>  #define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP)
> +#define _TIF_NEED_MIGRATE    (1 << TIF_NEED_MIGRATE)
>  
>  /* XXX: These two masks must never span more than 16 bits! */
>  /* work to do on interrupt/exception return */
> Index: linux-2.6/include/asm-blackfin/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-blackfin/thread_info.h
> +++ linux-2.6/include/asm-blackfin/thread_info.h
> @@ -54,6 +54,7 @@ struct thread_info {
>       unsigned long flags;    /* low level flags */
>       int cpu;                /* cpu we're on */
>       int preempt_count;      /* 0 => preemptable, <0 => BUG */
> +     int migrate_count;      /* 0: can migrate, <0 => BUG */
>       mm_segment_t addr_limit;        /* address limit */
>       struct restart_block restart_block;
>       struct l1_scratch_task_info l1_task_info;
> @@ -69,6 +70,7 @@ struct thread_info {
>       .flags          = 0,                    \
>       .cpu            = 0,                    \
>       .preempt_count  = 1,                    \
> +     .migrate_count = 0,                     \
>       .restart_block  = {                     \
>               .fn = do_no_restart_syscall,    \
>       },                                      \
> @@ -126,6 +128,7 @@ static inline struct thread_info *curren
>  #define TIF_MEMDIE              5
>  #define TIF_RESTORE_SIGMASK  6       /* restore signal mask in do_signal() */
>  #define TIF_FREEZE              7       /* is freezing for suspend */
> +#define TIF_NEED_MIGRATE     8       /* migration necessary */
>  
>  /* as above, but as bit values */
>  #define _TIF_SYSCALL_TRACE   (1<<TIF_SYSCALL_TRACE)
> @@ -135,6 +138,7 @@ static inline struct thread_info *curren
>  #define _TIF_POLLING_NRFLAG  (1<<TIF_POLLING_NRFLAG)
>  #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
>  #define _TIF_FREEZE             (1<<TIF_FREEZE)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  
>  #define _TIF_WORK_MASK               0x0000FFFE      /* work to do on 
> interrupt/exception return */
>  
> Index: linux-2.6/include/asm-cris/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-cris/thread_info.h
> +++ linux-2.6/include/asm-cris/thread_info.h
> @@ -32,6 +32,7 @@ struct thread_info {
>       unsigned long           flags;          /* low level flags */
>       __u32                   cpu;            /* current CPU */
>       int                     preempt_count;  /* 0 => preemptable, <0 => BUG 
> */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>  
>       mm_segment_t            addr_limit;     /* thread address space:
>                                                  0-0xBFFFFFFF for user-thead
> @@ -58,6 +59,7 @@ struct thread_info {
>       .flags          = 0,                            \
>       .cpu            = 0,                            \
>       .preempt_count  = 1,                            \
> +     .migrate_count = 0,                             \
>       .addr_limit     = KERNEL_DS,                    \
>       .restart_block = {                              \
>                      .fn = do_no_restart_syscall,     \
> @@ -82,6 +84,7 @@ struct thread_info {
>  #define TIF_NOTIFY_RESUME    1       /* resumption notification requested */
>  #define TIF_SIGPENDING               2       /* signal pending */
>  #define TIF_NEED_RESCHED     3       /* rescheduling necessary */
> +#define TIF_NEED_MIGRATE     4       /* migration necessary */
>  #define TIF_POLLING_NRFLAG   16      /* true if poll_idle() is polling 
> TIF_NEED_RESCHED */
>  #define TIF_MEMDIE           17
>  
> @@ -90,6 +93,7 @@ struct thread_info {
>  #define _TIF_SIGPENDING              (1<<TIF_SIGPENDING)
>  #define _TIF_NEED_RESCHED    (1<<TIF_NEED_RESCHED)
>  #define _TIF_POLLING_NRFLAG  (1<<TIF_POLLING_NRFLAG)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  
>  #define _TIF_WORK_MASK               0x0000FFFE      /* work to do on 
> interrupt/exception return */
>  #define _TIF_ALLWORK_MASK    0x0000FFFF      /* work to do on any return to 
> u-space */
> Index: linux-2.6/include/asm-frv/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-frv/thread_info.h
> +++ linux-2.6/include/asm-frv/thread_info.h
> @@ -36,6 +36,7 @@ struct thread_info {
>       unsigned long           status;         /* thread-synchronous flags */
>       __u32                   cpu;            /* current CPU */
>       int                     preempt_count;  /* 0 => preemptable, <0 => BUG 
> */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>  
>       mm_segment_t            addr_limit;     /* thread address space:
>                                                  0-0xBFFFFFFF for user-thead
> @@ -68,6 +69,7 @@ struct thread_info {
>       .flags          = 0,                    \
>       .cpu            = 0,                    \
>       .preempt_count  = 1,                    \
> +     .migrate_count = 0,                     \
>       .addr_limit     = KERNEL_DS,            \
>       .restart_block = {                      \
>               .fn = do_no_restart_syscall,    \
> @@ -114,6 +116,7 @@ register struct thread_info *__current_t
>  #define TIF_SINGLESTEP               4       /* restore singlestep on return 
> to user mode */
>  #define TIF_IRET             5       /* return with iret */
>  #define TIF_RESTORE_SIGMASK  6       /* restore signal mask in do_signal() */
> +#define TIF_NEED_MIGRATE     7       /* migration necessary */
>  #define TIF_POLLING_NRFLAG   16      /* true if poll_idle() is polling 
> TIF_NEED_RESCHED */
>  #define TIF_MEMDIE           17      /* OOM killer killed process */
>  #define TIF_FREEZE           18      /* freezing for suspend */
> @@ -127,6 +130,7 @@ register struct thread_info *__current_t
>  #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
>  #define _TIF_POLLING_NRFLAG  (1 << TIF_POLLING_NRFLAG)
>  #define _TIF_FREEZE          (1 << TIF_FREEZE)
> +#define _TIF_NEED_MIGRATE    (1 << TIF_NEED_MIGRATE)
>  
>  #define _TIF_WORK_MASK               0x0000FFFE      /* work to do on 
> interrupt/exception return */
>  #define _TIF_ALLWORK_MASK    0x0000FFFF      /* work to do on any return to 
> u-space */
> Index: linux-2.6/include/asm-h8300/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-h8300/thread_info.h
> +++ linux-2.6/include/asm-h8300/thread_info.h
> @@ -24,6 +24,7 @@ struct thread_info {
>       unsigned long      flags;               /* low level flags */
>       int                cpu;                 /* cpu we're on */
>       int                preempt_count;       /* 0 => preemptable, <0 => BUG 
> */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>       struct restart_block restart_block;
>  };
>  
> @@ -37,6 +38,7 @@ struct thread_info {
>       .flags =        0,                      \
>       .cpu =          0,                      \
>       .preempt_count = 1,                     \
> +     .migrate_count = 0,                     \
>       .restart_block  = {                     \
>               .fn = do_no_restart_syscall,    \
>       },                                      \
> @@ -92,6 +94,7 @@ static inline struct thread_info *curren
>  #define TIF_POLLING_NRFLAG   4       /* true if poll_idle() is polling
>                                          TIF_NEED_RESCHED */
>  #define TIF_MEMDIE           5
> +#define TIF_NEED_MIGRATE     6       /* migration necessary */
>  
>  /* as above, but as bit values */
>  #define _TIF_SYSCALL_TRACE   (1<<TIF_SYSCALL_TRACE)
> @@ -99,6 +102,7 @@ static inline struct thread_info *curren
>  #define _TIF_SIGPENDING              (1<<TIF_SIGPENDING)
>  #define _TIF_NEED_RESCHED    (1<<TIF_NEED_RESCHED)
>  #define _TIF_POLLING_NRFLAG  (1<<TIF_POLLING_NRFLAG)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  
>  #define _TIF_WORK_MASK               0x0000FFFE      /* work to do on 
> interrupt/exception return */
>  
> Index: linux-2.6/include/asm-ia64/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-ia64/thread_info.h
> +++ linux-2.6/include/asm-ia64/thread_info.h
> @@ -30,6 +30,7 @@ struct thread_info {
>       __u32 status;                   /* Thread synchronous flags */
>       mm_segment_t addr_limit;        /* user-level address space limit */
>       int preempt_count;              /* 0=premptable, <0=BUG; will also 
> serve as bh-counter */
> +     int migrate_count;              /* 0: can migrate, <0 => BUG */
>       struct restart_block restart_block;
>  };
>  
> @@ -43,6 +44,7 @@ struct thread_info {
>       .cpu            = 0,                    \
>       .addr_limit     = KERNEL_DS,            \
>       .preempt_count  = 0,                    \
> +     .migrate_count = 0,                     \
>       .restart_block = {                      \
>               .fn = do_no_restart_syscall,    \
>       },                                      \
> @@ -86,6 +88,7 @@ struct thread_info {
>  #define TIF_SYSCALL_AUDIT    4       /* syscall auditing active */
>  #define TIF_SINGLESTEP               5       /* restore singlestep on return 
> to user mode */
>  #define TIF_RESTORE_SIGMASK  6       /* restore signal mask in do_signal() */
> +#define TIF_NEED_MIGRATE     7       /* migration necessary */
>  #define TIF_POLLING_NRFLAG   16      /* true if poll_idle() is polling 
> TIF_NEED_RESCHED */
>  #define TIF_MEMDIE           17
>  #define TIF_MCA_INIT         18      /* this task is processing MCA or INIT 
> */
> @@ -99,6 +102,7 @@ struct thread_info {
>  #define _TIF_SYSCALL_TRACEAUDIT      
> (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP)
>  #define _TIF_NOTIFY_RESUME   (1 << TIF_NOTIFY_RESUME)
>  #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
> +#define _TIF_NEED_MIGRATE    (1 << TIF_NEED_MIGRATE)
>  #define _TIF_SIGPENDING              (1 << TIF_SIGPENDING)
>  #define _TIF_NEED_RESCHED    (1 << TIF_NEED_RESCHED)
>  #define _TIF_POLLING_NRFLAG  (1 << TIF_POLLING_NRFLAG)
> Index: linux-2.6/include/asm-m32r/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-m32r/thread_info.h
> +++ linux-2.6/include/asm-m32r/thread_info.h
> @@ -29,6 +29,7 @@ struct thread_info {
>       unsigned long           status;         /* thread-synchronous flags */
>       __u32                   cpu;            /* current CPU */
>       int                     preempt_count;  /* 0 => preemptable, <0 => BUG 
> */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>  
>       mm_segment_t            addr_limit;     /* thread address space:
>                                                  0-0xBFFFFFFF for user-thread
> @@ -69,6 +70,7 @@ struct thread_info {
>       .flags          = 0,                    \
>       .cpu            = 0,                    \
>       .preempt_count  = 1,                    \
> +     .migrate_count = 0,                     \
>       .addr_limit     = KERNEL_DS,            \
>       .restart_block = {                      \
>               .fn = do_no_restart_syscall,    \
> @@ -151,6 +153,7 @@ static inline unsigned int get_thread_fa
>  #define TIF_NEED_RESCHED     3       /* rescheduling necessary */
>  #define TIF_SINGLESTEP               4       /* restore singlestep on return 
> to user mode */
>  #define TIF_IRET             5       /* return with iret */
> +#define TIF_NEED_MIGRATE     6       /* migration necessary */
>  #define TIF_POLLING_NRFLAG   16      /* true if poll_idle() is polling 
> TIF_NEED_RESCHED */
>                                       /* 31..28 fault code */
>  #define TIF_MEMDIE           17
> @@ -162,6 +165,7 @@ static inline unsigned int get_thread_fa
>  #define _TIF_SINGLESTEP              (1<<TIF_SINGLESTEP)
>  #define _TIF_IRET            (1<<TIF_IRET)
>  #define _TIF_POLLING_NRFLAG  (1<<TIF_POLLING_NRFLAG)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  
>  #define _TIF_WORK_MASK               0x0000FFFE      /* work to do on 
> interrupt/exception return */
>  #define _TIF_ALLWORK_MASK    0x0000FFFF      /* work to do on any return to 
> u-space */
> Index: linux-2.6/include/asm-m68k/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-m68k/thread_info.h
> +++ linux-2.6/include/asm-m68k/thread_info.h
> @@ -9,6 +9,7 @@ struct thread_info {
>       unsigned long           flags;
>       struct exec_domain      *exec_domain;   /* execution domain */
>       int                     preempt_count;  /* 0 => preemptable, <0 => BUG 
> */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>       __u32 cpu; /* should always be 0 on m68k */
>       struct restart_block    restart_block;
>  };
> @@ -58,5 +59,6 @@ struct thread_info {
>  #define TIF_DELAYED_TRACE    14      /* single step a syscall */
>  #define TIF_SYSCALL_TRACE    15      /* syscall trace active */
>  #define TIF_MEMDIE           16
> +#define TIF_NEED_MIGRATE     17      /* migration necessary */
>  
>  #endif       /* _ASM_M68K_THREAD_INFO_H */
> Index: linux-2.6/include/asm-m68knommu/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-m68knommu/thread_info.h
> +++ linux-2.6/include/asm-m68knommu/thread_info.h
> @@ -37,6 +37,7 @@ struct thread_info {
>       unsigned long      flags;               /* low level flags */
>       int                cpu;                 /* cpu we're on */
>       int                preempt_count;       /* 0 => preemptable, <0 => BUG 
> */
> +     int                migrate_count;       /* 0: can migrate, <0 => BUG */
>       struct restart_block restart_block;
>  };
>  
> @@ -89,6 +90,7 @@ static inline struct thread_info *curren
>  #define TIF_POLLING_NRFLAG   4       /* true if poll_idle() is polling
>                                          TIF_NEED_RESCHED */
>  #define TIF_MEMDIE           5
> +#define TIF_NEED_MIGRATE     6       /* migration necessary */
>  
>  /* as above, but as bit values */
>  #define _TIF_SYSCALL_TRACE   (1<<TIF_SYSCALL_TRACE)
> @@ -96,6 +98,7 @@ static inline struct thread_info *curren
>  #define _TIF_SIGPENDING              (1<<TIF_SIGPENDING)
>  #define _TIF_NEED_RESCHED    (1<<TIF_NEED_RESCHED)
>  #define _TIF_POLLING_NRFLAG  (1<<TIF_POLLING_NRFLAG)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  
>  #define _TIF_WORK_MASK               0x0000FFFE      /* work to do on 
> interrupt/exception return */
>  
> Index: linux-2.6/include/asm-mips/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-mips/thread_info.h
> +++ linux-2.6/include/asm-mips/thread_info.h
> @@ -28,6 +28,7 @@ struct thread_info {
>       unsigned long           tp_value;       /* thread pointer */
>       __u32                   cpu;            /* current CPU */
>       int                     preempt_count;  /* 0 => preemptable, <0 => BUG 
> */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>  
>       mm_segment_t            addr_limit;     /* thread address space:
>                                                  0-0xBFFFFFFF for user-thead
> @@ -49,6 +50,7 @@ struct thread_info {
>       .flags          = 0,                    \
>       .cpu            = 0,                    \
>       .preempt_count  = 1,                    \
> +     .migrate_count = 0,                     \
>       .addr_limit     = KERNEL_DS,            \
>       .restart_block  = {                     \
>               .fn = do_no_restart_syscall,    \
> @@ -115,6 +117,7 @@ register struct thread_info *__current_t
>  #define TIF_SYSCALL_AUDIT    4       /* syscall auditing active */
>  #define TIF_SECCOMP          5       /* secure computing */
>  #define TIF_NEED_RESCHED_DELAYED 6   /* reschedule on return to userspace */
> +#define TIF_NEED_MIGRATE     7       /* migration necessary */
>  #define TIF_RESTORE_SIGMASK  9       /* restore signal mask in do_signal() */
>  #define TIF_USEDFPU          16      /* FPU was used by this task this 
> quantum (SMP) */
>  #define TIF_POLLING_NRFLAG   17      /* true if poll_idle() is polling 
> TIF_NEED_RESCHED */
> @@ -129,6 +132,7 @@ register struct thread_info *__current_t
>  #define _TIF_SYSCALL_AUDIT   (1<<TIF_SYSCALL_AUDIT)
>  #define _TIF_SECCOMP         (1<<TIF_SECCOMP)
>  #define _TIF_NEED_RESCHED_DELAYED (1<<TIF_NEED_RESCHED_DELAYED)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
>  #define _TIF_USEDFPU         (1<<TIF_USEDFPU)
>  #define _TIF_POLLING_NRFLAG  (1<<TIF_POLLING_NRFLAG)
> Index: linux-2.6/include/asm-parisc/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-parisc/thread_info.h
> +++ linux-2.6/include/asm-parisc/thread_info.h
> @@ -13,6 +13,7 @@ struct thread_info {
>       mm_segment_t addr_limit;        /* user-level address space limit */
>       __u32 cpu;                      /* current CPU */
>       int preempt_count;              /* 0=premptable, <0=BUG; will also 
> serve as bh-counter */
> +     int migrate_count;              /* 0: can migrate, <0 => BUG */
>       struct restart_block restart_block;
>  };
>  
> @@ -24,6 +25,7 @@ struct thread_info {
>       .cpu            = 0,                    \
>       .addr_limit     = KERNEL_DS,            \
>       .preempt_count  = 1,                    \
> +     .migrate_count = 0,                     \
>       .restart_block  = {                     \
>               .fn = do_no_restart_syscall     \
>       }                                       \
> @@ -63,6 +65,7 @@ struct thread_info {
>  #define TIF_32BIT               5       /* 32 bit binary */
>  #define TIF_MEMDIE           6
>  #define TIF_RESTORE_SIGMASK  7       /* restore saved signal mask */
> +#define TIF_NEED_MIGRATE     8       /* migration necessary */
>  
>  #define _TIF_SYSCALL_TRACE   (1 << TIF_SYSCALL_TRACE)
>  #define _TIF_NOTIFY_RESUME   (1 << TIF_NOTIFY_RESUME)
> @@ -71,6 +74,7 @@ struct thread_info {
>  #define _TIF_POLLING_NRFLAG  (1 << TIF_POLLING_NRFLAG)
>  #define _TIF_32BIT           (1 << TIF_32BIT)
>  #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
> +#define _TIF_NEED_MIGRATE    (1 << TIF_NEED_MIGRATE)
>  
>  #define _TIF_USER_WORK_MASK     (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
>                                   _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK)
> Index: linux-2.6/include/asm-powerpc/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-powerpc/thread_info.h
> +++ linux-2.6/include/asm-powerpc/thread_info.h
> @@ -35,6 +35,7 @@ struct thread_info {
>       int             cpu;                    /* cpu we're on */
>       int             preempt_count;          /* 0 => preemptable,
>                                                  <0 => BUG */
> +     int             migrate_count;  /* 0: can migrate, <0 => BUG */
>       struct restart_block restart_block;
>       unsigned long   local_flags;            /* private flags for thread */
>  
> @@ -53,6 +54,7 @@ struct thread_info {
>       .exec_domain =  &default_exec_domain,   \
>       .cpu =          0,                      \
>       .preempt_count = 1,                     \
> +     .migrate_count = 0,                     \
>       .restart_block = {                      \
>               .fn = do_no_restart_syscall,    \
>       },                                      \
> @@ -124,6 +126,7 @@ static inline struct thread_info *curren
>  #define TIF_NOERROR          14      /* Force successful syscall return */
>  #define TIF_RESTORE_SIGMASK  15      /* Restore signal mask in do_signal */
>  #define TIF_FREEZE           16      /* Freezing for suspend */
> +#define TIF_NEED_MIGRATE     17      /* migration necessary */
>  
>  /* as above, but as bit values */
>  #define _TIF_SYSCALL_TRACE   (1<<TIF_SYSCALL_TRACE)
> @@ -143,6 +146,7 @@ static inline struct thread_info *curren
>  #define _TIF_FREEZE          (1<<TIF_FREEZE)
>  #define _TIF_NEED_RESCHED_DELAYED (1<<TIF_NEED_RESCHED_DELAYED)
>  
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  #define _TIF_SYSCALL_T_OR_A  
> (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
>  
>  #define _TIF_USER_WORK_MASK  (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
> Index: linux-2.6/include/asm-s390/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-s390/thread_info.h
> +++ linux-2.6/include/asm-s390/thread_info.h
> @@ -51,6 +51,7 @@ struct thread_info {
>       unsigned long           flags;          /* low level flags */
>       unsigned int            cpu;            /* current CPU */
>       int                     preempt_count;  /* 0 => preemptable, <0 => BUG 
> */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>       struct restart_block    restart_block;
>  };
>  
> @@ -64,6 +65,7 @@ struct thread_info {
>       .flags          = 0,                    \
>       .cpu            = 0,                    \
>       .preempt_count  = 1,                    \
> +     .migrate_count = 0,                     \
>       .restart_block  = {                     \
>               .fn = do_no_restart_syscall,    \
>       },                                      \
> @@ -96,6 +98,7 @@ static inline struct thread_info *curren
>  #define TIF_SYSCALL_AUDIT    5       /* syscall auditing active */
>  #define TIF_SINGLE_STEP              6       /* deliver sigtrap on return to 
> user */
>  #define TIF_MCCK_PENDING     7       /* machine check handling is pending */
> +#define TIF_NEED_MIGRATE     8       /* migration necessary */
>  #define TIF_USEDFPU          16      /* FPU was used by this task this 
> quantum (SMP) */
>  #define TIF_POLLING_NRFLAG   17      /* true if poll_idle() is polling 
>                                          TIF_NEED_RESCHED */
> @@ -110,6 +113,7 @@ static inline struct thread_info *curren
>  #define _TIF_SYSCALL_AUDIT   (1<<TIF_SYSCALL_AUDIT)
>  #define _TIF_SINGLE_STEP     (1<<TIF_SINGLE_STEP)
>  #define _TIF_MCCK_PENDING    (1<<TIF_MCCK_PENDING)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  #define _TIF_USEDFPU         (1<<TIF_USEDFPU)
>  #define _TIF_POLLING_NRFLAG  (1<<TIF_POLLING_NRFLAG)
>  #define _TIF_31BIT           (1<<TIF_31BIT)
> Index: linux-2.6/include/asm-sh/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-sh/thread_info.h
> +++ linux-2.6/include/asm-sh/thread_info.h
> @@ -21,6 +21,7 @@ struct thread_info {
>       unsigned long           flags;          /* low level flags */
>       __u32                   cpu;
>       int                     preempt_count; /* 0 => preemptable, <0 => BUG */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>       mm_segment_t            addr_limit;     /* thread address space */
>       struct restart_block    restart_block;
>       unsigned long           previous_sp;    /* sp of previous stack in case
> @@ -58,6 +59,7 @@ struct thread_info {
>       .flags          = 0,                    \
>       .cpu            = 0,                    \
>       .preempt_count  = 1,                    \
> +     .migrate_count = 0,                     \
>       .addr_limit     = KERNEL_DS,            \
>       .restart_block  = {                     \
>               .fn = do_no_restart_syscall,    \
> @@ -113,6 +115,7 @@ static inline struct thread_info *curren
>  #define TIF_RESTORE_SIGMASK  4       /* restore signal mask in do_signal() */
>  #define TIF_SINGLESTEP               5       /* singlestepping active */
>  #define TIF_NEED_RESCHED_DELAYED     6       /* reschedule on return to 
> userspace */
> +#define TIF_NEED_MIGRATE     7       /* migration necessary */
>  #define TIF_USEDFPU          16      /* FPU was used by this task this 
> quantum (SMP) */
>  #define TIF_POLLING_NRFLAG   17      /* true if poll_idle() is polling 
> TIF_NEED_RESCHED */
>  #define TIF_MEMDIE           18
> @@ -125,6 +128,7 @@ static inline struct thread_info *curren
>  #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
>  #define _TIF_SINGLESTEP              (1<<TIF_SINGLESTEP)
>  #define _TIF_NEED_RESCHED_DELAYED    (1<<TIF_NEED_RESCHED_DELAYED)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  #define _TIF_USEDFPU         (1<<TIF_USEDFPU)
>  #define _TIF_POLLING_NRFLAG  (1<<TIF_POLLING_NRFLAG)
>  #define _TIF_FREEZE          (1<<TIF_FREEZE)
> Index: linux-2.6/include/asm-sh64/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-sh64/thread_info.h
> +++ linux-2.6/include/asm-sh64/thread_info.h
> @@ -23,6 +23,7 @@ struct thread_info {
>       unsigned long           flags;          /* low level flags */
>       /* Put the 4 32-bit fields together to make asm offsetting easier. */
>       int                     preempt_count;  /* 0 => preemptable, <0 => BUG 
> */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>       __u16                   cpu;
>  
>       mm_segment_t            addr_limit;
> @@ -41,6 +42,7 @@ struct thread_info {
>       .flags          = 0,                    \
>       .cpu            = 0,                    \
>       .preempt_count  = 1,                    \
> +     .migrate_count = 0,                     \
>       .addr_limit     = KERNEL_DS,            \
>       .restart_block  = {                     \
>               .fn = do_no_restart_syscall,    \
> @@ -79,12 +81,14 @@ static inline struct thread_info *curren
>  #define TIF_NEED_RESCHED     3       /* rescheduling necessary */
>  #define TIF_MEMDIE           4
>  #define TIF_RESTORE_SIGMASK  5       /* Restore signal mask in do_signal */
> +#define TIF_NEED_MIGRATE     6       /* migration necessary */
>  
>  #define _TIF_SYSCALL_TRACE   (1 << TIF_SYSCALL_TRACE)
>  #define _TIF_SIGPENDING              (1 << TIF_SIGPENDING)
>  #define _TIF_NEED_RESCHED    (1 << TIF_NEED_RESCHED)
>  #define _TIF_MEMDIE          (1 << TIF_MEMDIE)
>  #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
> +#define _TIF_NEED_MIGRATE    (1 << TIF_NEED_MIGRATE)
>  
>  #endif /* __KERNEL__ */
>  
> Index: linux-2.6/include/asm-sparc/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-sparc/thread_info.h
> +++ linux-2.6/include/asm-sparc/thread_info.h
> @@ -33,6 +33,7 @@ struct thread_info {
>       int                     cpu;            /* cpu we're on */
>       int                     preempt_count;  /* 0 => preemptable,
>                                                  <0 => BUG */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>       int                     softirq_count;
>       int                     hardirq_count;
>  
> @@ -65,6 +66,7 @@ struct thread_info {
>       .flags          =       0,                      \
>       .cpu            =       0,                      \
>       .preempt_count  =       1,                      \
> +     .migrate_count =        0,                      \
>       .restart_block  = {                             \
>               .fn     =       do_no_restart_syscall,  \
>       },                                              \
> @@ -132,6 +134,7 @@ BTFIXUPDEF_CALL(void, free_thread_info, 
>  #define TIF_SIGPENDING               2       /* signal pending */
>  #define TIF_NEED_RESCHED     3       /* rescheduling necessary */
>  #define TIF_RESTORE_SIGMASK  4       /* restore signal mask in do_signal() */
> +#define TIF_NEED_MIGRATE     5       /* migration necessary */
>  #define TIF_USEDFPU          8       /* FPU was used by this task
>                                        * this quantum (SMP) */
>  #define TIF_POLLING_NRFLAG   9       /* true if poll_idle() is polling
> @@ -143,6 +146,7 @@ BTFIXUPDEF_CALL(void, free_thread_info, 
>  #define _TIF_SIGPENDING              (1<<TIF_SIGPENDING)
>  #define _TIF_NEED_RESCHED    (1<<TIF_NEED_RESCHED)
>  #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  #define _TIF_USEDFPU         (1<<TIF_USEDFPU)
>  #define _TIF_POLLING_NRFLAG  (1<<TIF_POLLING_NRFLAG)
>  
> Index: linux-2.6/include/asm-sparc64/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-sparc64/thread_info.h
> +++ linux-2.6/include/asm-sparc64/thread_info.h
> @@ -47,6 +47,7 @@ struct thread_info {
>       struct pt_regs          *kregs;
>       struct exec_domain      *exec_domain;
>       int                     preempt_count;  /* 0 => preemptable, <0 => BUG 
> */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>       __u8                    new_child;
>       __u8                    syscall_noerror;
>       __u16                   cpu;
> @@ -137,6 +138,7 @@ struct thread_info {
>       .flags          = ((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT,   
> \
>       .exec_domain    =       &default_exec_domain,   \
>       .preempt_count  =       1,                      \
> +     .migrate_count =        0,                      \
>       .restart_block  = {                             \
>               .fn     =       do_no_restart_syscall,  \
>       },                                              \
> @@ -225,7 +227,7 @@ register struct thread_info *current_thr
>  #define TIF_UNALIGNED                5       /* allowed to do unaligned 
> accesses */
>  #define TIF_NEWSIGNALS               6       /* wants new-style signals */
>  #define TIF_32BIT            7       /* 32-bit binary */
> -/* flag bit 8 is available */
> +#define TIF_NEED_MIGRATE     8       /* migration necessary */
>  #define TIF_SECCOMP          9       /* secure computing */
>  #define TIF_SYSCALL_AUDIT    10      /* syscall auditing active */
>  /* flag bit 11 is available */
> @@ -244,6 +246,7 @@ register struct thread_info *current_thr
>  #define _TIF_UNALIGNED               (1<<TIF_UNALIGNED)
>  #define _TIF_NEWSIGNALS              (1<<TIF_NEWSIGNALS)
>  #define _TIF_32BIT           (1<<TIF_32BIT)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  #define _TIF_SECCOMP         (1<<TIF_SECCOMP)
>  #define _TIF_SYSCALL_AUDIT   (1<<TIF_SYSCALL_AUDIT)
>  #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
> Index: linux-2.6/include/asm-um/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-um/thread_info.h
> +++ linux-2.6/include/asm-um/thread_info.h
> @@ -18,6 +18,7 @@ struct thread_info {
>       __u32                   cpu;            /* current CPU */
>       int                     preempt_count;  /* 0 => preemptable,
>                                                  <0 => BUG */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>       mm_segment_t            addr_limit;     /* thread address space:
>                                                  0-0xBFFFFFFF for user
>                                                  0-0xFFFFFFFF for kernel */
> @@ -32,6 +33,7 @@ struct thread_info {
>       .flags =                0,              \
>       .cpu =          0,                      \
>       .preempt_count =        1,              \
> +     .migrate_count =        0,              \
>       .addr_limit =   KERNEL_DS,              \
>       .restart_block =  {                     \
>               .fn =  do_no_restart_syscall,   \
> @@ -71,6 +73,7 @@ static inline struct thread_info *curren
>  #define TIF_MEMDIE           5
>  #define TIF_SYSCALL_AUDIT    6
>  #define TIF_RESTORE_SIGMASK  7
> +#define TIF_NEED_MIGRATE     8       /* migration necessary */
>  
>  #define _TIF_SYSCALL_TRACE   (1 << TIF_SYSCALL_TRACE)
>  #define _TIF_SIGPENDING              (1 << TIF_SIGPENDING)
> @@ -79,5 +82,6 @@ static inline struct thread_info *curren
>  #define _TIF_MEMDIE          (1 << TIF_MEMDIE)
>  #define _TIF_SYSCALL_AUDIT   (1 << TIF_SYSCALL_AUDIT)
>  #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
> +#define _TIF_NEED_MIGRATE    (1 << TIF_NEED_MIGRATE)
>  
>  #endif
> Index: linux-2.6/include/asm-v850/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-v850/thread_info.h
> +++ linux-2.6/include/asm-v850/thread_info.h
> @@ -32,6 +32,7 @@ struct thread_info {
>       int                     cpu;            /* cpu we're on */
>       int                     preempt_count;  /* 0 => preemptable,
>                                                  <0 => BUG */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>       struct restart_block    restart_block;
>  };
>  
> @@ -42,6 +43,7 @@ struct thread_info {
>       .flags =        0,                                                    \
>       .cpu =          0,                                                    \
>       .preempt_count = 1,                                                   \
> +     .migrate_count = 0,                                                   \
>       .restart_block = {                                                    \
>               .fn = do_no_restart_syscall,                                  \
>       },                                                                    \
> @@ -83,6 +85,7 @@ struct thread_info {
>  #define TIF_POLLING_NRFLAG   4       /* true if poll_idle() is polling
>                                          TIF_NEED_RESCHED */
>  #define TIF_MEMDIE           5
> +#define TIF_NEED_MIGRATE     6       /* migration necessary */
>  
>  /* as above, but as bit values */
>  #define _TIF_SYSCALL_TRACE   (1<<TIF_SYSCALL_TRACE)
> @@ -90,6 +93,7 @@ struct thread_info {
>  #define _TIF_SIGPENDING              (1<<TIF_SIGPENDING)
>  #define _TIF_NEED_RESCHED    (1<<TIF_NEED_RESCHED)
>  #define _TIF_POLLING_NRFLAG  (1<<TIF_POLLING_NRFLAG)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  
>  
>  /* Size of kernel stack for each process.  */
> Index: linux-2.6/include/asm-x86_64/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-x86_64/thread_info.h
> +++ linux-2.6/include/asm-x86_64/thread_info.h
> @@ -30,6 +30,7 @@ struct thread_info {
>       __u32                   status;         /* thread synchronous flags */
>       __u32                   cpu;            /* current CPU */
>       int                     preempt_count;  /* 0 => preemptable, <0 => BUG 
> */
> +     int                     migrate_count;/* 0: can migrate, <0 => BUG */
>  
>       mm_segment_t            addr_limit;     
>       struct restart_block    restart_block;
> @@ -48,6 +49,7 @@ struct thread_info {
>       .flags         = 0,                     \
>       .cpu           = 0,                     \
>       .preempt_count = 1,                     \
> +     .migrate_count = 0,                     \
>       .addr_limit     = KERNEL_DS,            \
>       .restart_block = {                      \
>               .fn = do_no_restart_syscall,    \
> @@ -116,6 +118,7 @@ static inline struct thread_info *stack_
>  #define TIF_SYSCALL_AUDIT    7       /* syscall auditing active */
>  #define TIF_SECCOMP          8       /* secure computing */
>  #define TIF_RESTORE_SIGMASK  9       /* restore signal mask in do_signal */
> +#define TIF_NEED_MIGRATE     11      /* migration necessary */
>  /* 16 free */
>  #define TIF_IA32             17      /* 32bit process */ 
>  #define TIF_FORK             18      /* ret_from_fork */
> @@ -135,6 +138,7 @@ static inline struct thread_info *stack_
>  #define _TIF_SECCOMP         (1<<TIF_SECCOMP)
>  #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
>  #define _TIF_NEED_RESCHED_DELAYED (1<<TIF_NEED_RESCHED_DELAYED)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  #define _TIF_IA32            (1<<TIF_IA32)
>  #define _TIF_FORK            (1<<TIF_FORK)
>  #define _TIF_ABI_PENDING     (1<<TIF_ABI_PENDING)
> Index: linux-2.6/include/asm-xtensa/thread_info.h
> ===================================================================
> --- linux-2.6.orig/include/asm-xtensa/thread_info.h
> +++ linux-2.6/include/asm-xtensa/thread_info.h
> @@ -34,6 +34,7 @@ struct thread_info {
>       unsigned long           status;         /* thread-synchronous flags */
>       __u32                   cpu;            /* current CPU */
>       __s32                   preempt_count;  /* 0 => preemptable,< 0 => BUG*/
> +     __s32                   migrate_count;/* 0: can migrate, <0 => BUG */
>  
>       mm_segment_t            addr_limit;     /* thread address space */
>       struct restart_block    restart_block;
> @@ -72,6 +73,7 @@ struct thread_info {
>       .flags          = 0,                    \
>       .cpu            = 0,                    \
>       .preempt_count  = 1,                    \
> +     .migrate_count = 0,                     \
>       .addr_limit     = KERNEL_DS,            \
>       .restart_block = {                      \
>               .fn = do_no_restart_syscall,    \
> @@ -117,6 +119,7 @@ static inline struct thread_info *curren
>  #define TIF_IRET             5       /* return with iret */
>  #define TIF_MEMDIE           6
>  #define TIF_RESTORE_SIGMASK  7       /* restore signal mask in do_signal() */
> +#define TIF_NEED_MIGRATE     8       /* migration necessary */
>  #define TIF_POLLING_NRFLAG   16      /* true if poll_idle() is polling 
> TIF_NEED_RESCHED */
>  
>  #define _TIF_SYSCALL_TRACE   (1<<TIF_SYSCALL_TRACE)
> @@ -125,6 +128,7 @@ static inline struct thread_info *curren
>  #define _TIF_NEED_RESCHED    (1<<TIF_NEED_RESCHED)
>  #define _TIF_SINGLESTEP              (1<<TIF_SINGLESTEP)
>  #define _TIF_IRET            (1<<TIF_IRET)
> +#define _TIF_NEED_MIGRATE    (1<<TIF_NEED_MIGRATE)
>  #define _TIF_POLLING_NRFLAG  (1<<TIF_POLLING_NRFLAG)
>  #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
>  
> Index: linux-2.6/lib/smp_processor_id.c
> ===================================================================
> --- linux-2.6.orig/lib/smp_processor_id.c
> +++ linux-2.6/lib/smp_processor_id.c
> @@ -10,12 +10,16 @@
>  unsigned int notrace debug_smp_processor_id(void)
>  {
>       unsigned long preempt_count = preempt_count();
> +     unsigned long migrate_count = migrate_count();
>       int this_cpu = raw_smp_processor_id();
>       cpumask_t this_mask;
>  
>       if (likely(preempt_count))
>               goto out;
>  
> +     if (likely(migrate_count))
> +             goto out;
> +
>       if (irqs_disabled())
>               goto out;
>  
> @@ -42,7 +46,7 @@ unsigned int notrace debug_smp_processor
>       if (!printk_ratelimit())
>               goto out_enable;
>  
> -     printk(KERN_ERR "BUG: using smp_processor_id() in preemptible [%08x] 
> code: %s/%d\n", preempt_count()-1, current->comm, current->pid);
> +     printk(KERN_ERR "BUG: using smp_processor_id() in preemptible [%08x] 
> migration [%08x] code: %s/%d\n", preempt_count()-1, migrate_count(), 
> current->comm, current->pid);
>       print_symbol("caller is %s\n", (long)__builtin_return_address(0));
>       dump_stack();
>  
> 
> --
> 

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to