]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'perfcounters-fixes-for-linus' of git://git.kernel.org/pub/scm/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 20 Jun 2009 18:29:32 +0000 (11:29 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 20 Jun 2009 18:29:32 +0000 (11:29 -0700)
* 'perfcounters-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (49 commits)
  perfcounter: Handle some IO return values
  perf_counter: Push perf_sample_data through the swcounter code
  perf_counter tools: Define and use our own u64, s64 etc. definitions
  perf_counter: Close race in perf_lock_task_context()
  perf_counter, x86: Improve interactions with fast-gup
  perf_counter: Simplify and fix task migration counting
  perf_counter tools: Add a data file header
  perf_counter: Update userspace callchain sampling uses
  perf_counter: Make callchain samples extensible
  perf report: Filter to parent set by default
  perf_counter tools: Handle lost events
  perf_counter: Add event overlow handling
  fs: Provide empty .set_page_dirty() aop for anon inodes
  perf_counter: tools: Makefile tweaks for 64-bit powerpc
  perf_counter: powerpc: Add processor back-end for MPC7450 family
  perf_counter: powerpc: Make powerpc perf_counter code safe for 32-bit kernels
  perf_counter: powerpc: Change how processor-specific back-ends get selected
  perf_counter: powerpc: Use unsigned long for register and constraint values
  perf_counter: powerpc: Enable use of software counters on 32-bit powerpc
  perf_counter tools: Add and use isprint()
  ...

1  2 
arch/powerpc/kernel/Makefile
arch/powerpc/platforms/Kconfig.cputype
arch/x86/mm/gup.c
kernel/sched.c

index 6a4fb29a06184c6988bec3cafb7f36215a60280b,a9f882963379b8454316aef34fa5b2707c9dd28f..b73396b93905162fd7be004d069a7671d8073b53
@@@ -4,8 -4,6 +4,8 @@@
  
  CFLAGS_ptrace.o               += -DUTS_MACHINE='"$(UTS_MACHINE)"'
  
 +subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
 +
  ifeq ($(CONFIG_PPC64),y)
  CFLAGS_prom_init.o    += -mno-minimal-toc
  endif
@@@ -97,9 -95,10 +97,10 @@@ obj64-$(CONFIG_AUDIT)               += compat_audit.
  
  obj-$(CONFIG_DYNAMIC_FTRACE)  += ftrace.o
  obj-$(CONFIG_FUNCTION_GRAPH_TRACER)   += ftrace.o
- obj-$(CONFIG_PERF_COUNTERS)   += perf_counter.o power4-pmu.o ppc970-pmu.o \
-                                  power5-pmu.o power5+-pmu.o power6-pmu.o \
-                                  power7-pmu.o
+ obj-$(CONFIG_PPC_PERF_CTRS)   += perf_counter.o
+ obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \
+                                  power5+-pmu.o power6-pmu.o power7-pmu.o
+ obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o
  
  obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o
  
@@@ -108,6 -107,7 +109,7 @@@ obj-y                              += iomap.
  endif
  
  obj-$(CONFIG_PPC64)           += $(obj64-y)
+ obj-$(CONFIG_PPC32)           += $(obj32-y)
  
  ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC),)
  obj-y                         += ppc_save_regs.o
index c4192542b809de401e3393c9c93b930fa3e59d47,8485c8ca7a06ac64c225e357935002235fa7b875..61187bec75062e0f4656b0399cba3bc5bb492fed
@@@ -1,7 -1,7 +1,7 @@@
  config PPC64
        bool "64-bit kernel"
        default n
-       select HAVE_PERF_COUNTERS
+       select PPC_HAVE_PMU_SUPPORT
        help
          This option selects whether a 32-bit or a 64-bit kernel
          will be built.
@@@ -21,7 -21,7 +21,7 @@@ choic
  
          If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx.
  
 -config PPC_BOOK3S
 +config PPC_BOOK3S_32
        bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx"
        select PPC_FPU
  
@@@ -57,14 -57,11 +57,14 @@@ config E20
  
  endchoice
  
 -config PPC_BOOK3S
 -      default y
 +config PPC_BOOK3S_64
 +      def_bool y
        depends on PPC64
        select PPC_FPU
  
 +config PPC_BOOK3S
 +      def_bool y
 +      depends on PPC_BOOK3S_32 || PPC_BOOK3S_64
  
  config POWER4_ONLY
        bool "Optimize for POWER4"
@@@ -78,6 -75,7 +78,7 @@@
  config 6xx
        def_bool y
        depends on PPC32 && PPC_BOOK3S
+       select PPC_HAVE_PMU_SUPPORT
  
  config POWER3
        bool
@@@ -246,6 -244,15 +247,15 @@@ config VIRT_CPU_ACCOUNTIN
  
          If in doubt, say Y here.
  
+ config PPC_HAVE_PMU_SUPPORT
+        bool
+ config PPC_PERF_CTRS
+        def_bool y
+        depends on PERF_COUNTERS && PPC_HAVE_PMU_SUPPORT
+        help
+          This enables the powerpc-specific perf_counter back-end.
  config SMP
        depends on PPC_STD_MMU || FSL_BOOKE
        bool "Symmetric multi-processing support"
diff --combined arch/x86/mm/gup.c
index f974809412692190b2dd3fb7f7b0ca85bdcf838f,2d1d784ad3f789aa250e86ba418013c8010484f3..71da1bca13cbb9fde26f59100f1b9b3b30f3a8e5
@@@ -14,7 -14,7 +14,7 @@@
  static inline pte_t gup_get_pte(pte_t *ptep)
  {
  #ifndef CONFIG_X86_PAE
-       return *ptep;
+       return ACCESS_ONCE(*ptep);
  #else
        /*
         * With get_user_pages_fast, we walk down the pagetables without taking
@@@ -219,6 -219,62 +219,62 @@@ static int gup_pud_range(pgd_t pgd, uns
        return 1;
  }
  
+ /*
+  * Like get_user_pages_fast() except its IRQ-safe in that it won't fall
+  * back to the regular GUP.
+  */
+ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
+                         struct page **pages)
+ {
+       struct mm_struct *mm = current->mm;
+       unsigned long addr, len, end;
+       unsigned long next;
+       unsigned long flags;
+       pgd_t *pgdp;
+       int nr = 0;
+       start &= PAGE_MASK;
+       addr = start;
+       len = (unsigned long) nr_pages << PAGE_SHIFT;
+       end = start + len;
+       if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
+                                       (void __user *)start, len)))
+               return 0;
+       /*
+        * XXX: batch / limit 'nr', to avoid large irq off latency
+        * needs some instrumenting to determine the common sizes used by
+        * important workloads (eg. DB2), and whether limiting the batch size
+        * will decrease performance.
+        *
+        * It seems like we're in the clear for the moment. Direct-IO is
+        * the main guy that batches up lots of get_user_pages, and even
+        * they are limited to 64-at-a-time which is not so many.
+        */
+       /*
+        * This doesn't prevent pagetable teardown, but does prevent
+        * the pagetables and pages from being freed on x86.
+        *
+        * So long as we atomically load page table pointers versus teardown
+        * (which we do on x86, with the above PAE exception), we can follow the
+        * address down to the the page and take a ref on it.
+        */
+       local_irq_save(flags);
+       pgdp = pgd_offset(mm, addr);
+       do {
+               pgd_t pgd = *pgdp;
+               next = pgd_addr_end(addr, end);
+               if (pgd_none(pgd))
+                       break;
+               if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
+                       break;
+       } while (pgdp++, addr = next, addr != end);
+       local_irq_restore(flags);
+       return nr;
+ }
  /**
   * get_user_pages_fast() - pin user pages in memory
   * @start:    starting user address
@@@ -247,16 -303,11 +303,16 @@@ int get_user_pages_fast(unsigned long s
        start &= PAGE_MASK;
        addr = start;
        len = (unsigned long) nr_pages << PAGE_SHIFT;
 +
        end = start + len;
 -      if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
 -                                      (void __user *)start, len)))
 +      if (end < start)
                goto slow_irqon;
  
 +#ifdef CONFIG_X86_64
 +      if (end >> __VIRTUAL_MASK_SHIFT)
 +              goto slow_irqon;
 +#endif
 +
        /*
         * XXX: batch / limit 'nr', to avoid large irq off latency
         * needs some instrumenting to determine the common sizes used by
diff --combined kernel/sched.c
index 92e51287b980a1a2ca176b4bf34a81950d25e332,f46540b359c0de9c8f70454a4e91978047bf4cdf..7c9098d186e6f8e398c0cb9500c1efa2120293e2
@@@ -1978,7 -1978,8 +1978,8 @@@ void set_task_cpu(struct task_struct *p
                if (task_hot(p, old_rq->clock, NULL))
                        schedstat_inc(p, se.nr_forced2_migrations);
  #endif
-               perf_counter_task_migration(p, new_cpu);
+               perf_swcounter_event(PERF_COUNT_SW_CPU_MIGRATIONS,
+                                    1, 1, NULL, 0);
        }
        p->se.vruntime -= old_cfsrq->min_vruntime -
                                         new_cfsrq->min_vruntime;
@@@ -7045,7 -7046,7 +7046,7 @@@ static int migration_thread(void *data
  
                if (cpu_is_offline(cpu)) {
                        spin_unlock_irq(&rq->lock);
 -                      goto wait_to_die;
 +                      break;
                }
  
                if (rq->active_balance) {
                complete(&req->done);
        }
        __set_current_state(TASK_RUNNING);
 -      return 0;
  
 -wait_to_die:
 -      /* Wait for kthread_stop */
 -      set_current_state(TASK_INTERRUPTIBLE);
 -      while (!kthread_should_stop()) {
 -              schedule();
 -              set_current_state(TASK_INTERRUPTIBLE);
 -      }
 -      __set_current_state(TASK_RUNNING);
        return 0;
  }
  
@@@ -7485,7 -7495,6 +7486,7 @@@ migration_call(struct notifier_block *n
                rq = task_rq_lock(p, &flags);
                __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1);
                task_rq_unlock(rq, &flags);
 +              get_task_struct(p);
                cpu_rq(cpu)->migration_thread = p;
                break;
  
                kthread_bind(cpu_rq(cpu)->migration_thread,
                             cpumask_any(cpu_online_mask));
                kthread_stop(cpu_rq(cpu)->migration_thread);
 +              put_task_struct(cpu_rq(cpu)->migration_thread);
                cpu_rq(cpu)->migration_thread = NULL;
                break;
  
                migrate_live_tasks(cpu);
                rq = cpu_rq(cpu);
                kthread_stop(rq->migration_thread);
 +              put_task_struct(rq->migration_thread);
                rq->migration_thread = NULL;
                /* Idle task back to normal (off runqueue, low prio) */
                spin_lock_irq(&rq->lock);
@@@ -7822,7 -7829,7 +7823,7 @@@ static void rq_attach_root(struct rq *r
                free_rootdomain(old_rd);
  }
  
 -static int __init_refok init_rootdomain(struct root_domain *rd, bool bootmem)
 +static int init_rootdomain(struct root_domain *rd, bool bootmem)
  {
        gfp_t gfp = GFP_KERNEL;