Skip to content

Add changes for invokev2 #134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Docs/images/crc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/images/polling.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/images/polling_perf.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 62 additions & 0 deletions Docs/invoke_v2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Document for invoke_v2

## 1. Introduction
This document provides details about the enhanced invocation invoke_v2 request.

## 2. IOCTL interface
**IOCTL Name**: FASTRPC_IOCTL_INVOKEV2
**Description**: Any enhanced invocation request like CRC, perf counters, polling mode etc. will be made using this ioctl.


## 3. Data Structures

```c
struct fastrpc_ioctl_invoke_v2 {
struct fastrpc_ioctl_invoke inv; /* Invocation struct carrying handle, sc and arg details */
__u64 crc; /* User CRC memory pointer where DSP CRC values will be copied by fastrpc driver */
__u64 poll_timeout; /* Time for which driver will poll on memory */
__u32 reserved[14]; /* Reserved space for future enhancements */
};
```

## 4. CRC
CRC is a debugging feature which can be enabled by users to check for data inconsistencies in remote buffers. If user intends to enable CRC check, first local user CRC is calculated at user end and a CRC buffer is passed to DSP to capture remote CRC values. DSP is expected to write to the remote CRC buffer which is then compared at user level with the local CRC values.

Steps to enable CRC:
export FASTRPC_PROCESS_ATTRS=4

![Design](images/crc.png)

In case CRC is not supported on DSP, it won't result in any fatal failures. Only warning is getting printed for CRC mismatches.

## 5. Polling mode
For any remote call to DSP, after sending an invocation message, fastRPC driver waits for glink response and during this time the CPU can go into low power modes. Adding a polling mode support with which fastRPC driver will poll continuously on a memory after sending a message to remote subsystem which will eliminate CPU wakeup and scheduling latencies and reduce fastRPC overhead. With this change, DSP always sends a glink response which will get ignored if polling mode didn't time out.

Steps to enable polling mode:

** Remote control structure **:
```c
typedef enum remote_rpc_latency_flags {
RPC_DISABLE_QOS = 0,
RPC_PM_QOS,
RPC_ADAPTIVE_QOS,
RPC_POLL_QOS,
} remote_rpc_control_latency_t;

struct remote_rpc_control_latency {
remote_rpc_control_latency_t enable;
uint32_t latency; // Pass expected method execution time on DSP
};
```

** Application code **:
```c
struct remote_rpc_control_latency data;
data.enable = RPC_POLL_QOS;
data.latency = 5000; // Expected 5 ms execution time on DSP
err = remote_handle64_control(h, DSPRPC_CONTROL_LATENCY, (void*)&data, sizeof(data));
```
![Design](images/polling.png)

** Performance comparision **
![Polling performance](images/polling_perf.png)
3 changes: 2 additions & 1 deletion inc/fastrpc_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ struct handle_list {
struct fastrpc_dsp_capabilities cap_info;
int trace_marker_fd;
uint64_t jobid;
uint64_t poll_timeout;
/* Capability flag to check if mapping DMA handle through reverse RPC is supported */
int dma_handle_reverse_rpc_map_capability;
/* Mutex to synchronize ASync init and deinit */
Expand Down Expand Up @@ -541,7 +542,7 @@ int fastrpc_update_module_list(uint32_t req, int domain, remote_handle64 handle,
* @brief functions to wrap ioctl syscalls for downstream and upstream kernel
**/
int ioctl_init(int dev, uint32_t flags, int attr, byte* shell, int shelllen, int shellfd, char* initmem, int initmemlen, int initmemfd, int tessiglen);
int ioctl_invoke(int dev, int req, remote_handle handle, uint32_t sc, void* pra, int* fds, unsigned int* attrs, void *job, unsigned int* crc, uint64_t* perf_kernel, uint64_t* perf_dsp);
int ioctl_invoke(int dev, int req, remote_handle handle, uint32_t sc, void* pra, int* fds, unsigned int* attrs, void *job, unsigned int* crc, uint64_t* perf_kernel, uint64_t* perf_dsp, uint64_t poll_timeout);
int ioctl_invoke2_response(int dev, fastrpc_async_jobid *jobid, remote_handle *handle, uint32_t *sc, int* result, uint64_t *perf_kernel, uint64_t *perf_dsp);
int ioctl_invoke2_notif(int dev, int *domain, int *session, int *status);
int ioctl_mmap(int dev, int req, uint32_t flags, int attr, int fd, int offset, size_t len, uintptr_t vaddrin, uint64_t* vaddr_out);
Expand Down
8 changes: 8 additions & 0 deletions inc/fastrpc_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define FASTRPC_IOCTL_MEM_MAP _IOWR('R', 10, struct fastrpc_ioctl_mem_map)
#define FASTRPC_IOCTL_MEM_UNMAP _IOWR('R', 11, struct fastrpc_ioctl_mem_unmap)
#define FASTRPC_IOCTL_GET_DSP_INFO _IOWR('R', 13, struct fastrpc_ioctl_capability)
#define FASTRPC_IOCTL_INVOKEV2 _IOWR('R', 14, struct fastrpc_ioctl_invoke_v2)

#define ADSPRPC_DEVICE "/dev/fastrpc-adsp"
#define SDSPRPC_DEVICE "/dev/fastrpc-sdsp"
Expand Down Expand Up @@ -110,6 +111,13 @@ struct fastrpc_ioctl_invoke {
__u64 args;
};

struct fastrpc_ioctl_invoke_v2 {
struct fastrpc_ioctl_invoke inv;
__u64 crc;
__u64 poll_timeout;
__u32 reserved[14];
};

struct fastrpc_ioctl_alloc_dma_buf {
__s32 fd; /* fd */
__u32 flags; /* flags to map with */
Expand Down
16 changes: 8 additions & 8 deletions src/fastrpc_apps_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,9 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
req = INVOKE_PERF;
}

if (hlist[domain].poll_timeout)
req = INVOKE_PERF;

if (!IS_STATIC_HANDLE(handle)) {
fastrpc_latency_invoke_incr(&hlist[domain].qos);
if ((rpc_timeout = fastrpc_config_get_rpctimeout()) > 0) {
Expand All @@ -1353,7 +1356,7 @@ int remote_handle_invoke_domain(int domain, remote_handle handle,
}
// Macros are initializing and destroying pfds and pattrs.
nErr = ioctl_invoke(dev, req, handle, sc, get_args(), pfds, pattrs, job,
crc_remote, perf_kernel, perf_dsp);
crc_remote, perf_kernel, perf_dsp, hlist[domain].poll_timeout);
if (nErr) {
nErr = convert_kernel_to_user_error(nErr, errno);
}
Expand Down Expand Up @@ -2080,6 +2083,10 @@ static int manage_poll_qos(int domain, remote_handle64 h, uint32_t enable,
VERIFY(AEE_SUCCESS ==
(nErr = adsp_current_process1_poll_mode(handle, enable, latency)));
}
if (enable)
hlist[domain].poll_timeout = latency;
else
hlist[domain].poll_timeout = 0;
FARF(ALWAYS,
"%s: poll mode updated to %u for domain %d, handle 0x%" PRIx64
" for timeout %u\n",
Expand Down Expand Up @@ -2338,13 +2345,6 @@ int remote_handle_control_domain(int domain, remote_handle64 h, uint32_t req,
case RPC_POLL_QOS: {
VERIFY(AEE_SUCCESS ==
(nErr = manage_poll_qos(domain, h, RPC_POLL_QOS, lp->latency)));

/*
* Poll QoS option also enables PM QoS to enable early response from DSP
* and stop the CPU cores from going into deep sleep low power modes.
*/
VERIFY(AEE_SUCCESS == (nErr = manage_pm_qos(domain, h, RPC_PM_QOS,
POLL_MODE_PM_QOS_LATENCY)));
break;
}
default:
Expand Down
21 changes: 13 additions & 8 deletions src/fastrpc_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,22 @@ int ioctl_init(int dev, uint32_t flags, int attr, byte *shell, int shelllen,

int ioctl_invoke(int dev, int req, remote_handle handle, uint32_t sc, void *pra,
int *fds, unsigned int *attrs, void *job, unsigned int *crc,
uint64_t *perf_kernel, uint64_t *perf_dsp) {
uint64_t *perf_kernel, uint64_t *perf_dsp, uint64_t poll_timeout) {
int ioErr = AEE_SUCCESS;
struct fastrpc_ioctl_invoke invoke = {0};
struct fastrpc_ioctl_invoke_v2 invoke2 = {0};

invoke.handle = handle;
invoke.sc = sc;
invoke.args = (uint64_t)pra;
if (req >= INVOKE && req <= INVOKE_FD)
if (req >= INVOKE && req <= INVOKE_FD) {
ioErr = ioctl(dev, FASTRPC_IOCTL_INVOKE, (unsigned long)&invoke);
else
return AEE_EUNSUPPORTED;
} else {
invoke2.inv = invoke;
invoke2.crc = (uint64_t)crc;
invoke2.poll_timeout = (uint64_t)poll_timeout;
ioErr = ioctl(dev, FASTRPC_IOCTL_INVOKEV2, (unsigned long)&invoke2);
}

return ioErr;
}
Expand Down Expand Up @@ -198,13 +203,13 @@ int ioctl_getdspinfo(int dev, int domain, uint32_t attr, uint32_t *capability) {
}

int ioctl_setmode(int dev, int mode) {
if (mode == FASTRPC_SESSION_ID1)
return AEE_SUCCESS;

return AEE_EUNSUPPORTED;
return AEE_SUCCESS;
}

int ioctl_control(int dev, int req, void *c) {
if (req == DSPRPC_RPC_POLL)
return AEE_SUCCESS;

return AEE_EUNSUPPORTED;
}

Expand Down
Loading