summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/perf/hv-24x7.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/perf/hv-24x7.c')
-rw-r--r--arch/powerpc/perf/hv-24x7.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
index 141de0f708f7..8b1a3e849d23 100644
--- a/arch/powerpc/perf/hv-24x7.c
+++ b/arch/powerpc/perf/hv-24x7.c
@@ -1144,7 +1144,9 @@ static int add_event_to_24x7_request(struct perf_event *event,
static unsigned long single_24x7_request(struct perf_event *event, u64 *count)
{
+ u16 num_elements;
unsigned long ret;
+ struct hv_24x7_result *result;
struct hv_24x7_request_buffer *request_buffer;
struct hv_24x7_data_result_buffer *result_buffer;
@@ -1166,8 +1168,14 @@ static unsigned long single_24x7_request(struct perf_event *event, u64 *count)
goto out;
}
+ result = result_buffer->results;
+
+ /* This code assumes that a result has only one element. */
+ num_elements = be16_to_cpu(result->num_elements_returned);
+ WARN_ON_ONCE(num_elements != 1);
+
/* process result from hcall */
- *count = be64_to_cpu(result_buffer->results[0].elements[0].element_data[0]);
+ *count = be64_to_cpu(result->elements[0].element_data[0]);
out:
put_cpu_var(hv_24x7_reqb);
@@ -1400,8 +1408,7 @@ static int h_24x7_event_commit_txn(struct pmu *pmu)
{
struct hv_24x7_request_buffer *request_buffer;
struct hv_24x7_data_result_buffer *result_buffer;
- struct hv_24x7_result *resb;
- struct perf_event *event;
+ struct hv_24x7_result *res, *next_res;
u64 count;
int i, ret, txn_flags;
struct hv_24x7_hw *h24x7hw;
@@ -1428,13 +1435,20 @@ static int h_24x7_event_commit_txn(struct pmu *pmu)
h24x7hw = &get_cpu_var(hv_24x7_hw);
- /* Update event counts from hcall */
- for (i = 0; i < request_buffer->num_requests; i++) {
- resb = &result_buffer->results[i];
- count = be64_to_cpu(resb->elements[0].element_data[0]);
- event = h24x7hw->events[i];
- h24x7hw->events[i] = NULL;
+ /* Go through results in the result buffer to update event counts. */
+ for (i = 0, res = result_buffer->results;
+ i < result_buffer->num_results; i++, res = next_res) {
+ struct perf_event *event = h24x7hw->events[res->result_ix];
+ u16 num_elements = be16_to_cpu(res->num_elements_returned);
+ u16 data_size = be16_to_cpu(res->result_element_data_size);
+
+ /* This code assumes that a result has only one element. */
+ WARN_ON_ONCE(num_elements != 1);
+
+ count = be64_to_cpu(res->elements[0].element_data[0]);
update_event_count(event, count);
+
+ next_res = (void *) res->elements[0].element_data + data_size;
}
put_cpu_var(hv_24x7_hw);