RE: [EXT] Re: [PATCH v18 06/15] media: amphion: add vpu v4l2 m2m support

From: Ming Qian
Date: Wed Mar 09 2022 - 20:55:41 EST


> -----Original Message-----
> From: Dan Carpenter [mailto:dan.carpenter@xxxxxxxxxx]
> Sent: Wednesday, March 9, 2022 7:34 PM
> To: Ming Qian <ming.qian@xxxxxxx>
> Cc: mchehab@xxxxxxxxxx; shawnguo@xxxxxxxxxx; robh+dt@xxxxxxxxxx;
> s.hauer@xxxxxxxxxxxxxx; hverkuil-cisco@xxxxxxxxx; kernel@xxxxxxxxxxxxxx;
> festevam@xxxxxxxxx; dl-linux-imx <linux-imx@xxxxxxx>; Aisheng Dong
> <aisheng.dong@xxxxxxx>; linux-media@xxxxxxxxxxxxxxx;
> linux-kernel@xxxxxxxxxxxxxxx; devicetree@xxxxxxxxxxxxxxx;
> linux-arm-kernel@xxxxxxxxxxxxxxxxxxx
> Subject: [EXT] Re: [PATCH v18 06/15] media: amphion: add vpu v4l2 m2m
> support
>
> Caution: EXT Email
>
> This code has a serious case of the u32 pox. There are times where u32 is
> specified in the hardware or network spec. That's when a u32 is appropriate.
> Also for bit masks. Otherwise "int" is normally the correct type. If it's a size
> value then unsigned long, long, or unsigned long long is probably correct.
>
> INT_MAX is just over 2 billion. If you make a number line then most numbers
> are going to be near the zero. You have 10 fingers. You have
> 2 phones. 2 cars. 3 monitors connected to your computer. 200 error
> codes. You're never going to even get close to the 2 billion limit.
>
> For situations where the numbers get very large, then the band on the number
> line between 2 and 4 billion is very narrow. I can name people who have over
> a billion dollars but I cannot name even one who falls exactly between 2 and 4
> billion.
>
> In other words u32 is almost useless for describing anything. If something
> cannot fit in a int then it's not going to fit into a u32 either and you should use
> a u64 instead.
>
> Some people think that unsigned values are more safe than signed values.
> It is true, in certain limited cases that the invisible side effects of unsigned
> math can protect you. But mostly the invisible side effects create surprises
> and bugs. And again if you have to pick an unsigned type pick an u64
> because it is harder to have an integer overflow on a
> 64 bit type vs a 32 bit type.
>
> Avoid u32 types where ever you can, they only cause bugs.

OK, I think you're right, I'll check and fix it according to your comments
Thanks very much for your reivew

>
> > +u32 vpu_helper_copy_from_stream_buffer(struct vpu_buffer
> *stream_buffer,
> > + u32 *rptr, u32 size, void *dst) {
> > + u32 offset;
> > + u32 start;
> > + u32 end;
> > + void *virt;
> > +
> > + if (!stream_buffer || !rptr || !dst)
> > + return -EINVAL;
>
> This function returns negatives.
>
> > +
> > + if (!size)
> > + return 0;
> > +
> > + offset = *rptr;
> > + start = stream_buffer->phys;
> > + end = start + stream_buffer->length;
> > + virt = stream_buffer->virt;
> > +
> > + if (offset < start || offset > end)
> > + return -EINVAL;
> > +
> > + if (offset + size <= end) {
>
> Check for integer overflows?
>
>
> > + memcpy(dst, virt + (offset - start), size);
> > + } else {
> > + memcpy(dst, virt + (offset - start), end - offset);
> > + memcpy(dst + end - offset, virt, size + offset - end);
> > + }
> > +
> > + *rptr = vpu_helper_step_walk(stream_buffer, offset, size);
> > + return size;
>
> This function always returns size on success. Just return 0 on success.
>
> > +}
> > +
> > +u32 vpu_helper_copy_to_stream_buffer(struct vpu_buffer *stream_buffer,
> > + u32 *wptr, u32 size, void *src) {
> > + u32 offset;
> > + u32 start;
> > + u32 end;
> > + void *virt;
> > +
> > + if (!stream_buffer || !wptr || !src)
> > + return -EINVAL;
>
> Signedness bug.
>
> > +
> > + if (!size)
> > + return 0;
> > +
> > + offset = *wptr;
> > + start = stream_buffer->phys;
> > + end = start + stream_buffer->length;
> > + virt = stream_buffer->virt;
> > + if (offset < start || offset > end)
> > + return -EINVAL;
>
> Signedness.
>
> > +
> > + if (offset + size <= end) {
>
> Check for integer overflow?
>
> > + memcpy(virt + (offset - start), src, size);
> > + } else {
> > + memcpy(virt + (offset - start), src, end - offset);
> > + memcpy(virt, src + end - offset, size + offset - end);
> > + }
> > +
> > + *wptr = vpu_helper_step_walk(stream_buffer, offset, size);
> > +
> > + return size;
>
> Just return zero on success. No need to return a known parameter.
>
> > +}
> > +
> > +u32 vpu_helper_memset_stream_buffer(struct vpu_buffer *stream_buffer,
> > + u32 *wptr, u8 val, u32 size) {
> > + u32 offset;
> > + u32 start;
> > + u32 end;
> > + void *virt;
> > +
> > + if (!stream_buffer || !wptr)
> > + return -EINVAL;
>
> Signedness.
>
> > +
> > + if (!size)
> > + return 0;
> > +
> > + offset = *wptr;
> > + start = stream_buffer->phys;
> > + end = start + stream_buffer->length;
> > + virt = stream_buffer->virt;
> > + if (offset < start || offset > end)
> > + return -EINVAL;
> > +
> > + if (offset + size <= end) {
>
> Check for overflow?
>
> > + memset(virt + (offset - start), val, size);
> > + } else {
> > + memset(virt + (offset - start), val, end - offset);
> > + memset(virt, val, size + offset - end);
> > + }
> > +
> > + offset += size;
> > + if (offset >= end)
> > + offset -= stream_buffer->length;
> > +
> > + *wptr = offset;
> > +
> > + return size;
> > +}
>
> regards,
> dan carpenter