Re: [PATCH v10 09/10] powerpc/perf: Thread IMC PMU functions

2017-06-12 Thread Madhavan Srinivasan



On Sunday 11 June 2017 01:43 AM, kbuild test robot wrote:

Hi Anju,

[auto build test ERROR on powerpc/next]
[also build test ERROR on v4.12-rc4 next-20170609]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Madhavan-Srinivasan/IMC-Instrumentation-Support/20170609-183528
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-defconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
 wget 
https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
 chmod +x ~/bin/make.cross
 # save the attached .config to linux build tree
 make.cross ARCH=powerpc

Note: the 
linux-review/Madhavan-Srinivasan/IMC-Instrumentation-Support/20170609-183528 
HEAD 32ada0705ff79986e8ceca5e83dba14c0b620751 builds fine.
   It only hurts bisectibility.

All errors (new ones prefixed by >>):

In file included from include/linux/compiler.h:62:0,
 from include/uapi/linux/stddef.h:1,
 from include/linux/stddef.h:4,
 from include/uapi/linux/posix_types.h:4,
 from include/uapi/linux/types.h:13,
 from include/linux/types.h:5,
 from include/uapi/linux/perf_event.h:17,
 from include/linux/perf_event.h:17,
 from arch/powerpc/perf/imc-pmu.c:13:
arch/powerpc/perf/imc-pmu.c: In function 'cleanup_all_thread_imc_memory':

arch/powerpc/perf/imc-pmu.c:863:31: error: 'cpu' undeclared (first use in this 
function)

Have fixed this issue in the next patch. Damn my bad.
Will wait for comments and if needed can respin just with this.

Maddy


   if (per_cpu(thread_imc_mem, cpu))
   ^
include/linux/compiler-gcc.h:53:26: note: in definition of macro 
'RELOC_HIDE'
  (typeof(ptr)) (__ptr + (off)); \
  ^~~
include/linux/percpu-defs.h:223:2: note: in expansion of macro 
'SHIFT_PERCPU_PTR'
  SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
  ^~~~
include/linux/percpu-defs.h:223:26: note: in expansion of macro 
'per_cpu_offset'
  SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
  ^~
include/linux/percpu-defs.h:256:29: note: in expansion of macro 
'per_cpu_ptr'
 #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu))
 ^~~
arch/powerpc/perf/imc-pmu.c:863:7: note: in expansion of macro 'per_cpu'
   if (per_cpu(thread_imc_mem, cpu))
   ^~~
arch/powerpc/perf/imc-pmu.c:863:31: note: each undeclared identifier is 
reported only once for each function it appears in
   if (per_cpu(thread_imc_mem, cpu))
   ^
include/linux/compiler-gcc.h:53:26: note: in definition of macro 
'RELOC_HIDE'
  (typeof(ptr)) (__ptr + (off)); \
  ^~~
include/linux/percpu-defs.h:223:2: note: in expansion of macro 
'SHIFT_PERCPU_PTR'
  SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
  ^~~~
include/linux/percpu-defs.h:223:26: note: in expansion of macro 
'per_cpu_offset'
  SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
  ^~
include/linux/percpu-defs.h:256:29: note: in expansion of macro 
'per_cpu_ptr'
 #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu))
 ^~~
arch/powerpc/perf/imc-pmu.c:863:7: note: in expansion of macro 'per_cpu'
   if (per_cpu(thread_imc_mem, cpu))
   ^~~

vim +/cpu +863 arch/powerpc/perf/imc-pmu.c

857 
858 static void cleanup_all_thread_imc_memory(void)
859 {
860 int i;
861 
862 for_each_online_cpu(i) {
  > 863  if (per_cpu(thread_imc_mem, cpu))
864 free_pages(per_cpu(thread_imc_mem, cpu), 0);
865 }
866 }

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation




Re: [PATCH v10 09/10] powerpc/perf: Thread IMC PMU functions

2017-06-12 Thread Madhavan Srinivasan



On Sunday 11 June 2017 01:43 AM, kbuild test robot wrote:

Hi Anju,

[auto build test ERROR on powerpc/next]
[also build test ERROR on v4.12-rc4 next-20170609]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Madhavan-Srinivasan/IMC-Instrumentation-Support/20170609-183528
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-defconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
 wget 
https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
 chmod +x ~/bin/make.cross
 # save the attached .config to linux build tree
 make.cross ARCH=powerpc

Note: the 
linux-review/Madhavan-Srinivasan/IMC-Instrumentation-Support/20170609-183528 
HEAD 32ada0705ff79986e8ceca5e83dba14c0b620751 builds fine.
   It only hurts bisectibility.

All errors (new ones prefixed by >>):

In file included from include/linux/compiler.h:62:0,
 from include/uapi/linux/stddef.h:1,
 from include/linux/stddef.h:4,
 from include/uapi/linux/posix_types.h:4,
 from include/uapi/linux/types.h:13,
 from include/linux/types.h:5,
 from include/uapi/linux/perf_event.h:17,
 from include/linux/perf_event.h:17,
 from arch/powerpc/perf/imc-pmu.c:13:
arch/powerpc/perf/imc-pmu.c: In function 'cleanup_all_thread_imc_memory':

arch/powerpc/perf/imc-pmu.c:863:31: error: 'cpu' undeclared (first use in this 
function)

Have fixed this issue in the next patch. Damn my bad.
Will wait for comments and if needed can respin just with this.

Maddy


   if (per_cpu(thread_imc_mem, cpu))
   ^
include/linux/compiler-gcc.h:53:26: note: in definition of macro 
'RELOC_HIDE'
  (typeof(ptr)) (__ptr + (off)); \
  ^~~
include/linux/percpu-defs.h:223:2: note: in expansion of macro 
'SHIFT_PERCPU_PTR'
  SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
  ^~~~
include/linux/percpu-defs.h:223:26: note: in expansion of macro 
'per_cpu_offset'
  SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
  ^~
include/linux/percpu-defs.h:256:29: note: in expansion of macro 
'per_cpu_ptr'
 #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu))
 ^~~
arch/powerpc/perf/imc-pmu.c:863:7: note: in expansion of macro 'per_cpu'
   if (per_cpu(thread_imc_mem, cpu))
   ^~~
arch/powerpc/perf/imc-pmu.c:863:31: note: each undeclared identifier is 
reported only once for each function it appears in
   if (per_cpu(thread_imc_mem, cpu))
   ^
include/linux/compiler-gcc.h:53:26: note: in definition of macro 
'RELOC_HIDE'
  (typeof(ptr)) (__ptr + (off)); \
  ^~~
include/linux/percpu-defs.h:223:2: note: in expansion of macro 
'SHIFT_PERCPU_PTR'
  SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
  ^~~~
include/linux/percpu-defs.h:223:26: note: in expansion of macro 
'per_cpu_offset'
  SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
  ^~
include/linux/percpu-defs.h:256:29: note: in expansion of macro 
'per_cpu_ptr'
 #define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu))
 ^~~
arch/powerpc/perf/imc-pmu.c:863:7: note: in expansion of macro 'per_cpu'
   if (per_cpu(thread_imc_mem, cpu))
   ^~~

vim +/cpu +863 arch/powerpc/perf/imc-pmu.c

857 
858 static void cleanup_all_thread_imc_memory(void)
859 {
860 int i;
861 
862 for_each_online_cpu(i) {
  > 863  if (per_cpu(thread_imc_mem, cpu))
864 free_pages(per_cpu(thread_imc_mem, cpu), 0);
865 }
866 }

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation




Re: [PATCH v10 09/10] powerpc/perf: Thread IMC PMU functions

2017-06-10 Thread kbuild test robot
Hi Anju,

[auto build test ERROR on powerpc/next]
[also build test ERROR on v4.12-rc4 next-20170609]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Madhavan-Srinivasan/IMC-Instrumentation-Support/20170609-183528
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-defconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget 
https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=powerpc 

Note: the 
linux-review/Madhavan-Srinivasan/IMC-Instrumentation-Support/20170609-183528 
HEAD 32ada0705ff79986e8ceca5e83dba14c0b620751 builds fine.
  It only hurts bisectibility.

All errors (new ones prefixed by >>):

   In file included from include/linux/compiler.h:62:0,
from include/uapi/linux/stddef.h:1,
from include/linux/stddef.h:4,
from include/uapi/linux/posix_types.h:4,
from include/uapi/linux/types.h:13,
from include/linux/types.h:5,
from include/uapi/linux/perf_event.h:17,
from include/linux/perf_event.h:17,
from arch/powerpc/perf/imc-pmu.c:13:
   arch/powerpc/perf/imc-pmu.c: In function 'cleanup_all_thread_imc_memory':
>> arch/powerpc/perf/imc-pmu.c:863:31: error: 'cpu' undeclared (first use in 
>> this function)
  if (per_cpu(thread_imc_mem, cpu))
  ^
   include/linux/compiler-gcc.h:53:26: note: in definition of macro 'RELOC_HIDE'
 (typeof(ptr)) (__ptr + (off)); \
 ^~~
   include/linux/percpu-defs.h:223:2: note: in expansion of macro 
'SHIFT_PERCPU_PTR'
 SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
 ^~~~
   include/linux/percpu-defs.h:223:26: note: in expansion of macro 
'per_cpu_offset'
 SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
 ^~
   include/linux/percpu-defs.h:256:29: note: in expansion of macro 'per_cpu_ptr'
#define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu))
^~~
   arch/powerpc/perf/imc-pmu.c:863:7: note: in expansion of macro 'per_cpu'
  if (per_cpu(thread_imc_mem, cpu))
  ^~~
   arch/powerpc/perf/imc-pmu.c:863:31: note: each undeclared identifier is 
reported only once for each function it appears in
  if (per_cpu(thread_imc_mem, cpu))
  ^
   include/linux/compiler-gcc.h:53:26: note: in definition of macro 'RELOC_HIDE'
 (typeof(ptr)) (__ptr + (off)); \
 ^~~
   include/linux/percpu-defs.h:223:2: note: in expansion of macro 
'SHIFT_PERCPU_PTR'
 SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
 ^~~~
   include/linux/percpu-defs.h:223:26: note: in expansion of macro 
'per_cpu_offset'
 SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
 ^~
   include/linux/percpu-defs.h:256:29: note: in expansion of macro 'per_cpu_ptr'
#define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu))
^~~
   arch/powerpc/perf/imc-pmu.c:863:7: note: in expansion of macro 'per_cpu'
  if (per_cpu(thread_imc_mem, cpu))
  ^~~

vim +/cpu +863 arch/powerpc/perf/imc-pmu.c

   857  
   858  static void cleanup_all_thread_imc_memory(void)
   859  {
   860  int i;
   861  
   862  for_each_online_cpu(i) {
 > 863  if (per_cpu(thread_imc_mem, cpu))
   864  free_pages(per_cpu(thread_imc_mem, cpu), 0);
   865  }
   866  }

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH v10 09/10] powerpc/perf: Thread IMC PMU functions

2017-06-10 Thread kbuild test robot
Hi Anju,

[auto build test ERROR on powerpc/next]
[also build test ERROR on v4.12-rc4 next-20170609]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Madhavan-Srinivasan/IMC-Instrumentation-Support/20170609-183528
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-defconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget 
https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=powerpc 

Note: the 
linux-review/Madhavan-Srinivasan/IMC-Instrumentation-Support/20170609-183528 
HEAD 32ada0705ff79986e8ceca5e83dba14c0b620751 builds fine.
  It only hurts bisectibility.

All errors (new ones prefixed by >>):

   In file included from include/linux/compiler.h:62:0,
from include/uapi/linux/stddef.h:1,
from include/linux/stddef.h:4,
from include/uapi/linux/posix_types.h:4,
from include/uapi/linux/types.h:13,
from include/linux/types.h:5,
from include/uapi/linux/perf_event.h:17,
from include/linux/perf_event.h:17,
from arch/powerpc/perf/imc-pmu.c:13:
   arch/powerpc/perf/imc-pmu.c: In function 'cleanup_all_thread_imc_memory':
>> arch/powerpc/perf/imc-pmu.c:863:31: error: 'cpu' undeclared (first use in 
>> this function)
  if (per_cpu(thread_imc_mem, cpu))
  ^
   include/linux/compiler-gcc.h:53:26: note: in definition of macro 'RELOC_HIDE'
 (typeof(ptr)) (__ptr + (off)); \
 ^~~
   include/linux/percpu-defs.h:223:2: note: in expansion of macro 
'SHIFT_PERCPU_PTR'
 SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
 ^~~~
   include/linux/percpu-defs.h:223:26: note: in expansion of macro 
'per_cpu_offset'
 SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
 ^~
   include/linux/percpu-defs.h:256:29: note: in expansion of macro 'per_cpu_ptr'
#define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu))
^~~
   arch/powerpc/perf/imc-pmu.c:863:7: note: in expansion of macro 'per_cpu'
  if (per_cpu(thread_imc_mem, cpu))
  ^~~
   arch/powerpc/perf/imc-pmu.c:863:31: note: each undeclared identifier is 
reported only once for each function it appears in
  if (per_cpu(thread_imc_mem, cpu))
  ^
   include/linux/compiler-gcc.h:53:26: note: in definition of macro 'RELOC_HIDE'
 (typeof(ptr)) (__ptr + (off)); \
 ^~~
   include/linux/percpu-defs.h:223:2: note: in expansion of macro 
'SHIFT_PERCPU_PTR'
 SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
 ^~~~
   include/linux/percpu-defs.h:223:26: note: in expansion of macro 
'per_cpu_offset'
 SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)));   \
 ^~
   include/linux/percpu-defs.h:256:29: note: in expansion of macro 'per_cpu_ptr'
#define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu))
^~~
   arch/powerpc/perf/imc-pmu.c:863:7: note: in expansion of macro 'per_cpu'
  if (per_cpu(thread_imc_mem, cpu))
  ^~~

vim +/cpu +863 arch/powerpc/perf/imc-pmu.c

   857  
   858  static void cleanup_all_thread_imc_memory(void)
   859  {
   860  int i;
   861  
   862  for_each_online_cpu(i) {
 > 863  if (per_cpu(thread_imc_mem, cpu))
   864  free_pages(per_cpu(thread_imc_mem, cpu), 0);
   865  }
   866  }

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


[PATCH v10 09/10] powerpc/perf: Thread IMC PMU functions

2017-06-08 Thread Madhavan Srinivasan
From: Anju T Sudhakar 

Code to add PMU functions required for event initialization,
read, update, add, del etc. for thread IMC PMU. Thread IMC PMUs are used
for per-task monitoring.

For each CPU, a page of memory is allocated and is kept static i.e.,
these pages will exist till the machine shuts down. The base address of
this page is assigned to the ldbar of that cpu. As soon as we do that,
the thread IMC counters start running for that cpu and the data of these
counters are assigned to the page allocated. But we use this for
per-task monitoring. Whenever we start monitoring a task, the event is
added is onto the task. At that point, we read the initial value of the
event. Whenever, we stop monitoring the task, the final value is taken
and the difference is the event data.

Now, a task can move to a different cpu. Suppose a task X is moving from
cpu A to cpu B. When the task is scheduled out of A, we get an
event_del for A, and hence, the event data is updated. And, we stop
updating the X's event data. As soon as X moves on to B, event_add is
called for B, and we again update the event_data. And this is how it
keeps on updating the event data even when the task is scheduled on to
different cpus.

Signed-off-by: Anju T Sudhakar 
Signed-off-by: Hemant Kumar 
Signed-off-by: Madhavan Srinivasan 
---
 arch/powerpc/include/asm/imc-pmu.h|   4 +
 arch/powerpc/perf/imc-pmu.c   | 219 +-
 arch/powerpc/platforms/powernv/opal-imc.c |   2 +
 3 files changed, 218 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/imc-pmu.h 
b/arch/powerpc/include/asm/imc-pmu.h
index 6659846c21ab..56b2ace565f4 100644
--- a/arch/powerpc/include/asm/imc-pmu.h
+++ b/arch/powerpc/include/asm/imc-pmu.h
@@ -43,6 +43,9 @@
 #define IMC_DTB_COMPAT "ibm,opal-in-memory-counters"
 #define IMC_DTB_UNIT_COMPAT"ibm,imc-counters"
 
+#define THREAD_IMC_LDBAR_MASK   0x0003e000
+#define THREAD_IMC_ENABLE   0x8000
+
 /*
  * Structure to hold memory address information for imc units.
  */
@@ -102,4 +105,5 @@ extern struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS];
 extern struct imc_pmu *core_imc_pmu;
 extern int imc_control(unsigned long type, bool operation);
 extern int __init init_imc_pmu(struct imc_events *events, int idx, struct 
imc_pmu *pmu_ptr);
+void thread_imc_disable(void);
 #endif /* PPC_POWERNV_IMC_PMU_DEF_H */
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index e15a8df3d3b7..ca8c0b8e157a 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -18,6 +18,9 @@
 #include 
 #include 
 
+/* Maintains base address for all the cpus */
+static DEFINE_PER_CPU(u64 *, thread_imc_mem);
+
 /* Needed for sanity check */
 extern u64 nest_max_offset;
 extern u64 core_max_offset;
@@ -39,6 +42,7 @@ static struct cpumask imc_result_mask;
 static DEFINE_MUTEX(imc_control_mutex);
 
 struct imc_pmu *core_imc_pmu;
+static int thread_imc_mem_size;
 
 struct imc_pmu *imc_event_to_pmu(struct perf_event *event)
 {
@@ -317,18 +321,59 @@ bool is_core_imc_mem_inited(int cpu)
 }
 
 /*
- * imc_mem_init : Function to support memory allocation for core imc.
+ * Allocates a page of memory for each of the online cpus, and, writes the
+ * physical base address of that page to the LDBAR for that cpu. This starts
+ * the thread IMC counters.
+ */
+static int thread_imc_mem_alloc(int cpu_id, int size)
+{
+   u64 ldbar_value, *local_mem;
+   int phys_id = topology_physical_package_id(cpu_id);
+
+   if (per_cpu(thread_imc_mem, cpu_id) != NULL)
+   return 0;
+
+   local_mem = alloc_pages_exact_nid(phys_id,
+   (size_t)size, GFP_KERNEL | __GFP_ZERO);
+   if (!local_mem)
+   return -ENOMEM;
+
+   per_cpu(thread_imc_mem, cpu_id) = local_mem;
+
+   ldbar_value = ((u64)local_mem & (u64)THREAD_IMC_LDBAR_MASK) |
+   (u64)THREAD_IMC_ENABLE;
+
+   mtspr(SPRN_LDBAR, ldbar_value);
+   return 0;
+}
+
+/*
+ * imc_mem_init : Function to support memory allocation for core and thread 
imc.
  */
 static int imc_mem_init(struct imc_pmu *pmu_ptr)
 {
-   int nr_cores;
+   int nr_cores, cpu, res;
 
if (pmu_ptr->imc_counter_mmaped)
return 0;
-   nr_cores = num_present_cpus() / threads_per_core;
-   pmu_ptr->mem_info = kzalloc((sizeof(struct imc_mem_info) * nr_cores), 
GFP_KERNEL);
-   if (!pmu_ptr->mem_info)
-   return -ENOMEM;
+   switch (pmu_ptr->domain) {
+   case IMC_DOMAIN_CORE:
+   nr_cores = num_present_cpus() / threads_per_core;
+   pmu_ptr->mem_info = kzalloc((sizeof(struct imc_mem_info) * 
nr_cores), GFP_KERNEL);
+   if (!pmu_ptr->mem_info)
+   return -ENOMEM;
+

[PATCH v10 09/10] powerpc/perf: Thread IMC PMU functions

2017-06-08 Thread Madhavan Srinivasan
From: Anju T Sudhakar 

Code to add PMU functions required for event initialization,
read, update, add, del etc. for thread IMC PMU. Thread IMC PMUs are used
for per-task monitoring.

For each CPU, a page of memory is allocated and is kept static i.e.,
these pages will exist till the machine shuts down. The base address of
this page is assigned to the ldbar of that cpu. As soon as we do that,
the thread IMC counters start running for that cpu and the data of these
counters are assigned to the page allocated. But we use this for
per-task monitoring. Whenever we start monitoring a task, the event is
added is onto the task. At that point, we read the initial value of the
event. Whenever, we stop monitoring the task, the final value is taken
and the difference is the event data.

Now, a task can move to a different cpu. Suppose a task X is moving from
cpu A to cpu B. When the task is scheduled out of A, we get an
event_del for A, and hence, the event data is updated. And, we stop
updating the X's event data. As soon as X moves on to B, event_add is
called for B, and we again update the event_data. And this is how it
keeps on updating the event data even when the task is scheduled on to
different cpus.

Signed-off-by: Anju T Sudhakar 
Signed-off-by: Hemant Kumar 
Signed-off-by: Madhavan Srinivasan 
---
 arch/powerpc/include/asm/imc-pmu.h|   4 +
 arch/powerpc/perf/imc-pmu.c   | 219 +-
 arch/powerpc/platforms/powernv/opal-imc.c |   2 +
 3 files changed, 218 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/imc-pmu.h 
b/arch/powerpc/include/asm/imc-pmu.h
index 6659846c21ab..56b2ace565f4 100644
--- a/arch/powerpc/include/asm/imc-pmu.h
+++ b/arch/powerpc/include/asm/imc-pmu.h
@@ -43,6 +43,9 @@
 #define IMC_DTB_COMPAT "ibm,opal-in-memory-counters"
 #define IMC_DTB_UNIT_COMPAT"ibm,imc-counters"
 
+#define THREAD_IMC_LDBAR_MASK   0x0003e000
+#define THREAD_IMC_ENABLE   0x8000
+
 /*
  * Structure to hold memory address information for imc units.
  */
@@ -102,4 +105,5 @@ extern struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS];
 extern struct imc_pmu *core_imc_pmu;
 extern int imc_control(unsigned long type, bool operation);
 extern int __init init_imc_pmu(struct imc_events *events, int idx, struct 
imc_pmu *pmu_ptr);
+void thread_imc_disable(void);
 #endif /* PPC_POWERNV_IMC_PMU_DEF_H */
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index e15a8df3d3b7..ca8c0b8e157a 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -18,6 +18,9 @@
 #include 
 #include 
 
+/* Maintains base address for all the cpus */
+static DEFINE_PER_CPU(u64 *, thread_imc_mem);
+
 /* Needed for sanity check */
 extern u64 nest_max_offset;
 extern u64 core_max_offset;
@@ -39,6 +42,7 @@ static struct cpumask imc_result_mask;
 static DEFINE_MUTEX(imc_control_mutex);
 
 struct imc_pmu *core_imc_pmu;
+static int thread_imc_mem_size;
 
 struct imc_pmu *imc_event_to_pmu(struct perf_event *event)
 {
@@ -317,18 +321,59 @@ bool is_core_imc_mem_inited(int cpu)
 }
 
 /*
- * imc_mem_init : Function to support memory allocation for core imc.
+ * Allocates a page of memory for each of the online cpus, and, writes the
+ * physical base address of that page to the LDBAR for that cpu. This starts
+ * the thread IMC counters.
+ */
+static int thread_imc_mem_alloc(int cpu_id, int size)
+{
+   u64 ldbar_value, *local_mem;
+   int phys_id = topology_physical_package_id(cpu_id);
+
+   if (per_cpu(thread_imc_mem, cpu_id) != NULL)
+   return 0;
+
+   local_mem = alloc_pages_exact_nid(phys_id,
+   (size_t)size, GFP_KERNEL | __GFP_ZERO);
+   if (!local_mem)
+   return -ENOMEM;
+
+   per_cpu(thread_imc_mem, cpu_id) = local_mem;
+
+   ldbar_value = ((u64)local_mem & (u64)THREAD_IMC_LDBAR_MASK) |
+   (u64)THREAD_IMC_ENABLE;
+
+   mtspr(SPRN_LDBAR, ldbar_value);
+   return 0;
+}
+
+/*
+ * imc_mem_init : Function to support memory allocation for core and thread 
imc.
  */
 static int imc_mem_init(struct imc_pmu *pmu_ptr)
 {
-   int nr_cores;
+   int nr_cores, cpu, res;
 
if (pmu_ptr->imc_counter_mmaped)
return 0;
-   nr_cores = num_present_cpus() / threads_per_core;
-   pmu_ptr->mem_info = kzalloc((sizeof(struct imc_mem_info) * nr_cores), 
GFP_KERNEL);
-   if (!pmu_ptr->mem_info)
-   return -ENOMEM;
+   switch (pmu_ptr->domain) {
+   case IMC_DOMAIN_CORE:
+   nr_cores = num_present_cpus() / threads_per_core;
+   pmu_ptr->mem_info = kzalloc((sizeof(struct imc_mem_info) * 
nr_cores), GFP_KERNEL);
+   if (!pmu_ptr->mem_info)
+   return -ENOMEM;
+   break;
+   case IMC_DOMAIN_THREAD:
+   thread_imc_mem_size =