diff options
| -rw-r--r-- | arch/powerpc/perf/hv-24x7.c | 32 | 
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);  | 
