As &ndlp->lock is acquired by timer lpfc_els_retry_delay() under softirq
context, process context code acquiring the lock &phba->hbalock should
disable irq or bh, otherwise deadlock could happen if the timer preempt
the execution while the lock is held in process context on the same CPU.
The two lock acquisition inside lpfc_cleanup_pending_mbox() does not
disable irq or softirq.
[Deadlock Scenario]
lpfc_cmpl_els_fdisc()
-> lpfc_cleanup_pending_mbox()
-> spin_lock(&ndlp->lock);
<irq>
-> lpfc_els_retry_delay()
-> lpfc_nlp_get()
-> spin_lock_irqsave(&ndlp->lock, flags); (deadlock here)
This flaw was found by an experimental static analysis tool I am
developing for irq-related deadlock.
The patch fix the potential deadlock by spin_lock_irq() to disable
irq.
Signed-off-by: Chengfeng Ye <dg573847474(a)gmail.com>
---
drivers/scsi/lpfc/lpfc_sli.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 58d10f8f75a7..8555f6bb9742 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -21049,9 +21049,9 @@ lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
mb->mbox_flag |= LPFC_MBX_IMED_UNREG;
restart_loop = 1;
spin_unlock_irq(&phba->hbalock);
- spin_lock(&ndlp->lock);
+ spin_lock_irq(&ndlp->lock);
ndlp->nlp_flag &= ~NLP_IGNR_REG_CMPL;
- spin_unlock(&ndlp->lock);
+ spin_unlock_irq(&ndlp->lock);
spin_lock_irq(&phba->hbalock);
break;
}
@@ -21067,9 +21067,9 @@ lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
ndlp = (struct lpfc_nodelist *)mb->ctx_ndlp;
mb->ctx_ndlp = NULL;
if (ndlp) {
- spin_lock(&ndlp->lock);
+ spin_lock_irq(&ndlp->lock);
ndlp->nlp_flag &= ~NLP_IGNR_REG_CMPL;
- spin_unlock(&ndlp->lock);
+ spin_unlock_irq(&ndlp->lock);
lpfc_nlp_put(ndlp);
}
}
--
2.17.1
From: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
commit 05abb3be91d8788328231ee02973ab3d47f5e3d2 upstream.
Currently dma_resv_get_fences() will leak the previously
allocated array if the fence iteration got restarted and
the krealloc_array() fails.
Free the old array by hand, and make sure we still clear
the returned *fences so the caller won't end up accessing
freed memory. Some (but not all) of the callers of
dma_resv_get_fences() seem to still trawl through the
array even when dma_resv_get_fences() failed. And let's
zero out *num_fences as well for good measure.
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Christian König <christian.koenig(a)amd.com>
Cc: linux-media(a)vger.kernel.org
Cc: dri-devel(a)lists.freedesktop.org
Cc: linaro-mm-sig(a)lists.linaro.org
Fixes: d3c80698c9f5 ("dma-buf: use new iterator in dma_resv_get_fences v3")
Signed-off-by: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
Reviewed-by: Christian König <christian.koenig(a)amd.com>
Cc: stable(a)vger.kernel.org
Link: https://patchwork.freedesktop.org/patch/msgid/20230713194745.1751-1-ville.s…
Signed-off-by: Christian König <christian.koenig(a)amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/dma-resv.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -566,6 +566,7 @@ int dma_resv_get_fences(struct dma_resv
dma_resv_for_each_fence_unlocked(&cursor, fence) {
if (dma_resv_iter_is_restarted(&cursor)) {
+ struct dma_fence **new_fences;
unsigned int count;
while (*num_fences)
@@ -574,13 +575,17 @@ int dma_resv_get_fences(struct dma_resv
count = cursor.num_fences + 1;
/* Eventually re-allocate the array */
- *fences = krealloc_array(*fences, count,
- sizeof(void *),
- GFP_KERNEL);
- if (count && !*fences) {
+ new_fences = krealloc_array(*fences, count,
+ sizeof(void *),
+ GFP_KERNEL);
+ if (count && !new_fences) {
+ kfree(*fences);
+ *fences = NULL;
+ *num_fences = 0;
dma_resv_iter_end(&cursor);
return -ENOMEM;
}
+ *fences = new_fences;
}
(*fences)[(*num_fences)++] = dma_fence_get(fence);
From: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
commit 05abb3be91d8788328231ee02973ab3d47f5e3d2 upstream.
Currently dma_resv_get_fences() will leak the previously
allocated array if the fence iteration got restarted and
the krealloc_array() fails.
Free the old array by hand, and make sure we still clear
the returned *fences so the caller won't end up accessing
freed memory. Some (but not all) of the callers of
dma_resv_get_fences() seem to still trawl through the
array even when dma_resv_get_fences() failed. And let's
zero out *num_fences as well for good measure.
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Christian König <christian.koenig(a)amd.com>
Cc: linux-media(a)vger.kernel.org
Cc: dri-devel(a)lists.freedesktop.org
Cc: linaro-mm-sig(a)lists.linaro.org
Fixes: d3c80698c9f5 ("dma-buf: use new iterator in dma_resv_get_fences v3")
Signed-off-by: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
Reviewed-by: Christian König <christian.koenig(a)amd.com>
Cc: stable(a)vger.kernel.org
Link: https://patchwork.freedesktop.org/patch/msgid/20230713194745.1751-1-ville.s…
Signed-off-by: Christian König <christian.koenig(a)amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/dma-resv.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -571,6 +571,7 @@ int dma_resv_get_fences(struct dma_resv
dma_resv_for_each_fence_unlocked(&cursor, fence) {
if (dma_resv_iter_is_restarted(&cursor)) {
+ struct dma_fence **new_fences;
unsigned int count;
while (*num_fences)
@@ -579,13 +580,17 @@ int dma_resv_get_fences(struct dma_resv
count = cursor.num_fences + 1;
/* Eventually re-allocate the array */
- *fences = krealloc_array(*fences, count,
- sizeof(void *),
- GFP_KERNEL);
- if (count && !*fences) {
+ new_fences = krealloc_array(*fences, count,
+ sizeof(void *),
+ GFP_KERNEL);
+ if (count && !new_fences) {
+ kfree(*fences);
+ *fences = NULL;
+ *num_fences = 0;
dma_resv_iter_end(&cursor);
return -ENOMEM;
}
+ *fences = new_fences;
}
(*fences)[(*num_fences)++] = dma_fence_get(fence);
This is a note to let you know that I've just added the patch titled
dma-buf/dma-resv: Stop leaking on krealloc() failure
to the 6.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
dma-buf-dma-resv-stop-leaking-on-krealloc-failure.patch
and it can be found in the queue-6.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
From 05abb3be91d8788328231ee02973ab3d47f5e3d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala(a)linux.intel.com>
Date: Thu, 13 Jul 2023 22:47:45 +0300
Subject: dma-buf/dma-resv: Stop leaking on krealloc() failure
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
commit 05abb3be91d8788328231ee02973ab3d47f5e3d2 upstream.
Currently dma_resv_get_fences() will leak the previously
allocated array if the fence iteration got restarted and
the krealloc_array() fails.
Free the old array by hand, and make sure we still clear
the returned *fences so the caller won't end up accessing
freed memory. Some (but not all) of the callers of
dma_resv_get_fences() seem to still trawl through the
array even when dma_resv_get_fences() failed. And let's
zero out *num_fences as well for good measure.
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Christian König <christian.koenig(a)amd.com>
Cc: linux-media(a)vger.kernel.org
Cc: dri-devel(a)lists.freedesktop.org
Cc: linaro-mm-sig(a)lists.linaro.org
Fixes: d3c80698c9f5 ("dma-buf: use new iterator in dma_resv_get_fences v3")
Signed-off-by: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
Reviewed-by: Christian König <christian.koenig(a)amd.com>
Cc: stable(a)vger.kernel.org
Link: https://patchwork.freedesktop.org/patch/msgid/20230713194745.1751-1-ville.s…
Signed-off-by: Christian König <christian.koenig(a)amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/dma-resv.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -571,6 +571,7 @@ int dma_resv_get_fences(struct dma_resv
dma_resv_for_each_fence_unlocked(&cursor, fence) {
if (dma_resv_iter_is_restarted(&cursor)) {
+ struct dma_fence **new_fences;
unsigned int count;
while (*num_fences)
@@ -579,13 +580,17 @@ int dma_resv_get_fences(struct dma_resv
count = cursor.num_fences + 1;
/* Eventually re-allocate the array */
- *fences = krealloc_array(*fences, count,
- sizeof(void *),
- GFP_KERNEL);
- if (count && !*fences) {
+ new_fences = krealloc_array(*fences, count,
+ sizeof(void *),
+ GFP_KERNEL);
+ if (count && !new_fences) {
+ kfree(*fences);
+ *fences = NULL;
+ *num_fences = 0;
dma_resv_iter_end(&cursor);
return -ENOMEM;
}
+ *fences = new_fences;
}
(*fences)[(*num_fences)++] = dma_fence_get(fence);
Patches currently in stable-queue which might be from ville.syrjala(a)linux.intel.com are
queue-6.4/dma-buf-dma-resv-stop-leaking-on-krealloc-failure.patch
This is a note to let you know that I've just added the patch titled
dma-buf/dma-resv: Stop leaking on krealloc() failure
to the 6.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
dma-buf-dma-resv-stop-leaking-on-krealloc-failure.patch
and it can be found in the queue-6.1 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
From 05abb3be91d8788328231ee02973ab3d47f5e3d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala(a)linux.intel.com>
Date: Thu, 13 Jul 2023 22:47:45 +0300
Subject: dma-buf/dma-resv: Stop leaking on krealloc() failure
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
commit 05abb3be91d8788328231ee02973ab3d47f5e3d2 upstream.
Currently dma_resv_get_fences() will leak the previously
allocated array if the fence iteration got restarted and
the krealloc_array() fails.
Free the old array by hand, and make sure we still clear
the returned *fences so the caller won't end up accessing
freed memory. Some (but not all) of the callers of
dma_resv_get_fences() seem to still trawl through the
array even when dma_resv_get_fences() failed. And let's
zero out *num_fences as well for good measure.
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Christian König <christian.koenig(a)amd.com>
Cc: linux-media(a)vger.kernel.org
Cc: dri-devel(a)lists.freedesktop.org
Cc: linaro-mm-sig(a)lists.linaro.org
Fixes: d3c80698c9f5 ("dma-buf: use new iterator in dma_resv_get_fences v3")
Signed-off-by: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
Reviewed-by: Christian König <christian.koenig(a)amd.com>
Cc: stable(a)vger.kernel.org
Link: https://patchwork.freedesktop.org/patch/msgid/20230713194745.1751-1-ville.s…
Signed-off-by: Christian König <christian.koenig(a)amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/dma-resv.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -566,6 +566,7 @@ int dma_resv_get_fences(struct dma_resv
dma_resv_for_each_fence_unlocked(&cursor, fence) {
if (dma_resv_iter_is_restarted(&cursor)) {
+ struct dma_fence **new_fences;
unsigned int count;
while (*num_fences)
@@ -574,13 +575,17 @@ int dma_resv_get_fences(struct dma_resv
count = cursor.num_fences + 1;
/* Eventually re-allocate the array */
- *fences = krealloc_array(*fences, count,
- sizeof(void *),
- GFP_KERNEL);
- if (count && !*fences) {
+ new_fences = krealloc_array(*fences, count,
+ sizeof(void *),
+ GFP_KERNEL);
+ if (count && !new_fences) {
+ kfree(*fences);
+ *fences = NULL;
+ *num_fences = 0;
dma_resv_iter_end(&cursor);
return -ENOMEM;
}
+ *fences = new_fences;
}
(*fences)[(*num_fences)++] = dma_fence_get(fence);
Patches currently in stable-queue which might be from ville.syrjala(a)linux.intel.com are
queue-6.1/dma-buf-dma-resv-stop-leaking-on-krealloc-failure.patch
From: Luc Ma <luc(a)sietium.com>
Signed-off-by: Luc Ma <luc(a)sietium.com>
---
drivers/dma-buf/dma-buf-sysfs-stats.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma-buf/dma-buf-sysfs-stats.c b/drivers/dma-buf/dma-buf-sysfs-stats.c
index 6cfbbf0720bd..b5b62e40ccc1 100644
--- a/drivers/dma-buf/dma-buf-sysfs-stats.c
+++ b/drivers/dma-buf/dma-buf-sysfs-stats.c
@@ -33,7 +33,7 @@
* into their address space. This necessitated the creation of the DMA-BUF sysfs
* statistics interface to provide per-buffer information on production systems.
*
- * The interface at ``/sys/kernel/dma-buf/buffers`` exposes information about
+ * The interface at ``/sys/kernel/dmabuf/buffers`` exposes information about
* every DMA-BUF when ``CONFIG_DMABUF_SYSFS_STATS`` is enabled.
*
* The following stats are exposed by the interface:
--
2.25.1
From: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
Currently dma_resv_get_fences() will leak the previously
allocated array if the fence iteration got restarted and
the krealloc_array() fails.
Free the old array by hand, and make sure we still clear
the returned *fences so the caller won't end up accessing
freed memory. Some (but not all) of the callers of
dma_resv_get_fences() seem to still trawl through the
array even when dma_resv_get_fences() failed. And let's
zero out *num_fences as well for good measure.
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Christian König <christian.koenig(a)amd.com>
Cc: linux-media(a)vger.kernel.org
Cc: dri-devel(a)lists.freedesktop.org
Cc: linaro-mm-sig(a)lists.linaro.org
Fixes: d3c80698c9f5 ("dma-buf: use new iterator in dma_resv_get_fences v3")
Signed-off-by: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
---
drivers/dma-buf/dma-resv.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c
index b6f71eb00866..38b4110378de 100644
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -571,6 +571,7 @@ int dma_resv_get_fences(struct dma_resv *obj, enum dma_resv_usage usage,
dma_resv_for_each_fence_unlocked(&cursor, fence) {
if (dma_resv_iter_is_restarted(&cursor)) {
+ struct dma_fence **new_fences;
unsigned int count;
while (*num_fences)
@@ -579,13 +580,17 @@ int dma_resv_get_fences(struct dma_resv *obj, enum dma_resv_usage usage,
count = cursor.num_fences + 1;
/* Eventually re-allocate the array */
- *fences = krealloc_array(*fences, count,
- sizeof(void *),
- GFP_KERNEL);
- if (count && !*fences) {
+ new_fences = krealloc_array(*fences, count,
+ sizeof(void *),
+ GFP_KERNEL);
+ if (count && !new_fences) {
+ kfree(*fences);
+ *fences = NULL;
+ *num_fences = 0;
dma_resv_iter_end(&cursor);
return -ENOMEM;
}
+ *fences = new_fences;
}
(*fences)[(*num_fences)++] = dma_fence_get(fence);
--
2.39.3
The __dma_fence_unwrap_merge() function is supposed to return NULL on
error. But the dma_fence_allocate_private_stub() returns error pointers
so check for that and covert the error pointers to NULL returns.
Otherwise, the callers do not expect error pointers and it leads to an
Oops.
Fixes: f781f661e8c9 ("dma-buf: keep the signaling time of merged fences v3")
Signed-off-by: Dan Carpenter <dan.carpenter(a)linaro.org>
---
drivers/dma-buf/dma-fence-unwrap.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c
index c625bb2b5d56..d183eda0db89 100644
--- a/drivers/dma-buf/dma-fence-unwrap.c
+++ b/drivers/dma-buf/dma-fence-unwrap.c
@@ -94,8 +94,12 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
* If we couldn't find a pending fence just return a private signaled
* fence with the timestamp of the last signaled one.
*/
- if (count == 0)
- return dma_fence_allocate_private_stub(timestamp);
+ if (count == 0) {
+ tmp = dma_fence_allocate_private_stub(timestamp);
+ if (IS_ERR(tmp))
+ return NULL;
+ return tmp;
+ }
array = kmalloc_array(count, sizeof(*array), GFP_KERNEL);
if (!array)
@@ -176,6 +180,8 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
return_tmp:
kfree(array);
+ if (IS_ERR(tmp))
+ return NULL;
return tmp;
}
EXPORT_SYMBOL_GPL(__dma_fence_unwrap_merge);
--
2.39.2
Laura's email address has not been valid for quite awhile now,
so wanted to clean up the reviewer list here.
I reached out to Laura who said it made sense to drop her from
the list, so this patch does that.
I do want to recognize Laura's long time contribution to this
area and her previous ION maintainership, as this couldn't
have gone upstream without her prior efforts. Many thanks!
Cc: Laura Abbott <labbott(a)kernel.org>
Cc: T.J. Mercier <tjmercier(a)google.com>
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Benjamin Gaignard <benjamin.gaignard(a)collabora.com>
Cc: Brian Starkey <Brian.Starkey(a)arm.com>
Cc: John Stultz <jstultz(a)google.com>
Cc: linux-media(a)vger.kernel.org
Cc: dri-devel(a)lists.freedesktop.org
Cc: linaro-mm-sig(a)lists.linaro.org
Cc: kernel-team(a)android.com
Acked-by: Laura Abbott <labbott(a)kernel.org>
Signed-off-by: John Stultz <jstultz(a)google.com>
---
MAINTAINERS | 1 -
1 file changed, 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index f4e92b968ed7..6b28b59cbdb9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6181,7 +6181,6 @@ F: kernel/dma/
DMA-BUF HEAPS FRAMEWORK
M: Sumit Semwal <sumit.semwal(a)linaro.org>
R: Benjamin Gaignard <benjamin.gaignard(a)collabora.com>
-R: Laura Abbott <labbott(a)redhat.com>
R: Brian Starkey <Brian.Starkey(a)arm.com>
R: John Stultz <jstultz(a)google.com>
R: T.J. Mercier <tjmercier(a)google.com>
--
2.41.0.255.g8b1d071c50-goog
@codeaurora.org email addresses are no longer valid and will bounce.
I reached out to Liam about updating his entry under DMA-BUF HEAPS
FRAMEWORK with an @codeaurora.org address. His response:
"I am not a maintainer anymore, that should be removed."
Liam currently does not have an email address that can be used to remove
this entry, so I offered to submit a cleanup on his behalf with Liam's
consent.
Signed-off-by: Jeffrey Hugo <quic_jhugo(a)quicinc.com>
---
MAINTAINERS | 1 -
1 file changed, 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 76b53bafc03c..1781eb0a8dda 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6168,7 +6168,6 @@ F: kernel/dma/
DMA-BUF HEAPS FRAMEWORK
M: Sumit Semwal <sumit.semwal(a)linaro.org>
R: Benjamin Gaignard <benjamin.gaignard(a)collabora.com>
-R: Liam Mark <lmark(a)codeaurora.org>
R: Laura Abbott <labbott(a)redhat.com>
R: Brian Starkey <Brian.Starkey(a)arm.com>
R: John Stultz <jstultz(a)google.com>
--
2.40.1
Fix typo in comment of msm_gem.c.
Signed-off-by: Zhu Mao <zhumao001(a)208suo.com>
---
drivers/gpu/drm/msm/msm_gem.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_gem.c
b/drivers/gpu/drm/msm/msm_gem.c
index 20cfd86d2b32..ef81074416af 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -503,8 +503,8 @@ void msm_gem_unpin_locked(struct drm_gem_object
*obj)
/* Special unpin path for use in fence-signaling path, avoiding the
need
* to hold the obj lock by only depending on things that a protected by
- * the LRU lock. In particular we know that that we already have
backing
- * and and that the object's dma_resv has the fence for the current
+ * the LRU lock. In particular we know that we already have backing
+ * and that the object's dma_resv has the fence for the current
* submit/job which will prevent us racing against page eviction.
*/
void msm_gem_unpin_active(struct drm_gem_object *obj)
From: Sui Jingfeng <suijingfeng(a)loongson.cn>
Loongson display controller IP has been integrated in both Loongson north
bridge chipset(ls7a1000/ls7a2000) and Loongson SoCs(ls2k1000/ls2k2000), it
has been even included in Loongson self-made BMC products.
This display controller is a PCI device. It has two display pipes and each
display pipe support a primary plane and a cursor plane. For the DC in the
ls7a1000 and ls2k1000, each display pipe has a DVO output interface which
provide RGB888 signals, vertical & horizontal synchronisations and pixel
clock. Each CRTC is able to support 1920x1080@60Hz, the maximum resolution
of each display pipe is 2048x2048 according to the hardware spec.
For the DC in LS7A2000, each display pipe is equipped with a built-in HDMI
encoder which is compliant with the HDMI 1.4 specification, thus it support
3840x2160@30Hz. The first display pipe is also equipped with a transparent
vga encoder which is parallel with the HDMI encoder. The DC in LS7A2000 is
more complete compare with the one in old chips, besides above feature, it
has two hardware cursors, two hardware vblank counter and two scanout
position recorders unit. It also support tiled framebuffer format which
can be scanout the tiled framebuffer rendered by the LoongGPU directly.
v1 -> v2:
1) Use hpd status reg when polling for ls7a2000
2) Fix all warnings emerged when compile with W=1
v2 -> v3:
1) Add COMPILE_TEST in Kconfig and make the driver off by default
2) Alphabetical sorting headers (Thomas)
3) Untangle register access functions as much as possible (Thomas)
4) Switch to TTM based memory manager and prefer cached mapping
for Loongson SoC (Thomas)
5) Add chip id detection method, now all models are distinguishable.
6) Revise builtin HDMI phy driver, nearly all main stream mode
below 4K@30Hz is tested, this driver supported these mode very
well including clone display mode and extend display mode.
v3 -> v4:
1) Quickly fix a small mistake.
v4 -> v5:
1) Drop potential support for Loongson 2K series SoC temporary,
this part should be resend with the DT binding patch in the future.
2) Add per display pipe debugfs support to the builtin HDMI encoder.
3) Rewrite atomic_update() for hardware cursors plane(Thomas)
4) Rewrite encoder and connector initialization part, untangle it
according to the chip(Thomas).
v5 -> v6:
1) Remove stray code which didn't get used, say lsdc_of_get_reserved_ram
2) Fix all typos I could found, make sentences and code more readable
3) Untangle lsdc_hdmi*_connector_detect() function according to the pipe
4) After a serious consideration, we rename this driver as loongson.
Because we also have drivers toward the LoongGPU IP in LS7A2000 and
LS2K2000. Besides, there are also drivers about the external encoder,
HDMI audio driver and vbios support etc. This patch only provide DC
driver part, my teammate Li Yi believe that loongson will be more
suitable for loongson graphics than lsdc in the long run.
loongson.ko = LSDC + LoongGPU + encoders driver + vbios/DT ...
v6 -> v7:
1) Add prime support, self-sharing is works. sharing buffer with etnaviv
is also tested, and its works with limitation.
2) Implement buffer objects tracking with list_head.
3) S3(sleep to RAM) is tested on ls3a5000+ls7a2000 evb and it works.
4) Rewrite lsdc_bo_move, since ttm core stop allocating resources
during BO creation. Patch V1 ~ V6 of this series no longer works
on latest kernel. Thus, we send V7 to revival them.
v7 -> v8:
1) Zero a compile warnnings on 32-bit platform, compile with W=1
2) Revise lsdc_bo_gpu_offset() and minor cleanup
3) Pageflip tested on the virtual terminal with following commands
modetest -M loongson -s 32:1920x1080 -v
modetest -M loongson -s 34:1920x1080 -v -F tiles
It works like a charm, when running pageflip test with dual screnn
configuration, another two additional bo created by the modetest
emerged, VRAM usage up to 40+MB, well we have at least 64MB, still
enough.
# cat bos
bo[0000]: size: 8112kB VRAM
bo[0001]: size: 16kB VRAM
bo[0002]: size: 16kB VRAM
bo[0003]: size: 16208kB VRAM
bo[0004]: size: 8112kB VRAM
bo[0005]: size: 8112kB VRAM
v8 -> v9:
1) Select I2C and I2C_ALGOBIT in Kconfig and should depend on MMU.
2) Using pci_get_domain_bus_and_slot to get the GPU device.
3) Other minor improvements.
Those patches are tested on ls3a5000 + ls7a1000 CRB, ls3a5000 + ls7a2000
evb, and lemote a1901 board(ls3a4000 + ls7a1000). On loongson mips CPU,
the write combine support should be enabled, to get a decent performance
for writing framebuffer data to the VRAM.
v9 -> v10:
1) Revise lsdc_drm_freeze() to implement S3 completely and correctly.
I suddenly realized that pinned buffer can not move and VRAM lost
power when sleep to RAM. Thus, the data in the buffer who is pinned
in VRAM will get lost when resume. Yet it's not big problem because
we are software rendering solution which relay on the CPU update the
front framebuffer. We can see the garbage data when resume from S3,
but the screen will show correct image as I move the cursor. This is
due to the cpu repaint. v10 of this patch make S3 perfect by unpin
all of BOs in VRAM, evict them all to system RAM.
v10 -> v11:
1) On double screen case, the single giant framebuffer is referenced by
two GEM object, hence, it will be pinned by prepare_fb() at lease two
times. This cause its pin count > 1. V10 of this patch only unpin VRAM
BOs once when suspend, which is not correct on double screen case. V11
of this patch unpin BOs until its pin count reach to zero when suspend.
Then, we make the S3 support complete finally. With v11, I can't see
any garbage data after resume. Tested on both ls7a1000 and ls7a2000
platform, with single screen and double screen configuration.
2) Fix vblank wait timeout when disable CRTC.
3) Test against IGT, at least fbdev test and kms_flip test passed.
4) Rewrite pixel PLL update function, magic numbers eliminated (Emil)
5) Drop a few common hardware features description in lsdc_desc (Emil)
6) Drop lsdc_mode_config_mode_valid(), instead add restrictions in dumb
create function. (Emil)
7) Untangle the ls7a1000 case and ls7a2000 case completely (Thomas)
v11 -> v12:
none
v12 -> v13:
1) Add benchmark to figure out the bandwidth of the hardware platform.
Usage:
# cd /sys/kernel/debug/dri/0/
# cat benchmark
2) VRAM is filled with garbage data if uninitialized, add a buffer
clearing procedure, clear it on the BO creation time.
3) Update copyrights and adjust coding style (Huacai)
v13 -> v14:
1) Trying to add async update support for cursor plane.
Sui Jingfeng (2):
drm: add kms driver for loongson display controller
MAINTAINERS: add maintainers for DRM LOONGSON driver
MAINTAINERS | 8 +
drivers/gpu/drm/Kconfig | 2 +
drivers/gpu/drm/Makefile | 1 +
drivers/gpu/drm/loongson/Kconfig | 17 +
drivers/gpu/drm/loongson/Makefile | 20 +
drivers/gpu/drm/loongson/lsdc_benchmark.c | 133 ++
drivers/gpu/drm/loongson/lsdc_benchmark.h | 13 +
drivers/gpu/drm/loongson/lsdc_crtc.c | 1066 +++++++++++++++++
drivers/gpu/drm/loongson/lsdc_debugfs.c | 91 ++
drivers/gpu/drm/loongson/lsdc_device.c | 104 ++
drivers/gpu/drm/loongson/lsdc_drv.c | 495 ++++++++
drivers/gpu/drm/loongson/lsdc_drv.h | 451 +++++++
drivers/gpu/drm/loongson/lsdc_gem.c | 324 +++++
drivers/gpu/drm/loongson/lsdc_gem.h | 37 +
drivers/gpu/drm/loongson/lsdc_gfxpll.c | 199 +++
drivers/gpu/drm/loongson/lsdc_gfxpll.h | 52 +
drivers/gpu/drm/loongson/lsdc_i2c.c | 179 +++
drivers/gpu/drm/loongson/lsdc_i2c.h | 29 +
drivers/gpu/drm/loongson/lsdc_irq.c | 71 ++
drivers/gpu/drm/loongson/lsdc_irq.h | 16 +
drivers/gpu/drm/loongson/lsdc_output.h | 21 +
drivers/gpu/drm/loongson/lsdc_output_7a1000.c | 161 +++
drivers/gpu/drm/loongson/lsdc_output_7a2000.c | 531 ++++++++
drivers/gpu/drm/loongson/lsdc_pixpll.c | 481 ++++++++
drivers/gpu/drm/loongson/lsdc_pixpll.h | 86 ++
drivers/gpu/drm/loongson/lsdc_plane.c | 781 ++++++++++++
drivers/gpu/drm/loongson/lsdc_probe.c | 56 +
drivers/gpu/drm/loongson/lsdc_probe.h | 12 +
drivers/gpu/drm/loongson/lsdc_regs.h | 402 +++++++
drivers/gpu/drm/loongson/lsdc_ttm.c | 610 ++++++++++
drivers/gpu/drm/loongson/lsdc_ttm.h | 99 ++
31 files changed, 6548 insertions(+)
create mode 100644 drivers/gpu/drm/loongson/Kconfig
create mode 100644 drivers/gpu/drm/loongson/Makefile
create mode 100644 drivers/gpu/drm/loongson/lsdc_benchmark.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_benchmark.h
create mode 100644 drivers/gpu/drm/loongson/lsdc_crtc.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_debugfs.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_device.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_drv.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_drv.h
create mode 100644 drivers/gpu/drm/loongson/lsdc_gem.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_gem.h
create mode 100644 drivers/gpu/drm/loongson/lsdc_gfxpll.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_gfxpll.h
create mode 100644 drivers/gpu/drm/loongson/lsdc_i2c.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_i2c.h
create mode 100644 drivers/gpu/drm/loongson/lsdc_irq.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_irq.h
create mode 100644 drivers/gpu/drm/loongson/lsdc_output.h
create mode 100644 drivers/gpu/drm/loongson/lsdc_output_7a1000.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_output_7a2000.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_pixpll.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_pixpll.h
create mode 100644 drivers/gpu/drm/loongson/lsdc_plane.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_probe.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_probe.h
create mode 100644 drivers/gpu/drm/loongson/lsdc_regs.h
create mode 100644 drivers/gpu/drm/loongson/lsdc_ttm.c
create mode 100644 drivers/gpu/drm/loongson/lsdc_ttm.h
--
2.25.1