aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.10/950-0649-media-rpivid-Fix-H265-aux-ent-reuse-of-the-same-slot.patch
diff options
context:
space:
mode:
authorÁlvaro Fernández Rojas <noltari@gmail.com>2021-08-21 10:54:34 +0200
committerÁlvaro Fernández Rojas <noltari@gmail.com>2021-08-21 19:07:07 +0200
commit8299d1f057439f94c6a4412e2e5c5082b82a30c9 (patch)
tree1bf678d61f11f7394493be464c7876e496f7faed /target/linux/bcm27xx/patches-5.10/950-0649-media-rpivid-Fix-H265-aux-ent-reuse-of-the-same-slot.patch
parent33b6885975ce376ff075362b7f0890326043111b (diff)
downloadupstream-8299d1f057439f94c6a4412e2e5c5082b82a30c9.tar.gz
upstream-8299d1f057439f94c6a4412e2e5c5082b82a30c9.tar.bz2
upstream-8299d1f057439f94c6a4412e2e5c5082b82a30c9.zip
bcm27xx: add kernel 5.10 support
Rebased RPi foundation patches on linux 5.10.59, removed applied and reverted patches, wireless patches and defconfig patches. bcm2708: boot tested on RPi B+ v1.2 bcm2709: boot tested on RPi 4B v1.1 4G bcm2711: boot tested on RPi 4B v1.1 4G Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-5.10/950-0649-media-rpivid-Fix-H265-aux-ent-reuse-of-the-same-slot.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.10/950-0649-media-rpivid-Fix-H265-aux-ent-reuse-of-the-same-slot.patch151
1 files changed, 151 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.10/950-0649-media-rpivid-Fix-H265-aux-ent-reuse-of-the-same-slot.patch b/target/linux/bcm27xx/patches-5.10/950-0649-media-rpivid-Fix-H265-aux-ent-reuse-of-the-same-slot.patch
new file mode 100644
index 0000000000..6ef221136f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.10/950-0649-media-rpivid-Fix-H265-aux-ent-reuse-of-the-same-slot.patch
@@ -0,0 +1,151 @@
+From e3e645fde7d3141767c52a1ae0ffd2f94d0046a4 Mon Sep 17 00:00:00 2001
+From: John Cox <jc@kynesim.co.uk>
+Date: Thu, 24 Jun 2021 14:43:49 +0100
+Subject: [PATCH] media: rpivid: Fix H265 aux ent reuse of the same
+ slot
+
+It is legitimate, though unusual, for an aux ent associated with a slot
+to be selected in phase 0 before a previous selection has been used and
+released in phase 2. Fix such that if the slot is found to be in use
+that the aux ent associated with it is reused rather than an new aux
+ent being created. This fixes a problem where when the first aux ent
+was released the second was lost track of.
+
+This bug spotted in Nick's testing. It may explain some other occasional,
+unreliable decode error reports where dmesg included "Missing DPB AUX
+ent" logging.
+
+Signed-off-by: John Cox <jc@kynesim.co.uk>
+---
+ drivers/staging/media/rpivid/rpivid_h265.c | 75 ++++++++++++++--------
+ 1 file changed, 49 insertions(+), 26 deletions(-)
+
+--- a/drivers/staging/media/rpivid/rpivid_h265.c
++++ b/drivers/staging/media/rpivid/rpivid_h265.c
+@@ -371,7 +371,8 @@ static void aux_q_free(struct rpivid_ctx
+ kfree(aq);
+ }
+
+-static struct rpivid_q_aux *aux_q_alloc(struct rpivid_ctx *const ctx)
++static struct rpivid_q_aux *aux_q_alloc(struct rpivid_ctx *const ctx,
++ const unsigned int q_index)
+ {
+ struct rpivid_dev *const dev = ctx->dev;
+ struct rpivid_q_aux *const aq = kzalloc(sizeof(*aq), GFP_KERNEL);
+@@ -379,11 +380,17 @@ static struct rpivid_q_aux *aux_q_alloc(
+ if (!aq)
+ return NULL;
+
+- aq->refcount = 1;
+ if (gptr_alloc(dev, &aq->col, ctx->colmv_picsize,
+ DMA_ATTR_FORCE_CONTIGUOUS | DMA_ATTR_NO_KERNEL_MAPPING))
+ goto fail;
+
++ /*
++ * Spinlock not required as called in P0 only and
++ * aux checks done by _new
++ */
++ aq->refcount = 1;
++ aq->q_index = q_index;
++ ctx->aux_ents[q_index] = aq;
+ return aq;
+
+ fail:
+@@ -398,22 +405,38 @@ static struct rpivid_q_aux *aux_q_new(st
+ unsigned long lockflags;
+
+ spin_lock_irqsave(&ctx->aux_lock, lockflags);
+- aq = ctx->aux_free;
+- if (aq) {
++ /*
++ * If we already have this allocated to a slot then use that
++ * and assume that it will all work itself out in the pipeline
++ */
++ if ((aq = ctx->aux_ents[q_index]) != NULL) {
++ ++aq->refcount;
++ } else if ((aq = ctx->aux_free) != NULL) {
+ ctx->aux_free = aq->next;
+ aq->next = NULL;
+ aq->refcount = 1;
++ aq->q_index = q_index;
++ ctx->aux_ents[q_index] = aq;
+ }
+ spin_unlock_irqrestore(&ctx->aux_lock, lockflags);
+
+- if (!aq) {
+- aq = aux_q_alloc(ctx);
+- if (!aq)
+- return NULL;
+- }
++ if (!aq)
++ aq = aux_q_alloc(ctx, q_index);
++
++ return aq;
++}
++
++static struct rpivid_q_aux *aux_q_ref_idx(struct rpivid_ctx *const ctx,
++ const int q_index)
++{
++ unsigned long lockflags;
++ struct rpivid_q_aux *aq;
++
++ spin_lock_irqsave(&ctx->aux_lock, lockflags);
++ if ((aq = ctx->aux_ents[q_index]) != NULL)
++ ++aq->refcount;
++ spin_unlock_irqrestore(&ctx->aux_lock, lockflags);
+
+- aq->q_index = q_index;
+- ctx->aux_ents[q_index] = aq;
+ return aq;
+ }
+
+@@ -436,21 +459,21 @@ static void aux_q_release(struct rpivid_
+ struct rpivid_q_aux **const paq)
+ {
+ struct rpivid_q_aux *const aq = *paq;
+- *paq = NULL;
+-
+- if (aq) {
+- unsigned long lockflags;
++ unsigned long lockflags;
+
+- spin_lock_irqsave(&ctx->aux_lock, lockflags);
++ if (!aq)
++ return;
+
+- if (--aq->refcount == 0) {
+- aq->next = ctx->aux_free;
+- ctx->aux_free = aq;
+- ctx->aux_ents[aq->q_index] = NULL;
+- }
++ *paq = NULL;
+
+- spin_unlock_irqrestore(&ctx->aux_lock, lockflags);
++ spin_lock_irqsave(&ctx->aux_lock, lockflags);
++ if (--aq->refcount == 0) {
++ aq->next = ctx->aux_free;
++ ctx->aux_free = aq;
++ ctx->aux_ents[aq->q_index] = NULL;
++ aq->q_index = ~0U;
+ }
++ spin_unlock_irqrestore(&ctx->aux_lock, lockflags);
+ }
+
+ static void aux_q_init(struct rpivid_ctx *const ctx)
+@@ -1958,12 +1981,12 @@ static void rpivid_h265_setup(struct rpi
+ }
+
+ if (use_aux) {
+- dpb_q_aux[i] = aux_q_ref(ctx,
+- ctx->aux_ents[buffer_index]);
++ dpb_q_aux[i] = aux_q_ref_idx(ctx, buffer_index);
+ if (!dpb_q_aux[i])
+ v4l2_warn(&dev->v4l2_dev,
+- "Missing DPB AUX ent %d index=%d\n",
+- i, buffer_index);
++ "Missing DPB AUX ent %d, timestamp=%lld, index=%d\n",
++ i, (long long)sh->dpb[i].timestamp,
++ buffer_index);
+ }
+
+ de->ref_addrs[i] =