Skip to content

Commit 9bd3450

Browse files
nchatradsrgovard
authored andcommitted
misc: apml_sbtsi: Optimize TBAI trace buffer acquisition
This patch optimizes the TBAI (Trace Buffer Acquisition Interface) protocol implementation in the APML SB-TSI driver with the following improvements: - Replace multiple memory allocations with single allocation for the entire user-requested buffer size to reduce overhead and improve performance - Consolidate data copying using memcpy() instead of fragmented operations to transfer data to user structure efficiently - Replace magic numbers (0, 1, 2, 3) with descriptive TBAI_INPUT_*_INDEX macros to improve code readability and maintainability These changes enhance memory efficiency and code clarity while maintaining the same functional behavior of the trace buffer acquisition process. Signed-off-by: Akshay Gupta <Akshay.Gupta@amd.com> Signed-off-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
1 parent 7934d77 commit 9bd3450

File tree

1 file changed

+36
-37
lines changed

1 file changed

+36
-37
lines changed

drivers/misc/amd-apml/apml_sbtsi.c

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@
4444
#define TBAI_FLUSH_RD_LEN 0x4 /* flush buffer read length */
4545
#define MAX_PROTO_RD_SZ 32 /* Maximum bytes read in one transaction */
4646
#define DWORD_TO_BYTES 0x4 /* Number of bytes in dword */
47+
48+
/* TBAI Input structure index */
49+
#define TBAI_IN_LUT_INDEX 0 /* LUT index */
50+
#define TBAI_IN_OFF_LO 1 /* Low offset index */
51+
#define TBAI_IN_OFF_HI 2 /* Hi offset index */
52+
#define TBAI_IN_DWORD_COUNT 3 /* Number of Dwords index */
53+
4754
/* Maximum dwords possible to read in one transaction */
4855
#define MAX_DWORDS_READ 0x8
4956

@@ -260,43 +267,48 @@ static int tbai_protocol(struct apml_sbtsi_device *tsi_dev, u8 cmd, u8 *input,
260267

261268
static int flush_trace_buffer(struct apml_sbtsi_device *tsi_dev, struct apml_tbai_msg *tbai_msg)
262269
{
263-
u8 input[4] = {0};
264-
u8 output[4] = {0};
265-
int ret, i;
270+
u8 input[TBAI_WR_LEN] = {0};
271+
u8 output[TBAI_FLUSH_RD_LEN] = {0};
272+
int ret;
266273

267-
ret = tbai_protocol(tsi_dev, tbai_msg->reg_in[TBAI_CMD_INDEX], input, 4, output);
274+
ret = tbai_protocol(tsi_dev, tbai_msg->reg_in[TBAI_CMD_INDEX], input,
275+
TBAI_FLUSH_RD_LEN, output);
268276
if (ret)
269277
return ret;
270-
for (i = 0; i < TBAI_FLUSH_RD_LEN; i++)
271-
tbai_msg->data_out.bytes_out[i] = output[i];
278+
279+
memcpy(tbai_msg->data_out.bytes_out, output, TBAI_FLUSH_RD_LEN);
272280
return ret;
273281
}
274282

275283
static int acquire_trace_buffer(struct apml_sbtsi_device *tsi_dev, struct apml_tbai_msg *tbai_msg)
276284
{
277-
int dword_read, dword_remain, i, j, ret;
285+
int dword_read, dword_remain, i, ret;
286+
u32 total_dwords;
278287
u16 offset, offset_new;
279288
u8 input[TBAI_WR_LEN] = {0};
280-
/* TODO: static memory as max supported is 8 Dwords */
281289
u8 *output;
282290

283291
/* Dwords to read from user*/
284-
dword_remain = tbai_msg->reg_in[TBAI_DWORD_RD_INDEX];
292+
total_dwords = tbai_msg->reg_in[TBAI_DWORD_RD_INDEX];
293+
dword_remain = total_dwords;
285294
/* Extract the offset to update, if more than 8 Dwords require to read */
286295
offset = tbai_msg->reg_in[TBAI_OFFSET_HI] << 8 |
287296
tbai_msg->reg_in[TBAI_OFFSET_LO];
288297

289298
/* If Dwords to read is 0 or more than 32, return */
290-
if (tbai_msg->reg_in[TBAI_DWORD_RD_INDEX] == 0 ||
291-
tbai_msg->reg_in[TBAI_DWORD_RD_INDEX] > MAX_TBAI_DWORDS)
299+
if (total_dwords == 0 || total_dwords > MAX_TBAI_DWORDS)
292300
return -EINVAL;
293301

302+
/* Allocate memory at once for all dwords to be read */
303+
output = kcalloc(total_dwords * DWORD_TO_BYTES, sizeof(u8), GFP_KERNEL);
304+
if (!output)
305+
return -ENOMEM;
306+
294307
/*
295308
* Set required variables to read dwords
296309
* Maximum dwords supported from i3c protocol is 8
297310
*/
298-
for (i = 0; i <= tbai_msg->reg_in[TBAI_DWORD_RD_INDEX] / 8 &&
299-
dword_remain > 0; i++) {
311+
for (i = 0; i <= total_dwords / MAX_DWORDS_READ && dword_remain > 0; i++) {
300312
if (dword_remain > MAX_DWORDS_READ) {
301313
dword_remain -= MAX_DWORDS_READ;
302314
dword_read = MAX_DWORDS_READ;
@@ -306,36 +318,23 @@ static int acquire_trace_buffer(struct apml_sbtsi_device *tsi_dev, struct apml_t
306318
}
307319
/* update offset if more than 8 Dwords require to read */
308320
offset_new = i * MAX_PROTO_RD_SZ + offset;
309-
input[0] = tbai_msg->reg_in[TBAI_LUT_INDEX];
310-
input[1] = offset_new & 0xFF;
311-
input[2] = (offset_new >> 8) & 0xFF;
312-
input[3] = dword_read - 1;
321+
input[TBAI_IN_LUT_INDEX] = tbai_msg->reg_in[TBAI_LUT_INDEX];
322+
input[TBAI_IN_OFF_LO] = offset_new & 0xFF;
323+
input[TBAI_IN_OFF_HI] = (offset_new >> 8) & 0xFF;
324+
input[TBAI_IN_DWORD_COUNT] = dword_read - 1;
313325

314-
/*
315-
* TODO: Optimize to allocate memory at once as per user request
316-
* Currently in A0, only one Dword can be read, due to bug.
317-
* Optimize in B0.
318-
*/
319-
output = kcalloc(dword_read * DWORD_TO_BYTES, sizeof(u8), GFP_KERNEL);
320-
if (!output)
321-
return -ENOMEM;
322-
323-
ret = tbai_protocol(tsi_dev, tbai_msg->reg_in[TBAI_CMD_INDEX],
324-
input, dword_read * DWORD_TO_BYTES, output);
326+
ret = tbai_protocol(tsi_dev, tbai_msg->reg_in[TBAI_CMD_INDEX], input,
327+
dword_read * DWORD_TO_BYTES, &output[i * MAX_PROTO_RD_SZ]);
325328
if (ret) {
326329
kfree(output);
327330
return ret;
328331
}
329-
for (j = 0; j < dword_read * DWORD_TO_BYTES; j++) {
330-
/*
331-
* TODO: In A0, only one Dword is supported
332-
* APML module is optimized to read max of 32 Dwords at a time.
333-
* dwords exceeding 8 need to be tested in B0 platform.
334-
*/
335-
tbai_msg->data_out.bytes_out[j + (i * MAX_PROTO_RD_SZ)] = output[j];
336-
}
337-
kfree(output);
338332
}
333+
334+
/* Copy data to user */
335+
memcpy(tbai_msg->data_out.bytes_out, output, total_dwords * DWORD_TO_BYTES);
336+
kfree(output);
337+
339338
return 0;
340339
}
341340

0 commit comments

Comments
 (0)