We currently issue a new hcall for to retrieve the value of each 24x7
counter that we want to read. However, the H_GET_24x7_DATA hcall can
retrieve several counters in a single call, which would be useful in
getting a more consistent snapshot of the system.
Reorganize the code that prepares a 24x7 hcall request, submits it and
processes the result to allow reading seveal counters at once. We still
submit a fresh hcall for each event for now. A follow-on patch-set will
build on this to submit multiple perf_events in a single hcall.
Thanks to Peter Zijlstra for his input.
Sukadev Bhattiprolu (9):
powerpc/perf: hv-24x7: Modify definition of request and result buffers
powerpc: perf/hv24x7: Remove unnecessary parameter
powerpc: perf/hv-24x7: Drop event_24x7_request()
powerpc: perf/hv24x7: Move debug prints to separate function
perf: powerpc/hv-24x7: Rename hv_24x7_event_update
powerpc: perf/hv-24x7: Define add_event_to_24x7_request()
powerpc: perf/hv-24x7: Define update_event_count()
powerpc: perf/hv-24x7: Break up single_24x7_request
powerpc: perf/hv-24x7: Add missing put_cpu_var()
arch/powerpc/perf/hv-24x7.c | 198 ++++++++++++++++++++++++++++----------------
arch/powerpc/perf/hv-24x7.h | 8 +-
2 files changed, 130 insertions(+), 76 deletions(-)
--
1.8.3.1
The function event_24x7_request() is essentially a wrapper to the
function single_24x7_request() and can be dropped to simplify code.
Signed-off-by: Sukadev Bhattiprolu <redacted>
---
arch/powerpc/perf/hv-24x7.c | 41 ++++++++++++++++-------------------------
1 file changed, 16 insertions(+), 25 deletions(-)
@@ -1126,7 +1117,7 @@ static int h_24x7_event_init(struct perf_event *event)}/* see if the event complains */-if(event_24x7_request(event,&ct)){+if(single_24x7_request(event,&ct)){pr_devel("test hcall failed\n");return-EIO;}
@@ -1138,7 +1129,7 @@ static u64 h_24x7_get_value(struct perf_event *event){unsignedlongret;u64ct;-ret=event_24x7_request(event,&ct);+ret=single_24x7_request(event,&ct);if(ret)/* We checked this in event init, shouldn't fail here... */return0;
@@ -1130,7 +1126,7 @@ static int h_24x7_event_init(struct perf_event *event)}/* see if the event complains */-if(event_24x7_request(event,&ct,false)){+if(event_24x7_request(event,&ct)){pr_devel("test hcall failed\n");return-EIO;}
@@ -1142,7 +1138,7 @@ static u64 h_24x7_get_value(struct perf_event *event){unsignedlongret;u64ct;-ret=event_24x7_request(event,&ct,true);+ret=event_24x7_request(event,&ct);if(ret)/* We checked this in event init, shouldn't fail here... */return0;
Break up the function single_24x7_request() into smaller functions.
This would later enable us to "prepare" a multi-event request
buffer and then submit a single hcall for several events.
Signed-off-by: Sukadev Bhattiprolu <redacted>
---
arch/powerpc/perf/hv-24x7.c | 56 +++++++++++++++++++++++++++++++++------------
1 file changed, 42 insertions(+), 14 deletions(-)
@@ -1001,6 +1001,44 @@ static void log_24x7_hcall(struct hv_24x7_request_buffer *request_buffer,}/*+*StarttheprocessforanewH_GET_24x7_DATAhcall.+*/+staticvoidstart_24x7_get_data(structhv_24x7_request_buffer*request_buffer,+structhv_24x7_data_result_buffer*result_buffer)+{++memset(request_buffer,0,4096);+memset(result_buffer,0,4096);++request_buffer->interface_version=HV_24X7_IF_VERSION_CURRENT;+/* memset above set request_buffer->num_requests to 0 */+}++/*+*Commit(i.eperform)theH_GET_24x7_DATAhcallusingthedatacollected+*by'start_24x7_get_data()'and'add_event_to_24x7_request()'.+*/+staticintcommit_24x7_get_data(structhv_24x7_request_buffer*request_buffer,+structhv_24x7_data_result_buffer*result_buffer)+{+unsignedlongret;++/*+*NOTE:Duetovariablenumberofarrayelementsinrequestand+*resultbuffer(s),sizeof()isnotreliable.Usetheactual+*allocatedbuffersize,H24x7_DATA_BUFFER_SIZE.+*/+ret=plpar_hcall_norets(H_GET_24X7_DATA,+virt_to_phys(request_buffer),H24x7_DATA_BUFFER_SIZE,+virt_to_phys(result_buffer),H24x7_DATA_BUFFER_SIZE);++if(ret)+log_24x7_hcall(request_buffer,result_buffer,ret);++returnret;+}++/**Addthegiven@eventtothenextslotinthe24x7request_buffer.**NotethatH_GET_24X7_DATAhcallallowsreadingseveralcounters'
@@ -1042,7 +1080,6 @@ static int add_event_to_24x7_request(struct perf_event *event,staticunsignedlongsingle_24x7_request(structperf_event*event,u64*count){unsignedlongret;-structhv_24x7_request_buffer*request_buffer;structhv_24x7_data_result_buffer*result_buffer;structhv_24x7_result*resb;
@@ -1053,31 +1090,22 @@ static unsigned long single_24x7_request(struct perf_event *event, u64 *count)request_buffer=(void*)get_cpu_var(hv_24x7_reqb);result_buffer=(void*)get_cpu_var(hv_24x7_resb);-memset(request_buffer,0,4096);-memset(result_buffer,0,4096);--request_buffer->interface_version=HV_24X7_IF_VERSION_CURRENT;+start_24x7_get_data(request_buffer,result_buffer);ret=add_event_to_24x7_request(event,request_buffer);if(ret)returnret;-/*-*NOTE:Duetovariablenumberofarrayelementsinrequestand-*resultbuffer(s),sizeof()isnotreliable.Usetheactual-*allocatedbuffersize,H24x7_DATA_BUFFER_SIZE.-*/-ret=plpar_hcall_norets(H_GET_24X7_DATA,-virt_to_phys(request_buffer),H24x7_DATA_BUFFER_SIZE,-virt_to_phys(result_buffer),H24x7_DATA_BUFFER_SIZE);-+ret=commit_24x7_get_data(request_buffer,result_buffer);if(ret){log_24x7_hcall(request_buffer,result_buffer,ret);gotoout;}+/* process result from hcall */resb=&result_buffer->results[0];*count=be64_to_cpu(resb->elements[0].element_data[0]);+out:returnret;}
Move the code to update an event count into a new function,
update_event_count().
Signed-off-by: Sukadev Bhattiprolu <redacted>
---
arch/powerpc/perf/hv-24x7.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
For consistency with the pmu operation ->read() and with other
pmus, rename hv_24x7_event_update() to hv_24x7_event_read().
Signed-off-by: Sukadev Bhattiprolu <redacted>
---
arch/powerpc/perf/hv-24x7.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
To simplify/cleanup code, move the rather long printk() to a separate
function.
Signed-off-by: Sukadev Bhattiprolu <redacted>
---
arch/powerpc/perf/hv-24x7.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
Move code that maps a perf_event to a 24x7 request buffer into a
separate function, add_event_to_24x7_request().
Signed-off-by: Sukadev Bhattiprolu <redacted>
---
arch/powerpc/perf/hv-24x7.c | 61 ++++++++++++++++++++++++++++++++-------------
1 file changed, 43 insertions(+), 18 deletions(-)
The parameters to the 24x7 HCALL have variable number of elements in them.
Set the minimum number of such elements to 1 rather than 0 and eliminate
the temporary structures.
This would enable us to submit multiple counter requests and process
multiple results from a single HCALL (in a follow on patch).
Signed-off-by: Sukadev Bhattiprolu <redacted>
---
arch/powerpc/perf/hv-24x7.c | 77 ++++++++++++++++++++++-----------------------
arch/powerpc/perf/hv-24x7.h | 8 ++---
2 files changed, 41 insertions(+), 44 deletions(-)
@@ -87,7 +87,7 @@ struct hv_24x7_result {/* WARNING: only valid for first result element due to variable sizes*ofresultelements*//* struct hv_24x7_result_element[@num_elements_returned] */-structhv_24x7_result_elementelements[];+structhv_24x7_result_elementelements[1];}__packed;structhv_24x7_data_result_buffer{
@@ -103,7 +103,7 @@ struct hv_24x7_data_result_buffer {__u8reserved2[0x8];/* WARNING: only valid for the first result due to variable sizes of*results*/-structhv_24x7_resultresults[];/* [@num_results] */+structhv_24x7_resultresults[1];/* [@num_results] */}__packed;#endif
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2015-03-17 00:13:55
On Tue, 2015-17-02 at 22:00:27 UTC, Sukadev Bhattiprolu wrote:
Use pr_notice_ratelimited() to log error messages and remove
the 'success_expected' parameter.
I don't understand how this is equivalent?
The current code uses success_expected to indicate that once it's done the
request once and found that it works, it then expects the request to continue
working, and if it doesn't then that is an error.
Using pr_ratelimited() will do the opposite, ie. the first failure will print a
message, but that may not really indicate an error, it may just be a badly
configured request.
Or at least that's how I understand it, please convince me I'm wrong :)
cheers
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2015-03-17 02:24:00
On Tue, 2015-17-02 at 22:00:33 UTC, Sukadev Bhattiprolu wrote:
Break up the function single_24x7_request() into smaller functions.
This would later enable us to "prepare" a multi-event request
buffer and then submit a single hcall for several events.
This looks fine, though the names are a bit laboured.
Michael Ellerman [mpe@ellerman.id.au] wrote:
| On Tue, 2015-17-02 at 22:00:34 UTC, Sukadev Bhattiprolu wrote:
| > Add missing put_cpu_var() for 24x7 requests.
|
| When did it go missing? I assume in upstream, in which case this should be a
| separate patch which I could merge for 4.0.
It went missing in 3.18-rc3 (commit f34b6c7). I will resend this
separately.
Sukadev
Michael Ellerman [mpe@ellerman.id.au] wrote:
| On Tue, 2015-17-02 at 22:00:27 UTC, Sukadev Bhattiprolu wrote:
| > Use pr_notice_ratelimited() to log error messages and remove
| > the 'success_expected' parameter.
|
| I don't understand how this is equivalent?
They are two unrelated changes that I should have separated.
|
| The current code uses success_expected to indicate that once it's done the
| request once and found that it works, it then expects the request to continue
| working, and if it doesn't then that is an error.
The current code is using success_expected to _not_ log an error if
that initial request fails. i.e we silently return -EIO here.
I think the 'success_expected' parameter is not really necessary.
We can simply log the message even for that initial request.
And we can log it a lower priority than KERN_ERR since the message
is mostly for developers rather than users who would use event names
(which encode/abstract the domain and offset values).
|
| Using pr_ratelimited() will do the opposite, ie. the first failure will print a
| message, but that may not really indicate an error, it may just be a badly
| configured request.
|
| Or at least that's how I understand it, please convince me I'm wrong :)
|
| cheers
| _______________________________________________
| Linuxppc-dev mailing list
| Linuxppc-dev@lists.ozlabs.org
| https://lists.ozlabs.org/listinfo/linuxppc-dev