@@ -126,7 +126,7 @@ struct papr_scm_priv {
126126 u64 health_bitmap_inject_mask ;
127127
128128 /* array to have event_code and stat_id mappings */
129- char * * nvdimm_events_map ;
129+ u8 * nvdimm_events_map ;
130130};
131131
132132static int papr_scm_pmem_flush (struct nd_region * nd_region ,
@@ -370,7 +370,7 @@ static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev,
370370
371371 stat = & stats -> scm_statistic [0 ];
372372 memcpy (& stat -> stat_id ,
373- p -> nvdimm_events_map [event -> attr .config ],
373+ & p -> nvdimm_events_map [event -> attr .config * sizeof ( stat -> stat_id ) ],
374374 sizeof (stat -> stat_id ));
375375 stat -> stat_val = 0 ;
376376
@@ -462,14 +462,16 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu
462462{
463463 struct papr_scm_perf_stat * stat ;
464464 struct papr_scm_perf_stats * stats ;
465- int index , rc , count ;
466465 u32 available_events ;
466+ int index , rc = 0 ;
467467
468468 if (!p -> stat_buffer_len )
469469 return - ENOENT ;
470470
471471 available_events = (p -> stat_buffer_len - sizeof (struct papr_scm_perf_stats ))
472472 / sizeof (struct papr_scm_perf_stat );
473+ if (available_events == 0 )
474+ return - EOPNOTSUPP ;
473475
474476 /* Allocate the buffer for phyp where stats are written */
475477 stats = kzalloc (p -> stat_buffer_len , GFP_KERNEL );
@@ -478,35 +480,30 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu
478480 return rc ;
479481 }
480482
481- /* Allocate memory to nvdimm_event_map */
482- p -> nvdimm_events_map = kcalloc (available_events , sizeof (char * ), GFP_KERNEL );
483- if (!p -> nvdimm_events_map ) {
484- rc = - ENOMEM ;
485- goto out_stats ;
486- }
487-
488483 /* Called to get list of events supported */
489484 rc = drc_pmem_query_stats (p , stats , 0 );
490485 if (rc )
491- goto out_nvdimm_events_map ;
492-
493- for (index = 0 , stat = stats -> scm_statistic , count = 0 ;
494- index < available_events ; index ++ , ++ stat ) {
495- p -> nvdimm_events_map [count ] = kmemdup_nul (stat -> stat_id , 8 , GFP_KERNEL );
496- if (!p -> nvdimm_events_map [count ]) {
497- rc = - ENOMEM ;
498- goto out_nvdimm_events_map ;
499- }
486+ goto out ;
500487
501- count ++ ;
488+ /*
489+ * Allocate memory and populate nvdimm_event_map.
490+ * Allocate an extra element for NULL entry
491+ */
492+ p -> nvdimm_events_map = kcalloc (available_events + 1 ,
493+ sizeof (stat -> stat_id ),
494+ GFP_KERNEL );
495+ if (!p -> nvdimm_events_map ) {
496+ rc = - ENOMEM ;
497+ goto out ;
502498 }
503- p -> nvdimm_events_map [count ] = NULL ;
504- kfree (stats );
505- return 0 ;
506499
507- out_nvdimm_events_map :
508- kfree (p -> nvdimm_events_map );
509- out_stats :
500+ /* Copy all stat_ids to event map */
501+ for (index = 0 , stat = stats -> scm_statistic ;
502+ index < available_events ; index ++ , ++ stat ) {
503+ memcpy (& p -> nvdimm_events_map [index * sizeof (stat -> stat_id )],
504+ & stat -> stat_id , sizeof (stat -> stat_id ));
505+ }
506+ out :
510507 kfree (stats );
511508 return rc ;
512509}
0 commit comments