Skip to content

Commit 56f12be

Browse files
sukadev@linux.vnet.ibm.commpe
authored andcommitted
powerpc/perf/hv-24x7: Simplify catalog_read()
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]>
1 parent 48bee8a commit 56f12be

File tree

1 file changed

+14
-87
lines changed

1 file changed

+14
-87
lines changed

arch/powerpc/perf/hv-24x7.c

Lines changed: 14 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -75,86 +75,6 @@ static struct attribute_group format_group = {
7575

7676
static struct kmem_cache *hv_page_cache;
7777

78-
/*
79-
* read_offset_data - copy data from one buffer to another while treating the
80-
* source buffer as a small view on the total avaliable
81-
* source data.
82-
*
83-
* @dest: buffer to copy into
84-
* @dest_len: length of @dest in bytes
85-
* @requested_offset: the offset within the source data we want. Must be > 0
86-
* @src: buffer to copy data from
87-
* @src_len: length of @src in bytes
88-
* @source_offset: the offset in the sorce data that (src,src_len) refers to.
89-
* Must be > 0
90-
*
91-
* returns the number of bytes copied.
92-
*
93-
* The following ascii art shows the various buffer possitioning we need to
94-
* handle, assigns some arbitrary varibles to points on the buffer, and then
95-
* shows how we fiddle with those values to get things we care about (copy
96-
* start in src and copy len)
97-
*
98-
* s = @src buffer
99-
* d = @dest buffer
100-
* '.' areas in d are written to.
101-
*
102-
* u
103-
* x w v z
104-
* d |.........|
105-
* s |----------------------|
106-
*
107-
* u
108-
* x w z v
109-
* d |........------|
110-
* s |------------------|
111-
*
112-
* x w u,z,v
113-
* d |........|
114-
* s |------------------|
115-
*
116-
* x,w u,v,z
117-
* d |..................|
118-
* s |------------------|
119-
*
120-
* x u
121-
* w v z
122-
* d |........|
123-
* s |------------------|
124-
*
125-
* x z w v
126-
* d |------|
127-
* s |------|
128-
*
129-
* x = source_offset
130-
* w = requested_offset
131-
* z = source_offset + src_len
132-
* v = requested_offset + dest_len
133-
*
134-
* w_offset_in_s = w - x = requested_offset - source_offset
135-
* z_offset_in_s = z - x = src_len
136-
* v_offset_in_s = v - x = request_offset + dest_len - src_len
137-
*/
138-
static ssize_t read_offset_data(void *dest, size_t dest_len,
139-
loff_t requested_offset, void *src,
140-
size_t src_len, loff_t source_offset)
141-
{
142-
size_t w_offset_in_s = requested_offset - source_offset;
143-
size_t z_offset_in_s = src_len;
144-
size_t v_offset_in_s = requested_offset + dest_len - src_len;
145-
size_t u_offset_in_s = min(z_offset_in_s, v_offset_in_s);
146-
size_t copy_len = u_offset_in_s - w_offset_in_s;
147-
148-
if (requested_offset < 0 || source_offset < 0)
149-
return -EINVAL;
150-
151-
if (z_offset_in_s <= w_offset_in_s)
152-
return 0;
153-
154-
memcpy(dest, src + w_offset_in_s, copy_len);
155-
return copy_len;
156-
}
157-
15878
static unsigned long h_get_24x7_catalog_page_(unsigned long phys_4096,
15979
unsigned long version,
16080
unsigned long index)
@@ -183,8 +103,10 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
183103
{
184104
unsigned long hret;
185105
ssize_t ret = 0;
186-
size_t catalog_len = 0, catalog_page_len = 0, page_count = 0;
106+
size_t catalog_len = 0, catalog_page_len = 0;
187107
loff_t page_offset = 0;
108+
loff_t offset_in_page;
109+
size_t copy_len;
188110
uint64_t catalog_version_num = 0;
189111
void *page = kmem_cache_alloc(hv_page_cache, GFP_USER);
190112
struct hv_24x7_catalog_page_0 *page_0 = page;
@@ -202,7 +124,7 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
202124
catalog_len = catalog_page_len * 4096;
203125

204126
page_offset = offset / 4096;
205-
page_count = count / 4096;
127+
offset_in_page = offset % 4096;
206128

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

219-
ret = read_offset_data(buf, count, offset,
220-
page, 4096, page_offset * 4096);
141+
copy_len = 4096 - offset_in_page;
142+
if (copy_len > count)
143+
copy_len = count;
144+
145+
memcpy(buf, page+offset_in_page, copy_len);
146+
ret = copy_len;
147+
221148
e_free:
222149
if (hret)
223150
pr_err("h_get_24x7_catalog_page(ver=%lld, page=%lld) failed:"
224151
" rc=%ld\n",
225152
catalog_version_num, page_offset, hret);
226153
kmem_cache_free(hv_page_cache, page);
227154

228-
pr_devel("catalog_read: offset=%lld(%lld) count=%zu(%zu) catalog_len=%zu(%zu) => %zd\n",
229-
offset, page_offset, count, page_count, catalog_len,
230-
catalog_page_len, ret);
155+
pr_devel("catalog_read: offset=%lld(%lld) count=%zu "
156+
"catalog_len=%zu(%zu) => %zd\n", offset, page_offset,
157+
count, catalog_len, catalog_page_len, ret);
231158

232159
return ret;
233160
}

0 commit comments

Comments
 (0)