mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-10 07:50:04 +00:00
powerpc/perf/hv-24x7: Modify definition of request and result buffers
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 <sukadev@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
ed59190e41
commit
145264e212
@ -142,6 +142,15 @@ static struct attribute_group event_long_desc_group = {
|
|||||||
|
|
||||||
static struct kmem_cache *hv_page_cache;
|
static struct kmem_cache *hv_page_cache;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* request_buffer and result_buffer are not required to be 4k aligned,
|
||||||
|
* but are not allowed to cross any 4k boundary. Aligning them to 4k is
|
||||||
|
* the simplest way to ensure that.
|
||||||
|
*/
|
||||||
|
#define H24x7_DATA_BUFFER_SIZE 4096
|
||||||
|
DEFINE_PER_CPU(char, hv_24x7_reqb[H24x7_DATA_BUFFER_SIZE]) __aligned(4096);
|
||||||
|
DEFINE_PER_CPU(char, hv_24x7_resb[H24x7_DATA_BUFFER_SIZE]) __aligned(4096);
|
||||||
|
|
||||||
static char *event_name(struct hv_24x7_event_data *ev, int *len)
|
static char *event_name(struct hv_24x7_event_data *ev, int *len)
|
||||||
{
|
{
|
||||||
*len = be16_to_cpu(ev->event_name_len) - 2;
|
*len = be16_to_cpu(ev->event_name_len) - 2;
|
||||||
@ -976,31 +985,16 @@ static const struct attribute_group *attr_groups[] = {
|
|||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_PER_CPU(char, hv_24x7_reqb[4096]) __aligned(4096);
|
|
||||||
DEFINE_PER_CPU(char, hv_24x7_resb[4096]) __aligned(4096);
|
|
||||||
|
|
||||||
static unsigned long single_24x7_request(u8 domain, u32 offset, u16 ix,
|
static unsigned long single_24x7_request(u8 domain, u32 offset, u16 ix,
|
||||||
u16 lpar, u64 *res,
|
u16 lpar, u64 *count,
|
||||||
bool success_expected)
|
bool success_expected)
|
||||||
{
|
{
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
|
|
||||||
/*
|
struct hv_24x7_request_buffer *request_buffer;
|
||||||
* request_buffer and result_buffer are not required to be 4k aligned,
|
struct hv_24x7_data_result_buffer *result_buffer;
|
||||||
* but are not allowed to cross any 4k boundary. Aligning them to 4k is
|
struct hv_24x7_result *resb;
|
||||||
* the simplest way to ensure that.
|
struct hv_24x7_request *req;
|
||||||
*/
|
|
||||||
struct reqb {
|
|
||||||
struct hv_24x7_request_buffer buf;
|
|
||||||
struct hv_24x7_request req;
|
|
||||||
} __packed *request_buffer;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct hv_24x7_data_result_buffer buf;
|
|
||||||
struct hv_24x7_result res;
|
|
||||||
struct hv_24x7_result_element elem;
|
|
||||||
__be64 result;
|
|
||||||
} __packed *result_buffer;
|
|
||||||
|
|
||||||
BUILD_BUG_ON(sizeof(*request_buffer) > 4096);
|
BUILD_BUG_ON(sizeof(*request_buffer) > 4096);
|
||||||
BUILD_BUG_ON(sizeof(*result_buffer) > 4096);
|
BUILD_BUG_ON(sizeof(*result_buffer) > 4096);
|
||||||
@ -1011,38 +1005,41 @@ static unsigned long single_24x7_request(u8 domain, u32 offset, u16 ix,
|
|||||||
memset(request_buffer, 0, 4096);
|
memset(request_buffer, 0, 4096);
|
||||||
memset(result_buffer, 0, 4096);
|
memset(result_buffer, 0, 4096);
|
||||||
|
|
||||||
*request_buffer = (struct reqb) {
|
request_buffer->interface_version = HV_24X7_IF_VERSION_CURRENT;
|
||||||
.buf = {
|
request_buffer->num_requests = 1;
|
||||||
.interface_version = HV_24X7_IF_VERSION_CURRENT,
|
|
||||||
.num_requests = 1,
|
|
||||||
},
|
|
||||||
.req = {
|
|
||||||
.performance_domain = domain,
|
|
||||||
.data_size = cpu_to_be16(8),
|
|
||||||
.data_offset = cpu_to_be32(offset),
|
|
||||||
.starting_lpar_ix = cpu_to_be16(lpar),
|
|
||||||
.max_num_lpars = cpu_to_be16(1),
|
|
||||||
.starting_ix = cpu_to_be16(ix),
|
|
||||||
.max_ix = cpu_to_be16(1),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
req = &request_buffer->requests[0];
|
||||||
|
|
||||||
|
req->performance_domain = domain;
|
||||||
|
req->data_size = cpu_to_be16(8);
|
||||||
|
req->data_offset = cpu_to_be32(offset);
|
||||||
|
req->starting_lpar_ix = cpu_to_be16(lpar),
|
||||||
|
req->max_num_lpars = cpu_to_be16(1);
|
||||||
|
req->starting_ix = cpu_to_be16(ix);
|
||||||
|
req->max_ix = cpu_to_be16(1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: Due to variable number of array elements in request and
|
||||||
|
* result buffer(s), sizeof() is not reliable. Use the actual
|
||||||
|
* allocated buffer size, H24x7_DATA_BUFFER_SIZE.
|
||||||
|
*/
|
||||||
ret = plpar_hcall_norets(H_GET_24X7_DATA,
|
ret = plpar_hcall_norets(H_GET_24X7_DATA,
|
||||||
virt_to_phys(request_buffer), sizeof(*request_buffer),
|
virt_to_phys(request_buffer), H24x7_DATA_BUFFER_SIZE,
|
||||||
virt_to_phys(result_buffer), sizeof(*result_buffer));
|
virt_to_phys(result_buffer), H24x7_DATA_BUFFER_SIZE);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (success_expected)
|
if (success_expected)
|
||||||
pr_err_ratelimited("hcall failed: %d %#x %#x %d => "
|
pr_err_ratelimited("hcall failed: %d %#x %#x %d => "
|
||||||
"0x%lx (%ld) detail=0x%x failing ix=%x\n",
|
"0x%lx (%ld) detail=0x%x failing ix=%x\n",
|
||||||
domain, offset, ix, lpar, ret, ret,
|
domain, offset, ix, lpar, ret, ret,
|
||||||
result_buffer->buf.detailed_rc,
|
result_buffer->detailed_rc,
|
||||||
result_buffer->buf.failing_request_ix);
|
result_buffer->failing_request_ix);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
*res = be64_to_cpu(result_buffer->result);
|
resb = &result_buffer->results[0];
|
||||||
|
|
||||||
|
*count = be64_to_cpu(resb->elements[0].element_data[0]);
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ struct hv_24x7_request_buffer {
|
|||||||
__u8 interface_version;
|
__u8 interface_version;
|
||||||
__u8 num_requests;
|
__u8 num_requests;
|
||||||
__u8 reserved[0xE];
|
__u8 reserved[0xE];
|
||||||
struct hv_24x7_request requests[];
|
struct hv_24x7_request requests[1];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct hv_24x7_result_element {
|
struct hv_24x7_result_element {
|
||||||
@ -66,7 +66,7 @@ struct hv_24x7_result_element {
|
|||||||
__be32 lpar_cfg_instance_id;
|
__be32 lpar_cfg_instance_id;
|
||||||
|
|
||||||
/* size = @result_element_data_size of cointaining result. */
|
/* size = @result_element_data_size of cointaining result. */
|
||||||
__u8 element_data[];
|
__u64 element_data[1];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct hv_24x7_result {
|
struct hv_24x7_result {
|
||||||
@ -87,7 +87,7 @@ struct hv_24x7_result {
|
|||||||
/* WARNING: only valid for first result element due to variable sizes
|
/* WARNING: only valid for first result element due to variable sizes
|
||||||
* of result elements */
|
* of result elements */
|
||||||
/* struct hv_24x7_result_element[@num_elements_returned] */
|
/* struct hv_24x7_result_element[@num_elements_returned] */
|
||||||
struct hv_24x7_result_element elements[];
|
struct hv_24x7_result_element elements[1];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct hv_24x7_data_result_buffer {
|
struct hv_24x7_data_result_buffer {
|
||||||
@ -103,7 +103,7 @@ struct hv_24x7_data_result_buffer {
|
|||||||
__u8 reserved2[0x8];
|
__u8 reserved2[0x8];
|
||||||
/* WARNING: only valid for the first result due to variable sizes of
|
/* WARNING: only valid for the first result due to variable sizes of
|
||||||
* results */
|
* results */
|
||||||
struct hv_24x7_result results[]; /* [@num_results] */
|
struct hv_24x7_result results[1]; /* [@num_results] */
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user