Re: [PATCH v1 1/4] misc: fastrpc: Add CRC support using invokeV2 request

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Jan 23, 2025 at 05:34:00PM +0530, Ekansh Gupta wrote:
> 
> 
> 
> On 1/23/2025 4:43 PM, Dmitry Baryshkov wrote:
> > On Thu, Jan 23, 2025 at 03:19:21PM +0530, Ekansh Gupta wrote:
> >>
> >>
> >> On 1/23/2025 1:18 PM, Dmitry Baryshkov wrote:
> >>> On Thu, Jan 23, 2025 at 11:16:41AM +0530, Ekansh Gupta wrote:
> >>>>
> >>>> On 10/7/2024 7:27 PM, Dmitry Baryshkov wrote:
> >>>>> On Mon, Oct 07, 2024 at 02:15:15PM GMT, Ekansh Gupta wrote:
> >>>>>> InvokeV2 request is intended to support multiple enhanced invoke
> >>>>>> requests like CRC check, performance counter enablement and polling
> >>>>>> mode for RPC invocations. CRC check is getting enabled as part of
> >>>>>> this patch. CRC check for input and output argument helps in ensuring
> >>>>>> data consistency over a remote call. 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.
> >>>>> This doesn't explain why this is necessary. Why do you need to checksum
> >>>>> arguments?
> >>>> This helps if the user suspects any data inconsistencies in the buffers passed to DSP over
> >>>> remote call. This is not enabled by default and user can enable it as per their reqirement.
> >>>> I'll add this information.
> >>> An inconsistency where? Between the kernel and the DSP? Between the user
> >>> and the DSP? Does it cover buffer contents or just the addresses?
> >> Inconsistency between user and DSP. crc_user is calculated at user library before
> >> making ioctl call and it is compared against the crc data which is filled by DSP and
> >> copied to user.
> >> This covers inconsistency in buffer contents.
> > What is the reason for possible inconsistencies? Is it a debugging
> > feature?
> This is a debugging feature. Buffer data corruption might result in inconsistency.
> >
> >>>>> Also, what if the DSP firmware doesn't support CRC? How should userspace
> >>>>> know that?
> >>>> CRC support on DSP is there since long time(>6years).
> >>> This doesn't give us a lot. Upstream kernel supports fastrpc since
> >>> MSM8916 and MSM8996. Do those platforms support CRC?
> >> The metadata buffer as of today also carries space for CRC information:
> >> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/misc/fastrpc.c#n877
> >>
> >> So this is common across all platforms.
> >>
> >> In case CRC is not supported on any older platform, it would result in crc mismatch at user library.
> >> As of now a warning is getting logged there, I can add the information suggesting the failure might
> >> also occur if CRC is not supported.
> > Logs go to /dev/null, they are ignored by users, etc. So either there
> > should be an actual error being returned by the kernel / library, or it
> > can be completely ignored and skipped.
> >
> > So, do MSM8916 / MSM8996 / SDM845 support CRC? If not, that must be
> > handled somehow.
> I see it's supported on SDM845 but not on MSM89##. I'll just send the new patch version for now
> as CRC mismatch failures are getting ignored.

Please clearly document which platforms don't support CRC feature, the
implications and the possible (userspace) impact. E.g. if the kernel
logs a message for each call with failed CRC case, then this might cause
a serious slowdown. Likewise a userspace lib might cause a slowdown.

In fact, if CRC is a debugging feature, is it going to be enabled or
disabled by default?

> >
> >>> And if they do, why do we need the invoke_v2? Can we modify existing
> >>> code instead?
> >> invoke_v2 is needed because there is a need to pass user crc pointer over ioctl call which
> >> cannot be achieved using existing code. Also there are plans to add more features to this
> >> invoke_v2 request which will carry some information from user.
> > Is it really extensible without breaking the ABI?
> I'm planning to keep reserved bits in uapi struct for the same. Do you see any
> problem with this?

Please keep Greg's comment in mind - verify that all reserved fields are
zero.

> >>>> From user space CRC check failure is
> >>>> not fatal and is printed as a warning. But if copy of CRC to user fails, it will result in remote
> >>>> call failure. Should I keep it as fatal considering that ever very old DSP support this or should
> >>>> I consider the copy failure as non-fatal as userspace is treating this as a warning?
> >>> warnings can remain unseen for a long time. Consider a GUI app. Nobody
> >>> is there to view kernel warnings or library output.
> >> Let me see if this can be done. Are you suggesting that the app will be somewhat tracking
> >> if there is any crc check mismatch failures?
> > I suggest returning -EIO to the app.
> I'll check this.
> >
> >>>>>> Signed-off-by: Ekansh Gupta <quic_ekangupt@xxxxxxxxxxx>
> >>>>>> ---
> >>>>>>  drivers/misc/fastrpc.c      | 161 ++++++++++++++++++++++++------------
> >>>>>>  include/uapi/misc/fastrpc.h |   7 ++
> >>>>>>  2 files changed, 116 insertions(+), 52 deletions(-)
> >>>>>>
> >>>>>> diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
> >>>>>> index 74181b8c386b..8e817a763d1d 100644
> >>>>>> --- a/drivers/misc/fastrpc.c
> >>>>>> +++ b/drivers/misc/fastrpc.c
> >>>>>> @@ -573,13 +573,15 @@ static void fastrpc_get_buff_overlaps(struct fastrpc_invoke_ctx *ctx)
> >>>>>>  
> >>>>>>  static struct fastrpc_invoke_ctx *fastrpc_context_alloc(
> >>>>>>  			struct fastrpc_user *user, u32 kernel, u32 sc,
> >>>>>> -			struct fastrpc_invoke_args *args)
> >>>>>> +			struct fastrpc_invoke_v2 *inv2)
> >>>>>>  {
> >>>>>>  	struct fastrpc_channel_ctx *cctx = user->cctx;
> >>>>>>  	struct fastrpc_invoke_ctx *ctx = NULL;
> >>>>>> +	struct fastrpc_invoke_args *args = NULL;
> >>>>> Why do you need to init to NULL if you are going to set it two lines
> >>>>> below?
> >>>>>
> >>>>>>  	unsigned long flags;
> >>>>>>  	int ret;
> >>>>>>  
> >>>>>> +	args = (struct fastrpc_invoke_args *)inv2->inv.args;
> >>>>> Why does it need a typecast?
> >>>>>
> >>>>>>  	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
> >>>>>>  	if (!ctx)
> >>>>>>  		return ERR_PTR(-ENOMEM);
> >>>>>> @@ -611,6 +613,7 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc(
> >>>>>>  	/* Released in fastrpc_context_put() */
> >>>>>>  	fastrpc_channel_ctx_get(cctx);
> >>>>>>  
> >>>>>> +	ctx->crc = (u32 *)(uintptr_t)inv2->crc;
> >>>>> Oh, but why? Also is it a user pointer or in-kernel data? If it's a
> >>>>> user-based pointer, where is the accessiblity check? Why isn't it
> >>>>> annotated properly?
> >>>> This is a user pointer where the crc data is expected to be copied. There is no
> >>>> other access to this pointer from kernel. I'm planning to change the data type
> >>>> for crc as (void __user*) inside fastrpc_invoke_ctx structure.
> >>> Yes, please. Also make sure that sparse doesn't add any warnings
> >>> regarding pointer conversions.
> >> Ack.
> >>>>>>  	ctx->sc = sc;
> >>>>>>  	ctx->retval = -1;
> >>>>>>  	ctx->pid = current->pid;
> >>>>>> @@ -1070,6 +1073,7 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
> >>>>>>  	struct fastrpc_invoke_buf *list;
> >>>>>>  	struct fastrpc_phy_page *pages;
> >>>>>>  	u64 *fdlist;
> >>>>>> +	u32 *crclist;
> >>>>>>  	int i, inbufs, outbufs, handles;
> >>>>>>  
> >>>>>>  	inbufs = REMOTE_SCALARS_INBUFS(ctx->sc);
> >>>>>> @@ -1078,6 +1082,7 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
> >>>>>>  	list = fastrpc_invoke_buf_start(rpra, ctx->nscalars);
> >>>>>>  	pages = fastrpc_phy_page_start(list, ctx->nscalars);
> >>>>>>  	fdlist = (uint64_t *)(pages + inbufs + outbufs + handles);
> >>>>>> +	crclist = (u32 *)(fdlist + FASTRPC_MAX_FDLIST);
> >>>>> I think we should rewrite this parsing somehow. Is the format of data
> >>>>> documented somewhere?
> >>>> fdlist, crclist and poll(planned) are the only pointers that is being used. I'm planning
> >>>> to store these pointers to ctx structure and directly use it wherever needed. This will
> >>>> clean-up this unnecessary calculations at multiple places.
> >>> Please do. Nevertheless, the format also must be documented.
> >> Ack.
> >>>>>>  
> >>>>>>  	for (i = inbufs; i < ctx->nbufs; ++i) {
> >>>>>>  		if (!ctx->maps[i]) {
> >>>>>> @@ -1102,6 +1107,12 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
> >>>>>>  			fastrpc_map_put(mmap);
> >>>>>>  	}
> >>>>>>  
> >>>>>> +	if (ctx->crc && crclist && rpra) {
> >>>>>> +		if (copy_to_user((void __user *)ctx->crc, crclist,
> >>>>>> +				FASTRPC_MAX_CRCLIST * sizeof(u32)))
> >>>>> Oh, so it's a user pointer. Then u32* was completely incorrect.
> >>>>> Also you are copying FASTRPC_MAX_CRCLIST elements. Are all of them
> >>>>> filled? Or are we leaking some data to userspace?
> >>>> Yes, right. Planning clean-up in next patch.
> >>>>
> >>>> All of FASTRPC_MAX_CRCLIST is filled with crc data by DSP so copying should be fine.
> >>> Huh? I definitely want to see documentation for function arguments.
> >> Sure. I'll also modify the metadata layout doc here to add fdlist, CRC and other planned contents.
> >> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/misc/fastrpc.c#n842
> > This is not a documentation. E.g. I can not write code using that
> > description. For example, it mentions neither FDLIST nor CRC.
> I'm planning to add complete documentation for CRC and polling mode in user library project.
> If I need to add documentation in driver, can you pls suggest what is the right place to add
> the information?

Library should be fine. We don't require documenting all hardware in the
kernel. But the uAPI of the driver should be properly described.

> 
> Thanks for your comments.
> 
> --ekansh
> >
> >>>>>> +			return -EFAULT;
> >>>>>> +	}
> >>>>>> +
> >>>>>>  	return 0;
> >>>>>>  }
> >>>>>>  
> 

-- 
With best wishes
Dmitry



[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux