Skip to content

Commit

Permalink
powerpc/perf/hv-24x7: Simplify catalog_read()
Browse files Browse the repository at this point in the history
catalog_read() implements the read interface for the sysfs file

	/sys/bus/event_source/devices/hv_24x7/interface/catalog

It essentially takes a buffer, an offset and count as parameters
to the read() call.  It makes a hypervisor call to read a specific
page from the catalog and copy the required bytes into the given
buffer. Each call to catalog_read() returns at most one 4K page.

Given these requirements, we should be able to simplify the
catalog_read().

Signed-off-by: Sukadev Bhattiprolu <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
  • Loading branch information
[email protected] authored and mpe committed Oct 7, 2014
1 parent 48bee8a commit 56f12be
Showing 1 changed file with 14 additions and 87 deletions.
101 changes: 14 additions & 87 deletions arch/powerpc/perf/hv-24x7.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,86 +75,6 @@ static struct attribute_group format_group = {

static struct kmem_cache *hv_page_cache;

/*
* read_offset_data - copy data from one buffer to another while treating the
* source buffer as a small view on the total avaliable
* source data.
*
* @dest: buffer to copy into
* @dest_len: length of @dest in bytes
* @requested_offset: the offset within the source data we want. Must be > 0
* @src: buffer to copy data from
* @src_len: length of @src in bytes
* @source_offset: the offset in the sorce data that (src,src_len) refers to.
* Must be > 0
*
* returns the number of bytes copied.
*
* The following ascii art shows the various buffer possitioning we need to
* handle, assigns some arbitrary varibles to points on the buffer, and then
* shows how we fiddle with those values to get things we care about (copy
* start in src and copy len)
*
* s = @src buffer
* d = @dest buffer
* '.' areas in d are written to.
*
* u
* x w v z
* d |.........|
* s |----------------------|
*
* u
* x w z v
* d |........------|
* s |------------------|
*
* x w u,z,v
* d |........|
* s |------------------|
*
* x,w u,v,z
* d |..................|
* s |------------------|
*
* x u
* w v z
* d |........|
* s |------------------|
*
* x z w v
* d |------|
* s |------|
*
* x = source_offset
* w = requested_offset
* z = source_offset + src_len
* v = requested_offset + dest_len
*
* w_offset_in_s = w - x = requested_offset - source_offset
* z_offset_in_s = z - x = src_len
* v_offset_in_s = v - x = request_offset + dest_len - src_len
*/
static ssize_t read_offset_data(void *dest, size_t dest_len,
loff_t requested_offset, void *src,
size_t src_len, loff_t source_offset)
{
size_t w_offset_in_s = requested_offset - source_offset;
size_t z_offset_in_s = src_len;
size_t v_offset_in_s = requested_offset + dest_len - src_len;
size_t u_offset_in_s = min(z_offset_in_s, v_offset_in_s);
size_t copy_len = u_offset_in_s - w_offset_in_s;

if (requested_offset < 0 || source_offset < 0)
return -EINVAL;

if (z_offset_in_s <= w_offset_in_s)
return 0;

memcpy(dest, src + w_offset_in_s, copy_len);
return copy_len;
}

static unsigned long h_get_24x7_catalog_page_(unsigned long phys_4096,
unsigned long version,
unsigned long index)
Expand Down Expand Up @@ -183,8 +103,10 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
{
unsigned long hret;
ssize_t ret = 0;
size_t catalog_len = 0, catalog_page_len = 0, page_count = 0;
size_t catalog_len = 0, catalog_page_len = 0;
loff_t page_offset = 0;
loff_t offset_in_page;
size_t copy_len;
uint64_t catalog_version_num = 0;
void *page = kmem_cache_alloc(hv_page_cache, GFP_USER);
struct hv_24x7_catalog_page_0 *page_0 = page;
Expand All @@ -202,7 +124,7 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
catalog_len = catalog_page_len * 4096;

page_offset = offset / 4096;
page_count = count / 4096;
offset_in_page = offset % 4096;

if (page_offset >= catalog_page_len)
goto e_free;
Expand All @@ -216,18 +138,23 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
}
}

ret = read_offset_data(buf, count, offset,
page, 4096, page_offset * 4096);
copy_len = 4096 - offset_in_page;
if (copy_len > count)
copy_len = count;

memcpy(buf, page+offset_in_page, copy_len);
ret = copy_len;

e_free:
if (hret)
pr_err("h_get_24x7_catalog_page(ver=%lld, page=%lld) failed:"
" rc=%ld\n",
catalog_version_num, page_offset, hret);
kmem_cache_free(hv_page_cache, page);

pr_devel("catalog_read: offset=%lld(%lld) count=%zu(%zu) catalog_len=%zu(%zu) => %zd\n",
offset, page_offset, count, page_count, catalog_len,
catalog_page_len, ret);
pr_devel("catalog_read: offset=%lld(%lld) count=%zu "
"catalog_len=%zu(%zu) => %zd\n", offset, page_offset,
count, catalog_len, catalog_page_len, ret);

return ret;
}
Expand Down

0 comments on commit 56f12be

Please sign in to comment.