RE: [PATCH 0/5] udmbuf bug fix and some improvements
Hi Huan, > This patchset attempts to fix some errors in udmabuf and remove the > upin_list structure. > > Some of this fix just gather the patches which I upload before. > > Patch1 > === > Try to remove page fault mmap and direct map it. > Due to current udmabuf has already obtained and pinned the folio > upon completion of the creation.This means that the physical memory has > already been acquired, rather than being accessed dynamically. The > current page fault method only saves some page table memory. > > As a result, the page fault mechanism has lost its purpose as a demanding > page. Due to the fact that page fault requires trapping into kernel mode > and filling in when accessing the corresponding virtual address in mmap, > this means that user mode access to virtual addresses needs to trap into > kernel mode. > > Therefore, when creating a large size udmabuf, this represents a > considerable overhead. Just want to mention that for the main use-case the udmabuf driver is designed for, (sharing Qemu Guest FB with Host for GPU DMA), udmabufs are not created very frequently. And, I think providing CPU access via mmap is just a backup, mainly intended for debugging purposes. > > Therefore, the current patch removes the page fault method of mmap and > instead fills it directly when mmap is triggered. > > This is achieved by using the scatter-gather table to establish a > linear relationship for the page. Calling remap_pfn_range does not cause > the previously set VMA flags to become invalid. > > Patch2 > === > This is the same to patch: > https://lore.kernel.org/all/20240725021349.580574-1-l...@vivo.com/ > I just gather it to this patchset. > > Patch3 > === > The current implementation of udmabuf's vmap has issues. > > It does not correctly set each page of the folio to the page structure, > so that when vmap is called, all pages are the head page of the folio. > > This implementation is not the same as this patch: > https://lore.kernel.org/all/20240731090233.1343559-1-l...@vivo.com/ > > This reuse sgt table to map all page into vmalloc area. > > Patch4 > === > Wrap the repeated calls to get_sg_table, add a helper function to do it. > Set to udmabuf->sg use cmpxchg, It should be able to prevent concurrent > access situations. (I see mmap do not use lock) > > Patch5 > === > Attempt to remove unpin_list and other related data structures. > > In order to adapt to Folio, we established the unpin_list data structure > to unpin all folios and maintain the page mapping relationship. > > However, this data structure requires 24 bytes for each page and has low > traversal performance for the list. And maintaining the offset structure > also consumes a portion of memory. > > This patch attempts to remove these data structures and modify the > semantics of some existing data structures. > > udmabuf: > folios -> folios array, which only contain's the folio, org contains > duplicate. > add item_offset -> base on create item count, record it's start offset > in every memfd. > add item_size -> base on create item count, record it's size in every > memfd. > add nr_folios -> folios array number I am not sure if these changes improve the readability. Instead, I think it makes sense to add comments to the existing code. > > So, when building the sg table, it is necessary to iterate in this way: > if size cross item->size, take care of it's start offset in folio. > if got folio, set each page into sgl until reach into folio size. > > This patch also remove single folios' create on each create item, use it > be the ubuf->folios arrays' pointer, slide to fill the corresponding > folio under the item into the array. > > After the modification, the various data structures in udmabuf have the > following corresponding relationships: > pagecount * PAGESIZE = sum(folios_size(folios[i])) i=0->nr_folios > pagecount * PAGESIZE = sum(item_size[i]) i=0, item_count (do not > record) > item_offset use to record each memfd offset if exist, else 0. > > Huan Yang (5): > udmabuf: cancel mmap page fault, direct map it > udmabuf: change folios array from kmalloc to kvmalloc > udmabuf: fix vmap_udmabuf error page set Do you have a test-case to test this patch? > udmabuf: add get_sg_table helper function > udmabuf: remove folio pin list Please run the newly added udmabuf selftests to make sure that these patches are not causing any regressions. And, we also need to make sure that the main use-cases (Qemu with memfd + shmem and Qemu with memfd + hugetlb) are working as expected given the invasive changes. I'll be able to test and provide more detailed feedback on all patches once I am back from vacation late next week. Thanks, Vivek > > drivers/dma-buf/udmabuf.c | 270 +- > 1 file changed, 148 insertions(+), 122 deletions(-) > > > base-commit: cd19ac2f903276b820f5d0d89de0c896c27036ed > -- > 2.45.2
[PATCH 2/2] drm/vmwgfx: Fix prime with external buffers
Make sure that for external buffers mapping goes through the dma_buf interface instead of trying to access pages directly. External buffers might not provide direct access to readable/writable pages so to make sure the bo's created from external dma_bufs can be read dma_buf interface has to be used. Fixes crashes in IGT's kms_prime with vgem. Regular desktop usage won't trigger this due to the fact that virtual machines will not have multiple GPUs but it enables better test coverage in IGT. Signed-off-by: Zack Rusin Fixes: b32233acceff ("drm/vmwgfx: Fix prime import/export") Cc: # v6.6+ Cc: Broadcom internal kernel review list Cc: dri-devel@lists.freedesktop.org Cc: # v6.9+ --- drivers/gpu/drm/vmwgfx/vmwgfx_blit.c | 112 ++- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 12 +-- 3 files changed, 116 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c index 717d624e9a05..3140414d027e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c @@ -27,6 +27,8 @@ **/ #include "vmwgfx_drv.h" + +#include "vmwgfx_bo.h" #include /* @@ -420,13 +422,103 @@ static int vmw_bo_cpu_blit_line(struct vmw_bo_blit_line_data *d, return 0; } +static void *map_external(struct vmw_bo *bo, struct iosys_map *map) +{ + struct vmw_private *vmw = + container_of(bo->tbo.bdev, struct vmw_private, bdev); + void *ptr = NULL; + int ret; + + if (bo->tbo.base.import_attach) { + ret = dma_buf_vmap(bo->tbo.base.dma_buf, map); + if (ret) { + drm_dbg_driver(>drm, + "Wasn't able to map external bo!\n"); + goto out; + } + ptr = map->vaddr; + } else { + ptr = vmw_bo_map_and_cache(bo); + } + +out: + return ptr; +} + +static void unmap_external(struct vmw_bo *bo, struct iosys_map *map) +{ + if (bo->tbo.base.import_attach) + dma_buf_vunmap(bo->tbo.base.dma_buf, map); + else + vmw_bo_unmap(bo); +} + +static int vmw_external_bo_copy(struct vmw_bo *dst, u32 dst_offset, + u32 dst_stride, struct vmw_bo *src, + u32 src_offset, u32 src_stride, + u32 width_in_bytes, u32 height, + struct vmw_diff_cpy *diff) +{ + struct vmw_private *vmw = + container_of(dst->tbo.bdev, struct vmw_private, bdev); + size_t dst_size = dst->tbo.resource->size; + size_t src_size = src->tbo.resource->size; + struct iosys_map dst_map = {0}; + struct iosys_map src_map = {0}; + int ret, i; + u8 *vsrc; + u8 *vdst; + + vsrc = map_external(src, _map); + if (!vsrc) { + drm_dbg_driver(>drm, "Wasn't able to map src\n"); + ret = -ENOMEM; + goto out; + } + + vdst = map_external(dst, _map); + if (!vdst) { + drm_dbg_driver(>drm, "Wasn't able to map dst\n"); + ret = -ENOMEM; + goto out; + } + + vsrc += src_offset; + vdst += dst_offset; + if (src_stride == dst_stride) { + dst_size -= dst_offset; + src_size -= src_offset; + memcpy(vdst, vsrc, + min(dst_stride * height, min(dst_size, src_size))); + } else { + WARN_ON(dst_stride < width_in_bytes); + for (i = 0; i < height; ++i) { + memcpy(vdst, vsrc, width_in_bytes); + vsrc += src_stride; + vdst += dst_stride; + } + } + + diff->rect.y1 = dst_offset % dst_stride; + diff->rect.x1 = (dst_offset - dst_offset * diff->rect.y1) / diff->cpp; + diff->rect.x2 = diff->rect.x1 + width_in_bytes / diff->cpp; + diff->rect.y2 = diff->rect.y1 + height; + + ret = 0; +out: + unmap_external(src, _map); + unmap_external(dst, _map); + + return ret; +} + /** * vmw_bo_cpu_blit - in-kernel cpu blit. * - * @dst: Destination buffer object. + * @vmw_dst: Destination buffer object. * @dst_offset: Destination offset of blit start in bytes. * @dst_stride: Destination stride in bytes. - * @src: Source buffer object. + * @vmw_src: Source buffer object. * @src_offset: Source offset of blit start in bytes. * @src_stride: Source stride in bytes. * @w: Width of blit. @@ -444,13 +536,15 @@ static int vmw_bo_cpu_blit_line(struct vmw_bo_blit_line_data *d, * Neither of the buffer objects may be placed in PCI memory * (Fixed memory in TTM terminology) when using this function. */ -int vmw_bo_cpu_blit(struct
[PATCH 1/2] drm/vmwgfx: Prevent unmapping active read buffers
The kms paths keep a persistent map active to read and compare the cursor buffer. These maps can race with each other in simple scenario where: a) buffer "a" mapped for update b) buffer "a" mapped for compare c) do the compare d) unmap "a" for compare e) update the cursor f) unmap "a" for update At step "e" the buffer has been unmapped and the read contents is bogus. Prevent unmapping of active read buffers by simply keeping a count of how many paths have currently active maps and unmap only when the count reaches 0. Fixes: 485d98d472d5 ("drm/vmwgfx: Add support for CursorMob and CursorBypass 4") Cc: Broadcom internal kernel review list Cc: dri-devel@lists.freedesktop.org Cc: # v5.19+ Signed-off-by: Zack Rusin --- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 13 +++-- drivers/gpu/drm/vmwgfx/vmwgfx_bo.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c index f42ebc4a7c22..a0e433fbcba6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -360,6 +360,8 @@ void *vmw_bo_map_and_cache_size(struct vmw_bo *vbo, size_t size) void *virtual; int ret; + atomic_inc(>map_count); + virtual = ttm_kmap_obj_virtual(>map, _used); if (virtual) return virtual; @@ -383,11 +385,17 @@ void *vmw_bo_map_and_cache_size(struct vmw_bo *vbo, size_t size) */ void vmw_bo_unmap(struct vmw_bo *vbo) { + int map_count; + if (vbo->map.bo == NULL) return; - ttm_bo_kunmap(>map); - vbo->map.bo = NULL; + map_count = atomic_dec_return(>map_count); + + if (!map_count) { + ttm_bo_kunmap(>map); + vbo->map.bo = NULL; + } } @@ -421,6 +429,7 @@ static int vmw_bo_init(struct vmw_private *dev_priv, vmw_bo->tbo.priority = 3; vmw_bo->res_tree = RB_ROOT; xa_init(_bo->detached_resources); + atomic_set(_bo->map_count, 0); params->size = ALIGN(params->size, PAGE_SIZE); drm_gem_private_object_init(vdev, _bo->tbo.base, params->size); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h index 62b4342d5f7c..dc13f1e996c1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h @@ -90,6 +90,7 @@ struct vmw_bo { u32 res_prios[TTM_MAX_BO_PRIORITY]; struct xarray detached_resources; + atomic_t map_count; atomic_t cpu_writers; /* Not ref-counted. Protected by binding_mutex */ struct vmw_resource *dx_query_ctx; -- 2.43.0
[PATCH v2] drm: Add documentation for struct drm_pane_size_hint
Fixed warning for the following: ./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct member 'width' not described in 'drm_plane_size_hint' ./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct member 'height' not described in 'drm_plane_size_hint' Signed-off-by: abid-sayyad --- My sincere apologies for the spam and the patch subject error Changes in v2: - Adress review feedback regarding indentation in the fix - Link to v1 https://lore.kernel.org/all/20240801102239.572718-1-sayyad.abi...@gmail.com/ include/uapi/drm/drm_mode.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index d390011b89b4..9d398335d871 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -864,7 +864,13 @@ struct drm_color_lut { * array of struct drm_plane_size_hint. */ struct drm_plane_size_hint { + /** +* @width: width of the plane in pixels. +*/ __u16 width; + /** +* @height: height of the plane in pixels. +*/ __u16 height; }; -- 2.39.2
[PATCH] [PATCH v2] drm: Add documentation for struct drm_pane_size_hint
Fixed warning for the following: ./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct member 'width' not described in 'drm_plane_size_hint' ./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct member 'height' not described in 'drm_plane_size_hint' Signed-off-by: abid-sayyad --- Changes in v2: - Adress review feedback regarding indentation in the fix - Link to v1 https://lore.kernel.org/all/20240801102239.572718-1-sayyad.abi...@gmail.com/ include/uapi/drm/drm_mode.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index d390011b89b4..9d398335d871 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -864,7 +864,13 @@ struct drm_color_lut { * array of struct drm_plane_size_hint. */ struct drm_plane_size_hint { + /** +* @width: width of the plane in pixels. +*/ __u16 width; + /** +* @height: height of the plane in pixels. +*/ __u16 height; }; -- 2.39.2
Re: [PATCH] drm: bridge: adv7511: Accept audio sample widths of 32 bits via I2S
On Mon, Jul 29, 2024 at 10:15:55AM +0200, Ricard Wanderlof wrote: > > Hi, > > I submitted the patch below a while ago (two months) but as far as I can > make out it has not been included. There was an initial concern from > Dmitry Baryshkov which was subsequently addressed but no other objections. > > On Tue, 28 May 2024, Ricard Wanderlof wrote: > > > > > Even though data is truncated to 24 bits, the I2S interface does > > accept 32 bit data (the slot widths according to the data sheet > > can be 16 or 32 bits) so let the hw_params callback reflect this, > > even if the lowest 8 bits are not used when 32 bits are specified. > > > > This is normally how 24 bit audio data is handled (i.e. as 32 bit > > data, with the LSB:s unused) and this is also reflected in other > > bridge drivers which handle audio, for instance sii902x.c and > > synopsis/dw-hdmi-i2s-audio.c . > > > > Signed-off-by: Ricard Wanderlof > > --- > > drivers/gpu/drm/bridge/adv7511/adv7511_audio.c | 11 +++ > > 1 file changed, 7 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c > > b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c > > index 61f4a38e7d2b..4563f5d8136f 100644 > > --- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c > > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c > > @@ -101,11 +101,14 @@ static int adv7511_hdmi_hw_params(struct device *dev, > > void *data, > > case 20: > > len = ADV7511_I2S_SAMPLE_LEN_20; > > break; > > - case 32: > > - if (fmt->bit_fmt != SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE) > > - return -EINVAL; > > - fallthrough; > > case 24: > > + case 32: > > + /* > > +* 32 bits are handled like 24 bits, except that the lowest > > +* 8 bits are discarded. In fact, the accepted I2S slot widths > > +* are 16 and 32 bits, so the chip is fully compatible with > > +* 32 bit data. > > +*/ > > len = ADV7511_I2S_SAMPLE_LEN_24; > > break; > > default: > > I recently discovered that the maintainer for the ADV7511 driver (in the > I2C) framework is not included by the get_maintainers script, so perhaps > this is the reason? > > Otherwise, please enlighten me on what I need to do to get this patch > accepted! I have no experience with HDMI audio, so I didn't comment on your patch. Hans, is this within your area of expertise ? -- Regards, Laurent Pinchart
[Bug 219117] amdgpu: amdgpu_device_ip_init failed
https://bugzilla.kernel.org/show_bug.cgi?id=219117 Artem S. Tashkinov (a...@gmx.com) changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |ANSWERED --- Comment #1 from Artem S. Tashkinov (a...@gmx.com) --- Please report here instead: https://gitlab.freedesktop.org/drm/amd/-/issues -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
[Bug 219118] Linux 6.10.x [drm:amdgpu_job_timedout [amdgpu]] *ERROR* ring gfx timeout VM fault / GPU fault detected
https://bugzilla.kernel.org/show_bug.cgi?id=219118 Artem S. Tashkinov (a...@gmx.com) changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |ANSWERED --- Comment #1 from Artem S. Tashkinov (a...@gmx.com) --- Please report here instead: https://gitlab.freedesktop.org/drm/amd/-/issues -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
Re: [PATCH 0/2] Use pcim_request_region() in vboxvideo
On Mon, Jul 29, 2024 at 11:36:24AM +0200, Philipp Stanner wrote: > Hi everyone, > > Now that we've got the simplified PCI devres API available we can slowly > start using it in drivers and step by step phase the more problematic > API out. > > vboxvideo currently does not have a region request, so it is a suitable > first user. > > P. > > Philipp Stanner (2): > PCI: Make pcim_request_region() a public function > drm/vboxvideo: Add PCI region request > > drivers/gpu/drm/vboxvideo/vbox_main.c | 4 > drivers/pci/devres.c | 1 + > drivers/pci/pci.h | 2 -- > include/linux/pci.h | 1 + > 4 files changed, 6 insertions(+), 2 deletions(-) Applied with Hans' ack to pci/devres for v6.12, thanks!
Re: [PATCH 0/2] Add MSM8996/MSM8953 dpu catalog
Should i resend this patch set? On June 28, 2024 4:39:38 PM GMT+02:00, "Barnabás Czémán" wrote: >This patch series add dpu support for MSM8996/MSM8953 devices. > >Note, by default these platforms are still handled by the MDP5 driver >unless the `msm.prefer_mdp5=false' parameter is provided. > >Signed-off-by: Barnabás Czémán >--- >Dmitry Baryshkov (1): > drm/msm/dpu: add support for MSM8953 > >Konrad Dybcio (1): > drm/msm/dpu: Add MSM8996 support > > .../drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h | 218 + > .../drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h| 348 + > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 106 +++ > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 + > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 2 + > drivers/gpu/drm/msm/msm_drv.c | 2 + > 6 files changed, 678 insertions(+) >--- >base-commit: df9574a57d02b265322e77fb8628d4d33641dda9 >change-id: 20240528-dpu-msm8953-msm8996-5d0fb7e387b8 > >Best regards,
[Bug 219118] New: Linux 6.10.x [drm:amdgpu_job_timedout [amdgpu]] *ERROR* ring gfx timeout VM fault / GPU fault detected
https://bugzilla.kernel.org/show_bug.cgi?id=219118 Bug ID: 219118 Summary: Linux 6.10.x [drm:amdgpu_job_timedout [amdgpu]] *ERROR* ring gfx timeout VM fault / GPU fault detected Product: Drivers Version: 2.5 Hardware: All OS: Linux Status: NEW Severity: high Priority: P3 Component: Video(DRI - non Intel) Assignee: drivers_video-...@kernel-bugs.osdl.org Reporter: mjevans1...@gmail.com Regression: No I'm not sure if this should be filed under Console/Framebuffers, Video(DRI - non Intel), or Video(Other). I thought I'd created the bug in the correct location, https://gitlab.freedesktop.org/drm/amd/-/issues/3510 but no maintainer has commented or otherwise notably interacted with the report. Initially I thought it was just an MPV bug since VLC didn't trigger the issue https://github.com/mpv-player/mpv/issues/14600 . It looks like a developer's personal(?) drm-fixes-6.11 branch cherry picked the commit that appeared to fix the issue completely for my test cases: https://gitlab.freedesktop.org/agd5f/linux/-/commit/f3572db3c049b4d32bb5ba77ad5305616c44c7c1 However that isn't for the earlier 6.10.x series which also needs the fix, unless it's dead. This appears to be a Swiss cheese sort of bug situation. If software requests/provides contiguous buffers then the error results are more subtle, such as momentary video corruption if the kernel's access isn't out of bounds but rather rarely scrambled. It's only when both the userspace and driver don't enforce contiguous buffer segments that out of bounds accesses result in a GPU reset and consequently terminated userspace. ArchLinux (rolling release) Linux 6.10.1-arch1-1 #1 (closed) SMP PREEMPT_DYNAMIC Wed, 24 Jul 2024 22:25:43 + x86_64 GNU/Linux amdgpu + OpenGL version string: 4.6 (Compatibility Profile) Mesa 24.1.4-arch1.2 ArchLinux current stable builds [ 1766.321165] amdgpu :01:00.0: amdgpu: GPU fault detected: 147 0x0a22c802 [ 1766.321171] amdgpu :01:00.0: amdgpu: for process plasmashell pid 2961 thread plasmashel:cs0 pid 3007 [ 1766.321172] amdgpu :01:00.0: amdgpu: VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x00101F44 [ 1766.321174] amdgpu :01:00.0: amdgpu: VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x0B0C8002 [ 1766.321175] amdgpu :01:00.0: amdgpu: VM fault (0x02, vmid 5, pasid 32772) at page 1056580, write from 'TC3' (0x54433300) (200) [ 1766.321237] amdgpu :01:00.0: amdgpu: GPU fault detected: 147 0x07f2a002 [ 1766.321238] amdgpu :01:00.0: amdgpu: for process plasmashell pid 2961 thread plasmashel:cs0 pid 3007 [ 1766.321239] amdgpu :01:00.0: amdgpu: VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x0010120C [ 1766.321240] amdgpu :01:00.0: amdgpu: VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x0B020002 [ 1766.321241] amdgpu :01:00.0: amdgpu: VM fault (0x02, vmid 5, pasid 32772) at page 1053196, write from 'CB2' (0x43423200) (32) [ 1766.321244] amdgpu :01:00.0: amdgpu: GPU fault detected: 147 0x07b29002 [ 1766.321245] amdgpu :01:00.0: amdgpu: for process plasmashell pid 2961 thread plasmashel:cs0 pid 3007 [ 1766.321247] amdgpu :01:00.0: amdgpu: VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x00101237 [ 1766.321247] amdgpu :01:00.0: amdgpu: VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x0B010002 [ 1766.321248] amdgpu :01:00.0: amdgpu: VM fault (0x02, vmid 5, pasid 32772) at page 1053239, write from 'CB3' (0x43423300) (16) [ 1766.321255] amdgpu :01:00.0: amdgpu: GPU fault detected: 147 0x0772e002 [ 1766.321256] amdgpu :01:00.0: amdgpu: for process plasmashell pid 2961 thread plasmashel:cs0 pid 3007 [ 1766.321257] amdgpu :01:00.0: amdgpu: VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x00101200 [ 1766.321258] amdgpu :01:00.0: amdgpu: VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x0B0A0002 [ 1766.321258] amdgpu :01:00.0: amdgpu: VM fault (0x02, vmid 5, pasid 32772) at page 1053184, write from 'CB4' (0x43423400) (160) [ 1766.321262] amdgpu :01:00.0: amdgpu: GPU fault detected: 147 0x0772d002 [ 1766.321263] amdgpu :01:00.0: amdgpu: for process plasmashell pid 2961 thread plasmashel:cs0 pid 3007 [ 1766.321264] amdgpu :01:00.0: amdgpu: VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x00101232 [ 1766.321264] amdgpu :01:00.0: amdgpu: VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x0B0A0002 [ 1766.321265] amdgpu :01:00.0: amdgpu: VM fault (0x02, vmid 5, pasid 32772) at page 1053234, write from 'CB4' (0x43423400) (160) [ 1766.321268] amdgpu :01:00.0: amdgpu: GPU fault detected: 147 0x07729002 [ 1766.321269] amdgpu :01:00.0: amdgpu: for process plasmashell pid 2961 thread plasmashel:cs0 pid 3007 [ 1766.321271] amdgpu :01:00.0: amdgpu: VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x0010123A [ 1766.321271] amdgpu :01:00.0: amdgpu: VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x0B050002 [ 1766.321272] amdgpu :01:00.0: amdgpu: VM fault (0x02, vmid 5, pasid 32772) at
Re: [PATCH 3/4] drm/msm/a5xx: fix races in preemption evaluation stage
On Thu, Aug 1, 2024 at 3:26 PM Vladimir Lypak wrote: > > On Thu, Aug 01, 2024 at 01:52:32PM +0100, Connor Abbott wrote: > > On Thu, Aug 1, 2024 at 1:25 PM Vladimir Lypak > > wrote: > > > > > > On Mon, Jul 29, 2024 at 06:26:45PM +0100, Connor Abbott wrote: > > > > On Thu, Jul 11, 2024 at 11:10 AM Vladimir Lypak > > > > wrote: > > > > > > > > > > On A5XX GPUs when preemption is used it's invietable to enter a soft > > > > > lock-up state in which GPU is stuck at empty ring-buffer doing > > > > > nothing. > > > > > This appears as full UI lockup and not detected as GPU hang (because > > > > > it's not). This happens due to not triggering preemption when it was > > > > > needed. Sometimes this state can be recovered by some new submit but > > > > > generally it won't happen because applications are waiting for old > > > > > submits to retire. > > > > > > > > > > One of the reasons why this happens is a race between a5xx_submit and > > > > > a5xx_preempt_trigger called from IRQ during submit retire. Former > > > > > thread > > > > > updates ring->cur of previously empty and not current ring right after > > > > > latter checks it for emptiness. Then both threads can just exit > > > > > because > > > > > for first one preempt_state wasn't NONE yet and for second one all > > > > > rings > > > > > appeared to be empty. > > > > > > > > > > To prevent such situations from happening we need to establish > > > > > guarantee > > > > > for preempt_trigger to be called after each submit. To implement it > > > > > this > > > > > patch adds trigger call at the end of a5xx_preempt_irq to re-check if > > > > > we > > > > > should switch to non-empty or higher priority ring. Also we find next > > > > > ring in new preemption state "EVALUATE". If the thread that updated > > > > > some > > > > > ring with new submit sees this state it should wait until it passes. > > > > > > > > > > Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets") > > > > > Signed-off-by: Vladimir Lypak > > > > > --- > > > > > drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 6 +++--- > > > > > drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 11 +++ > > > > > drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 24 > > > > > +++ > > > > > 3 files changed, 30 insertions(+), 11 deletions(-) > > > > > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > > > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > > > > index 6c80d3003966..266744ee1d5f 100644 > > > > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > > > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > > > > @@ -110,7 +110,7 @@ static void a5xx_submit_in_rb(struct msm_gpu > > > > > *gpu, struct msm_gem_submit *submit > > > > > } > > > > > > > > > > a5xx_flush(gpu, ring, true); > > > > > - a5xx_preempt_trigger(gpu); > > > > > + a5xx_preempt_trigger(gpu, true); > > > > > > > > > > /* we might not necessarily have a cmd from userspace to > > > > > * trigger an event to know that submit has completed, so > > > > > @@ -240,7 +240,7 @@ static void a5xx_submit(struct msm_gpu *gpu, > > > > > struct msm_gem_submit *submit) > > > > > a5xx_flush(gpu, ring, false); > > > > > > > > > > /* Check to see if we need to start preemption */ > > > > > - a5xx_preempt_trigger(gpu); > > > > > + a5xx_preempt_trigger(gpu, true); > > > > > } > > > > > > > > > > static const struct adreno_five_hwcg_regs { > > > > > @@ -1296,7 +1296,7 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu) > > > > > a5xx_gpmu_err_irq(gpu); > > > > > > > > > > if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS) { > > > > > - a5xx_preempt_trigger(gpu); > > > > > + a5xx_preempt_trigger(gpu, false); > > > > > msm_gpu_retire(gpu); > > > > > } > > > > > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > > > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > > > > index c7187bcc5e90..1120824853d4 100644 > > > > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > > > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > > > > @@ -57,10 +57,12 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, > > > > > struct drm_minor *minor); > > > > > * through the process. > > > > > * > > > > > * PREEMPT_NONE - no preemption in progress. Next state START. > > > > > - * PREEMPT_START - The trigger is evaulating if preemption is > > > > > possible. Next > > > > > - * states: TRIGGERED, NONE > > > > > + * PREEMPT_EVALUATE - The trigger is evaulating if preemption is > > > > > possible. Next > > > > > + * states: START, ABORT > > > > > * PREEMPT_ABORT - An intermediate state before moving back to NONE. > > > > > Next > > > > > * state: NONE. > > > > > + * PREEMPT_START - The trigger is preparing for preemption. Next > > > > > state: > > > > > + * TRIGGERED > > > > > * PREEMPT_TRIGGERED: A preemption has been executed on the > > > > > hardware. Next > >
[PATCH] drm/i915/gt: Delete sysfs entries for engines on driver unload
While the sysfs entries for engines are added in intel_engines_init() during driver load, the corresponding function intel_engines_release() does not correctly get rid of them. This can lead to a UAF if, after failed initialization (for example when gt is set wedged on init), we try to access the engines. Empty the engines llist in intel_engines_release(). Suggested-by: Chris Wilson Signed-off-by: Krzysztof Niemiec --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 3b740ca25000..4d30a86016f2 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -693,6 +693,8 @@ void intel_engines_release(struct intel_gt *gt) memset(>reset, 0, sizeof(engine->reset)); } + + llist_del_all(>i915->uabi_engines_llist); } void intel_engine_free_request_pool(struct intel_engine_cs *engine) -- 2.45.2
[PATCH v5 2/3] drm/printer: Allow NULL data in devcoredump printer
We want to determine the size of the devcoredump before writing it out. To that end, we will run the devcoredump printer with NULL data to get the size, alloc data based on the generated offset, then run the devcorecump again with a valid data pointer to print. This necessitates not writing data to the data pointer on the initial pass, when it is NULL. v5: - Better commit message (Jonathan) - Add kerenl doc with examples (Jani) Cc: Maarten Lankhorst Acked-by: Maarten Lankhorst Signed-off-by: Matthew Brost Reviewed-by: Jonathan Cavitt --- drivers/gpu/drm/drm_print.c | 13 + include/drm/drm_print.h | 54 - 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c index cf24dfdeb6b2..a1a4de9f9c44 100644 --- a/drivers/gpu/drm/drm_print.c +++ b/drivers/gpu/drm/drm_print.c @@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, const char *str) copy = iterator->remain; /* Copy out the bit of the string that we need */ - memcpy(iterator->data, - str + (iterator->start - iterator->offset), copy); + if (iterator->data) + memcpy(iterator->data, + str + (iterator->start - iterator->offset), copy); iterator->offset = iterator->start + copy; iterator->remain -= copy; @@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, const char *str) len = min_t(ssize_t, strlen(str), iterator->remain); - memcpy(iterator->data + pos, str, len); + if (iterator->data) + memcpy(iterator->data + pos, str, len); iterator->offset += len; iterator->remain -= len; @@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf) if ((iterator->offset >= iterator->start) && (len < iterator->remain)) { ssize_t pos = iterator->offset - iterator->start; - snprintf(((char *) iterator->data) + pos, - iterator->remain, "%pV", vaf); + if (iterator->data) + snprintf(((char *) iterator->data) + pos, + iterator->remain, "%pV", vaf); iterator->offset += len; iterator->remain -= len; diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 5d9dff5149c9..d2676831d765 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -221,7 +221,8 @@ drm_vprintf(struct drm_printer *p, const char *fmt, va_list *va) /** * struct drm_print_iterator - local struct used with drm_printer_coredump - * @data: Pointer to the devcoredump output buffer + * @data: Pointer to the devcoredump output buffer, can be NULL if using + * drm_printer_coredump to determine size of devcoredump * @start: The offset within the buffer to start writing * @remain: The number of bytes to write for this iteration */ @@ -266,6 +267,57 @@ struct drm_print_iterator { * coredump_read, ...) * } * + * The above example has a time complexity of O(N^2), where N is the size of the + * devcoredump. This is acceptable for small devcoredumps but scales poorly for + * larger ones. + * + * Another use case for drm_coredump_printer is to capture the devcoredump into + * a saved buffer before the dev_coredump() callback. This involves two passes: + * one to determine the size of the devcoredump and another to print it to a + * buffer. Then, in dev_coredump(), copy from the saved buffer into the + * devcoredump read buffer. + * + * For example:: + * + * char *devcoredump_saved_buffer; + * + * ssize_t __coredump_print(char *buffer, ssize_t count, ...) + * { + * struct drm_print_iterator iter; + * struct drm_printer p; + * + * iter.data = buffer; + * iter.start = 0; + * iter.remain = count; + * + * p = drm_coredump_printer(); + * + * drm_printf(p, "foo=%d\n", foo); + * ... + * return count - iter.remain; + * } + * + * void coredump_print(...) + * { + * ssize_t count; + * + * count = __coredump_print(NULL, INT_MAX, ...); + * devcoredump_saved_buffer = kvmalloc(count, GFP_KERNEL); + * __coredump_print(devcoredump_saved_buffer, count, ...); + * } + * + * void coredump_read(char *buffer, loff_t offset, size_t count, + *void *data, size_t datalen) + * { + * ... + * memcpy(buffer, devcoredump_saved_buffer + offset, count); + * ... + * } + * + * The above example has a time complexity of O(N*2), where N is the size of the + * devcoredump. This scales better than the previous example for
[PATCH v5 3/3] drm/xe: Faster devcoredump
The current algorithm to read out devcoredump is O(N*N) where N is the size of coredump due to usage of the drm_coredump_printer in xe_devcoredump_read. Switch to a O(N) algorithm which prints the devcoredump into a readable format in snapshot work and update xe_devcoredump_read to memcpy from the readable format directly. v2: - Fix double free on devcoredump removal (Testing) - Set read_data_size after snap work flush - Adjust remaining in iterator upon realloc (Testing) - Set read_data upon realloc (Testing) v3: - Kernel doc v4: - Two pass algorithm to determine size (Maarten) v5: - Use scope for reading variables (Johnathan) Reported-by: Paulo Zanoni Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2408 Cc: Rodrigo Vivi Cc: Maarten Lankhorst Signed-off-by: Matthew Brost Reviewed-by: Jonathan Cavitt --- drivers/gpu/drm/xe/xe_devcoredump.c | 111 -- drivers/gpu/drm/xe/xe_devcoredump_types.h | 8 ++ 2 files changed, 88 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c index d8d8ca2c19d3..bdb76e834e4c 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump.c +++ b/drivers/gpu/drm/xe/xe_devcoredump.c @@ -66,22 +66,9 @@ static struct xe_guc *exec_queue_to_guc(struct xe_exec_queue *q) return >gt->uc.guc; } -static void xe_devcoredump_deferred_snap_work(struct work_struct *work) -{ - struct xe_devcoredump_snapshot *ss = container_of(work, typeof(*ss), work); - - /* keep going if fw fails as we still want to save the memory and SW data */ - if (xe_force_wake_get(gt_to_fw(ss->gt), XE_FORCEWAKE_ALL)) - xe_gt_info(ss->gt, "failed to get forcewake for coredump capture\n"); - xe_vm_snapshot_capture_delayed(ss->vm); - xe_guc_exec_queue_snapshot_capture_delayed(ss->ge); - xe_force_wake_put(gt_to_fw(ss->gt), XE_FORCEWAKE_ALL); -} - -static ssize_t xe_devcoredump_read(char *buffer, loff_t offset, - size_t count, void *data, size_t datalen) +static ssize_t __xe_devcoredump_read(char *buffer, size_t count, +struct xe_devcoredump *coredump) { - struct xe_devcoredump *coredump = data; struct xe_device *xe; struct xe_devcoredump_snapshot *ss; struct drm_printer p; @@ -89,18 +76,11 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset, struct timespec64 ts; int i; - if (!coredump) - return -ENODEV; - xe = coredump_to_xe(coredump); ss = >snapshot; - /* Ensure delayed work is captured before continuing */ - flush_work(>work); - iter.data = buffer; - iter.offset = 0; - iter.start = offset; + iter.start = 0; iter.remain = count; p = drm_coredump_printer(); @@ -134,10 +114,83 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset, return count - iter.remain; } +static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss) +{ + int i; + + xe_guc_ct_snapshot_free(ss->ct); + ss->ct = NULL; + + xe_guc_exec_queue_snapshot_free(ss->ge); + ss->ge = NULL; + + xe_sched_job_snapshot_free(ss->job); + ss->job = NULL; + + for (i = 0; i < XE_NUM_HW_ENGINES; i++) + if (ss->hwe[i]) { + xe_hw_engine_snapshot_free(ss->hwe[i]); + ss->hwe[i] = NULL; + } + + xe_vm_snapshot_free(ss->vm); + ss->vm = NULL; +} + +static void xe_devcoredump_deferred_snap_work(struct work_struct *work) +{ + struct xe_devcoredump_snapshot *ss = container_of(work, typeof(*ss), work); + struct xe_devcoredump *coredump = container_of(ss, typeof(*coredump), snapshot); + + /* keep going if fw fails as we still want to save the memory and SW data */ + if (xe_force_wake_get(gt_to_fw(ss->gt), XE_FORCEWAKE_ALL)) + xe_gt_info(ss->gt, "failed to get forcewake for coredump capture\n"); + xe_vm_snapshot_capture_delayed(ss->vm); + xe_guc_exec_queue_snapshot_capture_delayed(ss->ge); + xe_force_wake_put(gt_to_fw(ss->gt), XE_FORCEWAKE_ALL); + + /* Calculate devcoredump size */ + ss->read.size = __xe_devcoredump_read(NULL, INT_MAX, coredump); + + ss->read.buffer = kvmalloc(ss->read.size, GFP_USER); + if (!ss->read.buffer) + return; + + __xe_devcoredump_read(ss->read.buffer, ss->read.size, coredump); + xe_devcoredump_snapshot_free(ss); +} + +static ssize_t xe_devcoredump_read(char *buffer, loff_t offset, + size_t count, void *data, size_t datalen) +{ + struct xe_devcoredump *coredump = data; + struct xe_devcoredump_snapshot *ss; + ssize_t byte_copied; + + if (!coredump) + return -ENODEV; + + ss = >snapshot; + + /* Ensure delayed work is
[PATCH v5 1/3] drm/xe: Take ref to VM in delayed snapshot
Kernel BO's don't take a ref to the VM, we need the VM for the delayed snapshot, so take a ref to the VM in delayed snapshot. v2: - Check for lrc_bo before taking a VM ref (CI) - Check lrc_bo->vm before taking / dropping a VM ref (CI) - Drop VM in xe_lrc_snapshot_free v5: - Fix commit message wording (Johnathan) 47058633d9c5 ("drm/xe: Move lrc snapshot capturing to xe_lrc.c") Cc: Cc: Maarten Lankhorst Signed-off-by: Matthew Brost Reviewed-by: Jonathan Cavitt --- drivers/gpu/drm/xe/xe_lrc.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c index 94ff62e1d95e..58121821f081 100644 --- a/drivers/gpu/drm/xe/xe_lrc.c +++ b/drivers/gpu/drm/xe/xe_lrc.c @@ -1634,6 +1634,9 @@ struct xe_lrc_snapshot *xe_lrc_snapshot_capture(struct xe_lrc *lrc) if (!snapshot) return NULL; + if (lrc->bo && lrc->bo->vm) + xe_vm_get(lrc->bo->vm); + snapshot->context_desc = xe_lrc_ggtt_addr(lrc); snapshot->indirect_context_desc = xe_lrc_indirect_ring_ggtt_addr(lrc); snapshot->head = xe_lrc_ring_head(lrc); @@ -1653,12 +1656,14 @@ struct xe_lrc_snapshot *xe_lrc_snapshot_capture(struct xe_lrc *lrc) void xe_lrc_snapshot_capture_delayed(struct xe_lrc_snapshot *snapshot) { struct xe_bo *bo; + struct xe_vm *vm; struct iosys_map src; if (!snapshot) return; bo = snapshot->lrc_bo; + vm = bo->vm; snapshot->lrc_bo = NULL; snapshot->lrc_snapshot = kvmalloc(snapshot->lrc_size, GFP_KERNEL); @@ -1678,6 +1683,8 @@ void xe_lrc_snapshot_capture_delayed(struct xe_lrc_snapshot *snapshot) xe_bo_unlock(bo); put_bo: xe_bo_put(bo); + if (vm) + xe_vm_put(vm); } void xe_lrc_snapshot_print(struct xe_lrc_snapshot *snapshot, struct drm_printer *p) @@ -1727,8 +1734,14 @@ void xe_lrc_snapshot_free(struct xe_lrc_snapshot *snapshot) return; kvfree(snapshot->lrc_snapshot); - if (snapshot->lrc_bo) + if (snapshot->lrc_bo) { + struct xe_vm *vm; + + vm = snapshot->lrc_bo->vm; xe_bo_put(snapshot->lrc_bo); + if (vm) + xe_vm_put(vm); + } kfree(snapshot); } -- 2.34.1
[PATCH v5 0/3] Faster devcoredump and fixes
Combine [1] [2] for complete series to speedup devcoredump and fix it. [1] https://patchwork.freedesktop.org/series/136541/ [2] https://patchwork.freedesktop.org/series/136545/ Matthew Brost (3): drm/xe: Take ref to VM in delayed snapshot drm/printer: Allow NULL data in devcoredump printer drm/xe: Faster devcoredump drivers/gpu/drm/drm_print.c | 13 ++- drivers/gpu/drm/xe/xe_devcoredump.c | 111 -- drivers/gpu/drm/xe/xe_devcoredump_types.h | 8 ++ drivers/gpu/drm/xe/xe_lrc.c | 15 ++- include/drm/drm_print.h | 54 ++- 5 files changed, 163 insertions(+), 38 deletions(-) -- 2.34.1
Re: [PATCH 0/2] Use pcim_request_region() in vboxvideo
Hi Bjorn, On 7/31/24 9:36 PM, Bjorn Helgaas wrote: > On Mon, Jul 29, 2024 at 11:36:24AM +0200, Philipp Stanner wrote: >> Hi everyone, >> >> Now that we've got the simplified PCI devres API available we can slowly >> start using it in drivers and step by step phase the more problematic >> API out. >> >> vboxvideo currently does not have a region request, so it is a suitable >> first user. >> >> P. >> >> Philipp Stanner (2): >> PCI: Make pcim_request_region() a public function >> drm/vboxvideo: Add PCI region request >> >> drivers/gpu/drm/vboxvideo/vbox_main.c | 4 >> drivers/pci/devres.c | 1 + >> drivers/pci/pci.h | 2 -- >> include/linux/pci.h | 1 + >> 4 files changed, 6 insertions(+), 2 deletions(-) > > Given an ack from the vboxvideo maintainers, I can apply both of these > via the PCI tree so there's no race during the merge window. I'm the vboxvideo maintainer, merging both through the PCI tree sounds good to me: Acked-by: Hans de Goede Regards, Hans
Re: [PATCH 0/2] Use pcim_request_region() in vboxvideo
Hi, On 7/29/24 11:36 AM, Philipp Stanner wrote: > Hi everyone, > > Now that we've got the simplified PCI devres API available we can slowly > start using it in drivers and step by step phase the more problematic > API out. > > vboxvideo currently does not have a region request, so it is a suitable > first user. I have given both patches a test-run on top of 6.11-rc1 in a VirtualBox VM using the vboxsvga virtual vga card: Tested-by: Hans de Goede Also both patches look good to me: Reviewed-by: Hans de Goede for the series. Regards, Hans
Re: [PATCH v2 2/3] drm/rockchip: Explicitly include bits header
On 01/08/2024 04:25, Cristian Ciocaltea wrote: > Driver makes use of the BIT() macro, but relies on the bits header being > implicitly included. > > Explicitly pull the header in to avoid potential build failures in some > configurations. > > While at it, reorder include directives alphabetically. > > Fixes: 8c8546546f25 ("drm/rockchip: move output interface related definition > to rockchip_drm_drv.h") There is no bug here to be fixed. Drop. Especially bugfixes should not be combined with cleanups. Best regards, Krzysztof
Re: [PATCH v2 1/3] dt-bindings: display: rockchip: Add schema for RK3588 HDMI TX Controller
On 01/08/2024 11:50, Cristian Ciocaltea wrote: > On 8/1/24 6:37 AM, Rob Herring (Arm) wrote: >> >> On Thu, 01 Aug 2024 05:25:52 +0300, Cristian Ciocaltea wrote: >>> Rockchip RK3588 SoC integrates the Synopsys DesignWare HDMI 2.1 >>> Quad-Pixel (QP) TX controller IP. >>> >>> Since this is a new IP block, quite different from those used in the >>> previous generations of Rockchip SoCs, add a dedicated binding file. >>> >>> Signed-off-by: Cristian Ciocaltea >>> --- >>> .../display/rockchip/rockchip,dw-hdmi-qp.yaml | 188 >>> + >>> 1 file changed, 188 insertions(+) >>> >> >> My bot found errors running 'make dt_binding_check' on your patch: > > This is because the referenced synopsys,dw-hdmi-qp.yaml is provided by a > separate patchset: > > https://lore.kernel.org/lkml/20240801-dw-hdmi-qp-tx-v1-1-148f542de...@collabora.com/ So you made things untestable. No, this must be one patchset. Do not send some library/helper and users of it in separate patchsets. Best regards, Krzysztof
RE: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer
-Original Message- From: Brost, Matthew Sent: Thursday, August 1, 2024 7:30 AM To: Cavitt, Jonathan Cc: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; maarten.lankho...@linux.intel.com; Vivi, Rodrigo Subject: Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer > > On Thu, Aug 01, 2024 at 08:00:21AM -0600, Cavitt, Jonathan wrote: > > -Original Message- > > From: Brost, Matthew > > Sent: Wednesday, July 31, 2024 5:03 PM > > To: Cavitt, Jonathan > > Cc: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; > > maarten.lankho...@linux.intel.com; Vivi, Rodrigo > > Subject: Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump > > printer > > > > > > On Wed, Jul 31, 2024 at 04:22:03PM -0600, Cavitt, Jonathan wrote: > > > > -Original Message- > > > > From: Intel-xe On Behalf Of > > > > Matthew Brost > > > > Sent: Wednesday, July 31, 2024 2:32 PM > > > > To: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org > > > > Cc: maarten.lankho...@linux.intel.com; Vivi, Rodrigo > > > > > > > > Subject: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump > > > > printer > > > > > > > > > > Useful to determine size of devcoreump before writing it out. > > > > > > > > > > Cc: Maarten Lankhorst > > > > > Signed-off-by: Matthew Brost > > > > > > > > It seems this patch prevents us from copying strings into the data > > > > field if the data > > > > field hasn't been initialized. I'm not certain if it could ever be > > > > uninitialized at this > > > > point, but I recognize it as good practice to check just in case > > > > regardless. > > > > > > > > > > That's not the intent. The intent to call the print functions with NULL > > > data so the printer can calculate the size of buffer required to print > > > out all the devcoredump data. > > > > So if iterator->data is NULL, you want to NOT copy into it? > > -Jonathan Cavitt > > Yes, exactly. Run devcoredump printer with NULL data to get size, alloc > data based on devcoredump printer offset, run it again with a valid data > pointer to print. Okay, I think I understand. That might be good to add to the commit message, then. Something like: """ We want to determine the size of the devcoredump before writing it out. To that end, we will run the devcoredump printer with NULL data to get the size, alloc data based on the generated offset, then run the devcorecump again with a valid data pointer to print. This necessitates not writing data to the data pointer on the initial pass, when it is NULL. """ Maybe that's a bit overboard? In either case, my RB still stands, regardless of if the commit message is updated or not. -Jonathan Cavitt > > Matt > > > > > > > > > Matt > > > > > > > Reviewed-by: Jonathan Cavitt > > > > -Jonathan Cavitt > > > > > > > > > --- > > > > > drivers/gpu/drm/drm_print.c | 13 - > > > > > 1 file changed, 8 insertions(+), 5 deletions(-) > > > > > > > > > > diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c > > > > > index cf24dfdeb6b2..a1a4de9f9c44 100644 > > > > > --- a/drivers/gpu/drm/drm_print.c > > > > > +++ b/drivers/gpu/drm/drm_print.c > > > > > @@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, > > > > > const char *str) > > > > > copy = iterator->remain; > > > > > > > > > > /* Copy out the bit of the string that we need */ > > > > > - memcpy(iterator->data, > > > > > - str + (iterator->start - iterator->offset), > > > > > copy); > > > > > + if (iterator->data) > > > > > + memcpy(iterator->data, > > > > > + str + (iterator->start - > > > > > iterator->offset), copy); > > > > > > > > > > iterator->offset = iterator->start + copy; > > > > > iterator->remain -= copy; > > > > > @@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, > > > > > const char *str) > > > > > > > > > > len = min_t(ssize_t, strlen(str), iterator->remain); > > > > > > > > > > - memcpy(iterator->data + pos, str, len); > > > > > + if (iterator->data) > > > > > + memcpy(iterator->data + pos, str, len); > > > > > > > > > > iterator->offset += len; > > > > > iterator->remain -= len; > > > > > @@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer > > > > > *p, struct va_format *vaf) > > > > > if ((iterator->offset >= iterator->start) && (len < > > > > > iterator->remain)) { > > > > > ssize_t pos = iterator->offset - iterator->start; > > > > > > > > > > - snprintf(((char *) iterator->data) + pos, > > > > > - iterator->remain, "%pV", vaf); > > > > > + if (iterator->data) > > > > > + snprintf(((char *) iterator->data) + pos, > > > > > +
Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer
On Thu, Aug 01, 2024 at 08:00:21AM -0600, Cavitt, Jonathan wrote: > -Original Message- > From: Brost, Matthew > Sent: Wednesday, July 31, 2024 5:03 PM > To: Cavitt, Jonathan > Cc: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; > maarten.lankho...@linux.intel.com; Vivi, Rodrigo > Subject: Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump > printer > > > > On Wed, Jul 31, 2024 at 04:22:03PM -0600, Cavitt, Jonathan wrote: > > > -Original Message- > > > From: Intel-xe On Behalf Of > > > Matthew Brost > > > Sent: Wednesday, July 31, 2024 2:32 PM > > > To: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org > > > Cc: maarten.lankho...@linux.intel.com; Vivi, Rodrigo > > > > > > Subject: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump > > > printer > > > > > > > > Useful to determine size of devcoreump before writing it out. > > > > > > > > Cc: Maarten Lankhorst > > > > Signed-off-by: Matthew Brost > > > > > > It seems this patch prevents us from copying strings into the data field > > > if the data > > > field hasn't been initialized. I'm not certain if it could ever be > > > uninitialized at this > > > point, but I recognize it as good practice to check just in case > > > regardless. > > > > > > > That's not the intent. The intent to call the print functions with NULL > > data so the printer can calculate the size of buffer required to print > > out all the devcoredump data. > > So if iterator->data is NULL, you want to NOT copy into it? > -Jonathan Cavitt Yes, exactly. Run devcoredump printer with NULL data to get size, alloc data based on devcoredump printer offset, run it again with a valid data pointer to print. Matt > > > > > Matt > > > > > Reviewed-by: Jonathan Cavitt > > > -Jonathan Cavitt > > > > > > > --- > > > > drivers/gpu/drm/drm_print.c | 13 - > > > > 1 file changed, 8 insertions(+), 5 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c > > > > index cf24dfdeb6b2..a1a4de9f9c44 100644 > > > > --- a/drivers/gpu/drm/drm_print.c > > > > +++ b/drivers/gpu/drm/drm_print.c > > > > @@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, > > > > const char *str) > > > > copy = iterator->remain; > > > > > > > > /* Copy out the bit of the string that we need */ > > > > - memcpy(iterator->data, > > > > - str + (iterator->start - iterator->offset), > > > > copy); > > > > + if (iterator->data) > > > > + memcpy(iterator->data, > > > > + str + (iterator->start - > > > > iterator->offset), copy); > > > > > > > > iterator->offset = iterator->start + copy; > > > > iterator->remain -= copy; > > > > @@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, > > > > const char *str) > > > > > > > > len = min_t(ssize_t, strlen(str), iterator->remain); > > > > > > > > - memcpy(iterator->data + pos, str, len); > > > > + if (iterator->data) > > > > + memcpy(iterator->data + pos, str, len); > > > > > > > > iterator->offset += len; > > > > iterator->remain -= len; > > > > @@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer *p, > > > > struct va_format *vaf) > > > > if ((iterator->offset >= iterator->start) && (len < > > > > iterator->remain)) { > > > > ssize_t pos = iterator->offset - iterator->start; > > > > > > > > - snprintf(((char *) iterator->data) + pos, > > > > - iterator->remain, "%pV", vaf); > > > > + if (iterator->data) > > > > + snprintf(((char *) iterator->data) + pos, > > > > + iterator->remain, "%pV", vaf); > > > > > > > > iterator->offset += len; > > > > iterator->remain -= len; > > > > -- > > > > 2.34.1 > > > > > > > > > >
Re: [RFC PATCH 3/3] drm/log: Introduce a new boot logger to draw the kmsg on the screen
On 2024-08-01, Jocelyn Falempe wrote: > I think I can also register one console for each drm driver, which > will simplify drm_log even further. (currently it would mean having a > circular buffer and work function for each driver which is a bit too > much). Indeed. > Do you know if there is a chance to have write_thread() in 6.12 or > 6.13 ? Sorry, I have no crystal ball. Petr Mladek and I are working really hard to get things in shape for mainline. I do think there is a chance for the 6.12 merge window. But it would also need to get past Linus. Our recent atomic console efforts were rejected [0] for the 6.11 merge window. We are working to get that series in shape for 6.12 in parallel. John [0] https://lore.kernel.org/lkml/CAHk-=whU_woFnFN-3Jv2hNCmwLg_fkrT42AWwxm-=ha5bmn...@mail.gmail.com
Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer
On Thu, Aug 01, 2024 at 11:05:21AM +0300, Jani Nikula wrote: > On Wed, 31 Jul 2024, Matthew Brost wrote: > > Useful to determine size of devcoreump before writing it out. > > I find it useful to have this special case documented, with an example, > so it's easier to see how handy this really is. > Good idea, will add some kernel doc explaining the problem devcoredump in Xe and how use a devcoredump printer with NULL to make it faster. Matt > BR, > Jani. > > > > > > Cc: Maarten Lankhorst > > Signed-off-by: Matthew Brost > > --- > > drivers/gpu/drm/drm_print.c | 13 - > > 1 file changed, 8 insertions(+), 5 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c > > index cf24dfdeb6b2..a1a4de9f9c44 100644 > > --- a/drivers/gpu/drm/drm_print.c > > +++ b/drivers/gpu/drm/drm_print.c > > @@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, const > > char *str) > > copy = iterator->remain; > > > > /* Copy out the bit of the string that we need */ > > - memcpy(iterator->data, > > - str + (iterator->start - iterator->offset), copy); > > + if (iterator->data) > > + memcpy(iterator->data, > > + str + (iterator->start - iterator->offset), > > copy); > > > > iterator->offset = iterator->start + copy; > > iterator->remain -= copy; > > @@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, const > > char *str) > > > > len = min_t(ssize_t, strlen(str), iterator->remain); > > > > - memcpy(iterator->data + pos, str, len); > > + if (iterator->data) > > + memcpy(iterator->data + pos, str, len); > > > > iterator->offset += len; > > iterator->remain -= len; > > @@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer *p, > > struct va_format *vaf) > > if ((iterator->offset >= iterator->start) && (len < iterator->remain)) { > > ssize_t pos = iterator->offset - iterator->start; > > > > - snprintf(((char *) iterator->data) + pos, > > - iterator->remain, "%pV", vaf); > > + if (iterator->data) > > + snprintf(((char *) iterator->data) + pos, > > + iterator->remain, "%pV", vaf); > > > > iterator->offset += len; > > iterator->remain -= len; > > -- > Jani Nikula, Intel
Re: [PATCH 3/4] drm/msm/a5xx: fix races in preemption evaluation stage
On Thu, Aug 01, 2024 at 01:52:32PM +0100, Connor Abbott wrote: > On Thu, Aug 1, 2024 at 1:25 PM Vladimir Lypak > wrote: > > > > On Mon, Jul 29, 2024 at 06:26:45PM +0100, Connor Abbott wrote: > > > On Thu, Jul 11, 2024 at 11:10 AM Vladimir Lypak > > > wrote: > > > > > > > > On A5XX GPUs when preemption is used it's invietable to enter a soft > > > > lock-up state in which GPU is stuck at empty ring-buffer doing nothing. > > > > This appears as full UI lockup and not detected as GPU hang (because > > > > it's not). This happens due to not triggering preemption when it was > > > > needed. Sometimes this state can be recovered by some new submit but > > > > generally it won't happen because applications are waiting for old > > > > submits to retire. > > > > > > > > One of the reasons why this happens is a race between a5xx_submit and > > > > a5xx_preempt_trigger called from IRQ during submit retire. Former thread > > > > updates ring->cur of previously empty and not current ring right after > > > > latter checks it for emptiness. Then both threads can just exit because > > > > for first one preempt_state wasn't NONE yet and for second one all rings > > > > appeared to be empty. > > > > > > > > To prevent such situations from happening we need to establish guarantee > > > > for preempt_trigger to be called after each submit. To implement it this > > > > patch adds trigger call at the end of a5xx_preempt_irq to re-check if we > > > > should switch to non-empty or higher priority ring. Also we find next > > > > ring in new preemption state "EVALUATE". If the thread that updated some > > > > ring with new submit sees this state it should wait until it passes. > > > > > > > > Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets") > > > > Signed-off-by: Vladimir Lypak > > > > --- > > > > drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 6 +++--- > > > > drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 11 +++ > > > > drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 24 +++ > > > > 3 files changed, 30 insertions(+), 11 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > > > index 6c80d3003966..266744ee1d5f 100644 > > > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > > > @@ -110,7 +110,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, > > > > struct msm_gem_submit *submit > > > > } > > > > > > > > a5xx_flush(gpu, ring, true); > > > > - a5xx_preempt_trigger(gpu); > > > > + a5xx_preempt_trigger(gpu, true); > > > > > > > > /* we might not necessarily have a cmd from userspace to > > > > * trigger an event to know that submit has completed, so > > > > @@ -240,7 +240,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct > > > > msm_gem_submit *submit) > > > > a5xx_flush(gpu, ring, false); > > > > > > > > /* Check to see if we need to start preemption */ > > > > - a5xx_preempt_trigger(gpu); > > > > + a5xx_preempt_trigger(gpu, true); > > > > } > > > > > > > > static const struct adreno_five_hwcg_regs { > > > > @@ -1296,7 +1296,7 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu) > > > > a5xx_gpmu_err_irq(gpu); > > > > > > > > if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS) { > > > > - a5xx_preempt_trigger(gpu); > > > > + a5xx_preempt_trigger(gpu, false); > > > > msm_gpu_retire(gpu); > > > > } > > > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > > > index c7187bcc5e90..1120824853d4 100644 > > > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > > > @@ -57,10 +57,12 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, struct > > > > drm_minor *minor); > > > > * through the process. > > > > * > > > > * PREEMPT_NONE - no preemption in progress. Next state START. > > > > - * PREEMPT_START - The trigger is evaulating if preemption is > > > > possible. Next > > > > - * states: TRIGGERED, NONE > > > > + * PREEMPT_EVALUATE - The trigger is evaulating if preemption is > > > > possible. Next > > > > + * states: START, ABORT > > > > * PREEMPT_ABORT - An intermediate state before moving back to NONE. > > > > Next > > > > * state: NONE. > > > > + * PREEMPT_START - The trigger is preparing for preemption. Next state: > > > > + * TRIGGERED > > > > * PREEMPT_TRIGGERED: A preemption has been executed on the hardware. > > > > Next > > > > * states: FAULTED, PENDING > > > > * PREEMPT_FAULTED: A preemption timed out (never completed). This > > > > will trigger > > > > @@ -71,8 +73,9 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, struct > > > > drm_minor *minor); > > > > > > > > enum preempt_state { > > > > PREEMPT_NONE = 0, > > > > - PREEMPT_START, > > > > +
Re: [PATCH 1/2] dt-bindings: display: bridge: Add schema for Synopsys DW HDMI QP TX IP
On 01/08/2024 11:29, Cristian Ciocaltea wrote: > On 8/1/24 11:38 AM, Krzysztof Kozlowski wrote:> On 01/08/2024 04:05, Cristian > Ciocaltea wrote: >>> Add dt-binding schema containing the common properties for the Synopsys >>> DesignWare HDMI QP TX controller. >>> >>> Note this is not a full dt-binding specification, but is meant to be >>> referenced by platform-specific bindings for this IP core. >> >> Please provide an user for this binding. Otherwise it is a no-op. > > The first user of this is RK3588 HDMI TX Controller [1]. Patchsets do not work like this. Splitting things causes that your other patch simply cannot even be tested because you introduced dependency. Combine patches so bindings referencing common properties can properly be tested by automation. Best regards, Krzysztof
Re: [PATCH 2/2] drm/bridge: synopsys: Add DW HDMI QP TX Controller driver
On 01/08/2024 11:43, Cristian Ciocaltea wrote: > On 8/1/24 11:50 AM, Krzysztof Kozlowski wrote: >> On 01/08/2024 04:05, Cristian Ciocaltea wrote: >>> The Synopsys DesignWare HDMI 2.1 Quad-Pixel (QP) TX Controller supports >>> the following features, among others: >> >> ... >> >>> + >>> +void dw_hdmi_qp_unbind(struct dw_hdmi_qp *hdmi) >>> +{ >>> +} >>> +EXPORT_SYMBOL_GPL(dw_hdmi_qp_unbind); >> >> This looks like quite useless export. Drop. >> >> >>> + >>> +void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi) >>> +{ >>> + dw_hdmi_qp_init_hw(hdmi); >>> +} >>> +EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume); >>> + >>> +MODULE_AUTHOR("Algea Cao "); >>> +MODULE_AUTHOR("Cristian Ciocaltea "); >>> +MODULE_DESCRIPTION("DW HDMI QP transmitter driver"); >>> +MODULE_LICENSE("GPL"); >>> +MODULE_ALIAS("platform:dw-hdmi-qp"); >> >> That's not a platform driver. That does not look like driver at all, >> just some helper code without any user > > This is actually used to provide RK3588 HDMI output support: > > https://lore.kernel.org/lkml/20240801-b4-rk3588-bridge-upstream-v2-3-9fa657a4e...@collabora.com/ That is supposed to be in one patchset, so we can see how you use the introduced functions. Best regards, Krzysztof
RE: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer
-Original Message- From: Brost, Matthew Sent: Wednesday, July 31, 2024 5:03 PM To: Cavitt, Jonathan Cc: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; maarten.lankho...@linux.intel.com; Vivi, Rodrigo Subject: Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer > > On Wed, Jul 31, 2024 at 04:22:03PM -0600, Cavitt, Jonathan wrote: > > -Original Message- > > From: Intel-xe On Behalf Of > > Matthew Brost > > Sent: Wednesday, July 31, 2024 2:32 PM > > To: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org > > Cc: maarten.lankho...@linux.intel.com; Vivi, Rodrigo > > > > Subject: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer > > > > > > Useful to determine size of devcoreump before writing it out. > > > > > > Cc: Maarten Lankhorst > > > Signed-off-by: Matthew Brost > > > > It seems this patch prevents us from copying strings into the data field if > > the data > > field hasn't been initialized. I'm not certain if it could ever be > > uninitialized at this > > point, but I recognize it as good practice to check just in case regardless. > > > > That's not the intent. The intent to call the print functions with NULL > data so the printer can calculate the size of buffer required to print > out all the devcoredump data. So if iterator->data is NULL, you want to NOT copy into it? -Jonathan Cavitt > > Matt > > > Reviewed-by: Jonathan Cavitt > > -Jonathan Cavitt > > > > > --- > > > drivers/gpu/drm/drm_print.c | 13 - > > > 1 file changed, 8 insertions(+), 5 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c > > > index cf24dfdeb6b2..a1a4de9f9c44 100644 > > > --- a/drivers/gpu/drm/drm_print.c > > > +++ b/drivers/gpu/drm/drm_print.c > > > @@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, const > > > char *str) > > > copy = iterator->remain; > > > > > > /* Copy out the bit of the string that we need */ > > > - memcpy(iterator->data, > > > - str + (iterator->start - iterator->offset), copy); > > > + if (iterator->data) > > > + memcpy(iterator->data, > > > + str + (iterator->start - iterator->offset), > > > copy); > > > > > > iterator->offset = iterator->start + copy; > > > iterator->remain -= copy; > > > @@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, const > > > char *str) > > > > > > len = min_t(ssize_t, strlen(str), iterator->remain); > > > > > > - memcpy(iterator->data + pos, str, len); > > > + if (iterator->data) > > > + memcpy(iterator->data + pos, str, len); > > > > > > iterator->offset += len; > > > iterator->remain -= len; > > > @@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer *p, > > > struct va_format *vaf) > > > if ((iterator->offset >= iterator->start) && (len < iterator->remain)) { > > > ssize_t pos = iterator->offset - iterator->start; > > > > > > - snprintf(((char *) iterator->data) + pos, > > > - iterator->remain, "%pV", vaf); > > > + if (iterator->data) > > > + snprintf(((char *) iterator->data) + pos, > > > + iterator->remain, "%pV", vaf); > > > > > > iterator->offset += len; > > > iterator->remain -= len; > > > -- > > > 2.34.1 > > > > > > >
Re: [RFC PATCH 3/3] drm/log: Introduce a new boot logger to draw the kmsg on the screen
On 01/08/2024 12:51, John Ogness wrote: On 2024-08-01, Jocelyn Falempe wrote: * It uses a circular buffer so the console->write() callback is very quick, and will never stall. * Drawing is done asynchronously using a workqueue. For CON_NBCON, neither of the above points are necessary. You can draw directly from the write_thread() callback. See below: +static bool drm_log_work_draw(void) +{ + unsigned int len; + char buf[512]; + + len = drm_log_buf_read(buf, sizeof(buf)); + if (len) + drm_log_draw_all(buf, len); + return len != 0; +} For CON_NBCON, this is essentially your write_thread() callback: void drm_log_write_thread(struct console *con, struct nbcon_write_context *wctxt) { drm_log_draw_all(wctxt->outbuf, wctxt->len); } You cannot implement a write_atomic() callback because the console must be able to print directly in NMI context and must not defer. But write_atomic() is optional, so you should be fine there. Disclaimer: Only in PREEMPT_RT patchset at the moment. Thanks, so that means the circular buffer and workqueue are only necessary until write_thread() is merged in mainline. It will be a nice simplification. I think I can also register one console for each drm driver, which will simplify drm_log even further. (currently it would mean having a circular buffer and work function for each driver which is a bit too much). Do you know if there is a chance to have write_thread() in 6.12 or 6.13 ? John Ogness > Best regards -- Jocelyn
Re: [PATCH 2/4] drm/msm/a5xx: properly clear preemption records on resume
On Thu, Jul 11, 2024 at 10:00:19AM +, Vladimir Lypak wrote: > Two fields of preempt_record which are used by CP aren't reset on > resume: "data" and "info". This is the reason behind faults which happen > when we try to switch to the ring that was active last before suspend. > In addition those faults can't be recovered from because we use suspend > and resume to do so (keeping values of those fields again). > > Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets") > Signed-off-by: Vladimir Lypak > --- > drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c > b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c > index f58dd564d122..67a8ef4adf6b 100644 > --- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c > +++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c > @@ -204,6 +204,8 @@ void a5xx_preempt_hw_init(struct msm_gpu *gpu) > return; > > for (i = 0; i < gpu->nr_rings; i++) { > + a5xx_gpu->preempt[i]->data = 0; > + a5xx_gpu->preempt[i]->info = 0; I don't see this bit in the downstream driver. Just curious, do we need to clear both fields to avoid the gpu faults? -Akhil > a5xx_gpu->preempt[i]->wptr = 0; > a5xx_gpu->preempt[i]->rptr = 0; > a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova; > -- > 2.45.2 >
[PATCH] drm/client: Use common display mode for cloned outputs
For cloned outputs, don't pick a default resolution of 1024x768 as most hardware can do better. Instead look through the modes of all connectors to find a common mode for all of them. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_client_modeset.c | 54 +--- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index 31af5cf37a09..67b422dc8e7f 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -266,7 +266,7 @@ static bool drm_client_target_cloned(struct drm_device *dev, { int count, i, j; bool can_clone = false; - struct drm_display_mode *dmt_mode, *mode; + struct drm_display_mode *mode, *common_mode = NULL; /* only contemplate cloning in the single crtc case */ if (dev->mode_config.num_crtc > 1) @@ -309,35 +309,49 @@ static bool drm_client_target_cloned(struct drm_device *dev, return true; } - /* try and find a 1024x768 mode on each connector */ - can_clone = true; - dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false); - - if (!dmt_mode) - goto fail; + /* try and find a mode common among connectors */ + can_clone = false; for (i = 0; i < connector_count; i++) { if (!enabled[i]) continue; - list_for_each_entry(mode, [i]->modes, head) { - if (drm_mode_match(mode, dmt_mode, - DRM_MODE_MATCH_TIMINGS | - DRM_MODE_MATCH_CLOCK | - DRM_MODE_MATCH_FLAGS | - DRM_MODE_MATCH_3D_FLAGS)) - modes[i] = mode; + list_for_each_entry(common_mode, [i]->modes, head) { + can_clone = true; + + for (j = 1; j < connector_count; j++) { + if (!enabled[i]) + continue; + + can_clone = false; + list_for_each_entry(mode, [j]->modes, head) { + can_clone = drm_mode_match(common_mode, mode, + DRM_MODE_MATCH_TIMINGS | + DRM_MODE_MATCH_CLOCK | + DRM_MODE_MATCH_FLAGS | + DRM_MODE_MATCH_3D_FLAGS); + if (can_clone) + break; // found common mode on connector + } + if (!can_clone) + break; // try next common mode + } + if (can_clone) + break; // found common mode among all connectors } - if (!modes[i]) - can_clone = false; + break; } - kfree(dmt_mode); - if (can_clone) { - drm_dbg_kms(dev, "can clone using 1024x768\n"); + for (i = 0; i < connector_count; i++) { + if (!enabled[i]) + continue; + modes[i] = common_mode; + + } + drm_dbg_kms(dev, "can clone using" DRM_MODE_FMT "\n", DRM_MODE_ARG(common_mode)); return true; } -fail: + drm_info(dev, "kms: can't enable cloning when we probably wanted to.\n"); return false; } -- 2.45.2
Re: [PATCH v3 2/2] drm/amd: Add power_saving_policy drm property to eDP connectors
On Thu, 01 Aug 2024, Thomas Zimmermann wrote: > Hi > > Am 01.08.24 um 14:33 schrieb Jani Nikula: >> On Mon, 01 Jul 2024, Xaver Hugl wrote: >>> Am Do., 20. Juni 2024 um 22:22 Uhr schrieb Xaver Hugl >>> : Merging can only happen once a real world userspace application has implemented support for it. I'll try to do that sometime next week in KWin >>> Here's the promised implementation: >>> https://invent.kde.org/plasma/kwin/-/merge_requests/6028 >> The requirement is that the userspace patches must be reviewed and ready >> for merging into a suitable and canonical upstream project. >> >> Are they? > > I already saw this series in today's PR for drm-misc-next. :/ Exactly what triggered the question! BR, Jani. > > Best regards > Thomas > >> >> >> BR, >> Jani. >> >> >>> In testing with the patches on top of kernel 6.9.6, setting the >>> property to `Require color accuracy` makes the sysfs file correctly >>> report "Device or resource busy" when trying to change the power >>> saving level, but setting the property to zero doesn't really work. >>> Once KWin sets the property to zero, changing the power saving level >>> "works" but the screen blanks for a moment (might just be a single >>> frame) and reading from the file returns zero again, with the visuals >>> and backlight level unchanged as well. -- Jani Nikula, Intel
Re: [PATCH 3/4] drm/msm/a5xx: fix races in preemption evaluation stage
On Thu, Aug 1, 2024 at 1:25 PM Vladimir Lypak wrote: > > On Mon, Jul 29, 2024 at 06:26:45PM +0100, Connor Abbott wrote: > > On Thu, Jul 11, 2024 at 11:10 AM Vladimir Lypak > > wrote: > > > > > > On A5XX GPUs when preemption is used it's invietable to enter a soft > > > lock-up state in which GPU is stuck at empty ring-buffer doing nothing. > > > This appears as full UI lockup and not detected as GPU hang (because > > > it's not). This happens due to not triggering preemption when it was > > > needed. Sometimes this state can be recovered by some new submit but > > > generally it won't happen because applications are waiting for old > > > submits to retire. > > > > > > One of the reasons why this happens is a race between a5xx_submit and > > > a5xx_preempt_trigger called from IRQ during submit retire. Former thread > > > updates ring->cur of previously empty and not current ring right after > > > latter checks it for emptiness. Then both threads can just exit because > > > for first one preempt_state wasn't NONE yet and for second one all rings > > > appeared to be empty. > > > > > > To prevent such situations from happening we need to establish guarantee > > > for preempt_trigger to be called after each submit. To implement it this > > > patch adds trigger call at the end of a5xx_preempt_irq to re-check if we > > > should switch to non-empty or higher priority ring. Also we find next > > > ring in new preemption state "EVALUATE". If the thread that updated some > > > ring with new submit sees this state it should wait until it passes. > > > > > > Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets") > > > Signed-off-by: Vladimir Lypak > > > --- > > > drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 6 +++--- > > > drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 11 +++ > > > drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 24 +++ > > > 3 files changed, 30 insertions(+), 11 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > > index 6c80d3003966..266744ee1d5f 100644 > > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > > @@ -110,7 +110,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, > > > struct msm_gem_submit *submit > > > } > > > > > > a5xx_flush(gpu, ring, true); > > > - a5xx_preempt_trigger(gpu); > > > + a5xx_preempt_trigger(gpu, true); > > > > > > /* we might not necessarily have a cmd from userspace to > > > * trigger an event to know that submit has completed, so > > > @@ -240,7 +240,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct > > > msm_gem_submit *submit) > > > a5xx_flush(gpu, ring, false); > > > > > > /* Check to see if we need to start preemption */ > > > - a5xx_preempt_trigger(gpu); > > > + a5xx_preempt_trigger(gpu, true); > > > } > > > > > > static const struct adreno_five_hwcg_regs { > > > @@ -1296,7 +1296,7 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu) > > > a5xx_gpmu_err_irq(gpu); > > > > > > if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS) { > > > - a5xx_preempt_trigger(gpu); > > > + a5xx_preempt_trigger(gpu, false); > > > msm_gpu_retire(gpu); > > > } > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > > index c7187bcc5e90..1120824853d4 100644 > > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > > @@ -57,10 +57,12 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, struct > > > drm_minor *minor); > > > * through the process. > > > * > > > * PREEMPT_NONE - no preemption in progress. Next state START. > > > - * PREEMPT_START - The trigger is evaulating if preemption is possible. > > > Next > > > - * states: TRIGGERED, NONE > > > + * PREEMPT_EVALUATE - The trigger is evaulating if preemption is > > > possible. Next > > > + * states: START, ABORT > > > * PREEMPT_ABORT - An intermediate state before moving back to NONE. Next > > > * state: NONE. > > > + * PREEMPT_START - The trigger is preparing for preemption. Next state: > > > + * TRIGGERED > > > * PREEMPT_TRIGGERED: A preemption has been executed on the hardware. > > > Next > > > * states: FAULTED, PENDING > > > * PREEMPT_FAULTED: A preemption timed out (never completed). This will > > > trigger > > > @@ -71,8 +73,9 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, struct > > > drm_minor *minor); > > > > > > enum preempt_state { > > > PREEMPT_NONE = 0, > > > - PREEMPT_START, > > > + PREEMPT_EVALUATE, > > > PREEMPT_ABORT, > > > + PREEMPT_START, > > > PREEMPT_TRIGGERED, > > > PREEMPT_FAULTED, > > > PREEMPT_PENDING, > > > @@ -156,7 +159,7 @@ void a5xx_set_hwcg(struct msm_gpu *gpu, bool state); > > > > > > void
Introduction and Seeking Advice on X.Org Evoc Mentorship Program
Hello everyone, Hello, my name is Priyansu Rout I am from India. I am right now in my second year of B. Tech in Computer Science and Engineering. I have been developing in blockchain projects and now I would like to get experience in X. Org, especially on the kernel level. I am very much interested in being a mentee in the X. Org Evoc Mentorship Program. I would really be grateful for any pointers on how to proceed in contributing to X. Org and how the mentorship process works. Thanks for your time and I am looking forward to enrich this community through learning and sharing.
Re: [PATCH v3 2/2] drm/amd: Add power_saving_policy drm property to eDP connectors
Hi Am 01.08.24 um 14:33 schrieb Jani Nikula: On Mon, 01 Jul 2024, Xaver Hugl wrote: Am Do., 20. Juni 2024 um 22:22 Uhr schrieb Xaver Hugl : Merging can only happen once a real world userspace application has implemented support for it. I'll try to do that sometime next week in KWin Here's the promised implementation: https://invent.kde.org/plasma/kwin/-/merge_requests/6028 The requirement is that the userspace patches must be reviewed and ready for merging into a suitable and canonical upstream project. Are they? I already saw this series in today's PR for drm-misc-next. :/ Best regards Thomas BR, Jani. In testing with the patches on top of kernel 6.9.6, setting the property to `Require color accuracy` makes the sysfs file correctly report "Device or resource busy" when trying to change the power saving level, but setting the property to zero doesn't really work. Once KWin sets the property to zero, changing the power saving level "works" but the screen blanks for a moment (might just be a single frame) and reading from the file returns zero again, with the visuals and backlight level unchanged as well. -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH 1/4] drm/msm/a5xx: disable preemption in submits by default
On Mon, Jul 15, 2024 at 02:00:10PM -0700, Rob Clark wrote: > On Thu, Jul 11, 2024 at 3:02 AM Vladimir Lypak > wrote: > > > > Fine grain preemption (switching from/to points within submits) > > requires extra handling in command stream of those submits, especially > > when rendering with tiling (using GMEM). However this handling is > > missing at this point in mesa (and always was). For this reason we get > > random GPU faults and hangs if more than one priority level is used > > because local preemption is enabled prior to executing command stream > > from submit. > > With that said it was ahead of time to enable local preemption by > > default considering the fact that even on downstream kernel it is only > > enabled if requested via UAPI. > > > > Fixes: a7a4c19c36de ("drm/msm/a5xx: fix setting of the > > CP_PREEMPT_ENABLE_LOCAL register") > > Signed-off-by: Vladimir Lypak > > --- > > drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 8 ++-- > > 1 file changed, 6 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > index c0b5373e90d7..6c80d3003966 100644 > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > @@ -150,9 +150,13 @@ static void a5xx_submit(struct msm_gpu *gpu, struct > > msm_gem_submit *submit) > > OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); > > OUT_RING(ring, 1); > > > > - /* Enable local preemption for finegrain preemption */ > > + /* > > +* Disable local preemption by default because it requires > > +* user-space to be aware of it and provide additional handling > > +* to restore rendering state or do various flushes on switch. > > +*/ > > OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1); > > - OUT_RING(ring, 0x1); > > + OUT_RING(ring, 0x0); > > From a quick look at the a530 pfp fw, it looks like > CP_PREEMPT_ENABLE_LOCAL is allowed in IB1/IB2 (ie. not restricted to > kernel RB). So we should just disable it in the kernel, and let > userspace send a CP_PREEMPT_ENABLE_LOCAL to enable local preemption. Ack. AFAIU about a5x preemption, this should work. -Akhil > > BR, > -R > > > /* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */ > > OUT_PKT7(ring, CP_YIELD_ENABLE, 1); > > -- > > 2.45.2 > >
Re: [PATCH v3 2/2] drm/amd: Add power_saving_policy drm property to eDP connectors
On Mon, 01 Jul 2024, Xaver Hugl wrote: > Am Do., 20. Juni 2024 um 22:22 Uhr schrieb Xaver Hugl : >> Merging can only happen once a real world userspace application has >> implemented support for it. I'll try to do that sometime next week in >> KWin > > Here's the promised implementation: > https://invent.kde.org/plasma/kwin/-/merge_requests/6028 The requirement is that the userspace patches must be reviewed and ready for merging into a suitable and canonical upstream project. Are they? BR, Jani. > > In testing with the patches on top of kernel 6.9.6, setting the > property to `Require color accuracy` makes the sysfs file correctly > report "Device or resource busy" when trying to change the power > saving level, but setting the property to zero doesn't really work. > Once KWin sets the property to zero, changing the power saving level > "works" but the screen blanks for a moment (might just be a single > frame) and reading from the file returns zero again, with the visuals > and backlight level unchanged as well. -- Jani Nikula, Intel
Re: [PATCH] backlight: pwm_bl: print errno for probe errors
On Thu, 01 Aug 2024, Martin Kepplinger-Novaković wrote: > This makes debugging often easier. > > Signed-off-by: Martin Kepplinger-Novaković > > --- > drivers/video/backlight/pwm_bl.c | 9 ++--- > 1 file changed, 6 insertions(+), 3 deletions(-) Please refrain from signing your mails like this. It means that some of us have to physically click a pop-up box as we are parsing our inboxes. I'm deleting all mails in this thread. -- Lee Jones [李琼斯]
Re: [PATCH 3/4] drm/msm/a5xx: fix races in preemption evaluation stage
On Mon, Jul 29, 2024 at 06:26:45PM +0100, Connor Abbott wrote: > On Thu, Jul 11, 2024 at 11:10 AM Vladimir Lypak > wrote: > > > > On A5XX GPUs when preemption is used it's invietable to enter a soft > > lock-up state in which GPU is stuck at empty ring-buffer doing nothing. > > This appears as full UI lockup and not detected as GPU hang (because > > it's not). This happens due to not triggering preemption when it was > > needed. Sometimes this state can be recovered by some new submit but > > generally it won't happen because applications are waiting for old > > submits to retire. > > > > One of the reasons why this happens is a race between a5xx_submit and > > a5xx_preempt_trigger called from IRQ during submit retire. Former thread > > updates ring->cur of previously empty and not current ring right after > > latter checks it for emptiness. Then both threads can just exit because > > for first one preempt_state wasn't NONE yet and for second one all rings > > appeared to be empty. > > > > To prevent such situations from happening we need to establish guarantee > > for preempt_trigger to be called after each submit. To implement it this > > patch adds trigger call at the end of a5xx_preempt_irq to re-check if we > > should switch to non-empty or higher priority ring. Also we find next > > ring in new preemption state "EVALUATE". If the thread that updated some > > ring with new submit sees this state it should wait until it passes. > > > > Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets") > > Signed-off-by: Vladimir Lypak > > --- > > drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 6 +++--- > > drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 11 +++ > > drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 24 +++ > > 3 files changed, 30 insertions(+), 11 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > index 6c80d3003966..266744ee1d5f 100644 > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > > @@ -110,7 +110,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, > > struct msm_gem_submit *submit > > } > > > > a5xx_flush(gpu, ring, true); > > - a5xx_preempt_trigger(gpu); > > + a5xx_preempt_trigger(gpu, true); > > > > /* we might not necessarily have a cmd from userspace to > > * trigger an event to know that submit has completed, so > > @@ -240,7 +240,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct > > msm_gem_submit *submit) > > a5xx_flush(gpu, ring, false); > > > > /* Check to see if we need to start preemption */ > > - a5xx_preempt_trigger(gpu); > > + a5xx_preempt_trigger(gpu, true); > > } > > > > static const struct adreno_five_hwcg_regs { > > @@ -1296,7 +1296,7 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu) > > a5xx_gpmu_err_irq(gpu); > > > > if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS) { > > - a5xx_preempt_trigger(gpu); > > + a5xx_preempt_trigger(gpu, false); > > msm_gpu_retire(gpu); > > } > > > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > index c7187bcc5e90..1120824853d4 100644 > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h > > @@ -57,10 +57,12 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, struct > > drm_minor *minor); > > * through the process. > > * > > * PREEMPT_NONE - no preemption in progress. Next state START. > > - * PREEMPT_START - The trigger is evaulating if preemption is possible. > > Next > > - * states: TRIGGERED, NONE > > + * PREEMPT_EVALUATE - The trigger is evaulating if preemption is possible. > > Next > > + * states: START, ABORT > > * PREEMPT_ABORT - An intermediate state before moving back to NONE. Next > > * state: NONE. > > + * PREEMPT_START - The trigger is preparing for preemption. Next state: > > + * TRIGGERED > > * PREEMPT_TRIGGERED: A preemption has been executed on the hardware. Next > > * states: FAULTED, PENDING > > * PREEMPT_FAULTED: A preemption timed out (never completed). This will > > trigger > > @@ -71,8 +73,9 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, struct > > drm_minor *minor); > > > > enum preempt_state { > > PREEMPT_NONE = 0, > > - PREEMPT_START, > > + PREEMPT_EVALUATE, > > PREEMPT_ABORT, > > + PREEMPT_START, > > PREEMPT_TRIGGERED, > > PREEMPT_FAULTED, > > PREEMPT_PENDING, > > @@ -156,7 +159,7 @@ void a5xx_set_hwcg(struct msm_gpu *gpu, bool state); > > > > void a5xx_preempt_init(struct msm_gpu *gpu); > > void a5xx_preempt_hw_init(struct msm_gpu *gpu); > > -void a5xx_preempt_trigger(struct msm_gpu *gpu); > > +void a5xx_preempt_trigger(struct msm_gpu *gpu, bool new_submit); > > void a5xx_preempt_irq(struct msm_gpu *gpu); > > void
[Bug 219117] New: amdgpu: amdgpu_device_ip_init failed
https://bugzilla.kernel.org/show_bug.cgi?id=219117 Bug ID: 219117 Summary: amdgpu: amdgpu_device_ip_init failed Product: Drivers Version: 2.5 Kernel Version: 6.11.0-rc1 Hardware: All OS: Linux Status: NEW Severity: blocking Priority: P3 Component: Video(DRI - non Intel) Assignee: drivers_video-...@kernel-bugs.osdl.org Reporter: jean-christo...@guillain.net Regression: Yes Bisected 064d92436b6924937ef414894d9174fa4465f788 commit-id: Hello ! Since the last kernel RC (6.11-rc1), the boot process hangs on my computer after a GPU error : Jul 30 10:18:10 youpi kernel: amdgpu :00:01.0: [drm:amdgpu_ring_test_helper [amdgpu]] *ERROR* ring gfx test failed (-110) Jul 30 10:18:10 youpi kernel: [drm:amdgpu_device_init [amdgpu]] *ERROR* hw_init of IP block failed -110 Jul 30 10:18:10 youpi kernel: amdgpu :00:01.0: amdgpu: amdgpu_device_ip_init failed Jul 30 10:18:10 youpi kernel: amdgpu :00:01.0: amdgpu: Fatal error during GPU init Jul 30 10:18:10 youpi kernel: amdgpu :00:01.0: amdgpu: amdgpu: finishing device. Jul 30 10:18:10 youpi kernel: [ cut here ] Jul 30 10:18:10 youpi kernel: WARNING: CPU: 0 PID: 186 at drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c:631 amdgpu_irq_put+0x45/0x70 [amdgpu] Jul 30 10:18:10 youpi kernel: Modules linked in: sd_mod usbhid uas hid usb_storage amdgpu(+) amdxcp drm_exec gpu_sched drm_buddy i2c_algo_bit drm_suballoc_helper drm> Jul 30 10:18:10 youpi kernel: CPU: 0 UID: 0 PID: 186 Comm: (udev-worker) Not tainted 6.11.0-rc1-jcg+ #1 Jul 30 10:18:10 youpi kernel: Hardware name: LENOVO 10VGS02P00/3130, BIOS M1XKT57A 02/10/2022 Jul 30 10:18:10 youpi kernel: RIP: 0010:amdgpu_irq_put+0x45/0x70 [amdgpu] Jul 30 10:18:10 youpi kernel: Code: 48 8b 4e 10 48 83 39 00 74 2c 89 d1 48 8d 04 88 8b 08 85 c9 74 14 f0 ff 08 b8 00 00 00 00 74 05 e9 50 c5 f7 d8 e9 6b fd ff ff <0f> Jul 30 10:18:10 youpi kernel: RSP: 0018:af1480677940 EFLAGS: 00010246 Jul 30 10:18:10 youpi kernel: RAX: 94f286417540 RBX: 94f285818880 RCX: Jul 30 10:18:10 youpi kernel: RDX: RSI: 94f2858254c0 RDI: 94f28580 Jul 30 10:18:10 youpi kernel: RBP: 94f285810208 R08: 0002 R09: 0003 Jul 30 10:18:10 youpi kernel: R10: af1480677768 R11: 9a4c96c8 R12: 94f2858105e8 Jul 30 10:18:10 youpi kernel: R13: 94f285800010 R14: 94f28580 R15: 94f2858254c0 Jul 30 10:18:10 youpi kernel: FS: 7f03450bb8c0() GS:94f31760() knlGS: Jul 30 10:18:10 youpi kernel: CS: 0010 DS: ES: CR0: 80050033 Jul 30 10:18:10 youpi kernel: CR2: 7f03450b2028 CR3: 0001458d8000 CR4: 001506f0 Jul 30 10:18:10 youpi kernel: Call Trace: Jul 30 10:18:10 youpi kernel: Jul 30 10:18:10 youpi kernel: ? __warn+0x7c/0x120 Jul 30 10:18:10 youpi kernel: ? amdgpu_irq_put+0x45/0x70 [amdgpu] Jul 30 10:18:10 youpi kernel: ? report_bug+0x155/0x170 Jul 30 10:18:10 youpi kernel: ? handle_bug+0x3f/0x80 Jul 30 10:18:10 youpi kernel: ? exc_invalid_op+0x13/0x60 Jul 30 10:18:10 youpi kernel: ? asm_exc_invalid_op+0x16/0x20 Jul 30 10:18:10 youpi kernel: ? amdgpu_irq_put+0x45/0x70 [amdgpu] Jul 30 10:18:10 youpi kernel: amdgpu_fence_driver_hw_fini+0xfa/0x130 [amdgpu] Jul 30 10:18:10 youpi kernel: amdgpu_device_fini_hw+0xa2/0x3f0 [amdgpu] Jul 30 10:18:10 youpi kernel: amdgpu_driver_load_kms+0x79/0xb0 [amdgpu] Jul 30 10:18:10 youpi kernel: amdgpu_pci_probe+0x195/0x520 [amdgpu] Jul 30 10:18:10 youpi kernel: local_pci_probe+0x41/0x90 Jul 30 10:18:10 youpi kernel: pci_device_probe+0xbb/0x1e0 Jul 30 10:18:10 youpi kernel: really_probe+0xd6/0x390 Jul 30 10:18:10 youpi kernel: ? __pfx___driver_attach+0x10/0x10 Jul 30 10:18:10 youpi kernel: __driver_probe_device+0x78/0x150 Jul 30 10:18:10 youpi kernel: driver_probe_device+0x1f/0x90 Jul 30 10:18:10 youpi kernel: __driver_attach+0xce/0x1c0 Jul 30 10:18:10 youpi kernel: bus_for_each_dev+0x84/0xd0 Jul 30 10:18:10 youpi kernel: bus_add_driver+0x10e/0x240 Jul 30 10:18:10 youpi kernel: driver_register+0x55/0x100 Jul 30 10:18:10 youpi kernel: ? __pfx_amdgpu_init+0x10/0x10 [amdgpu] Jul 30 10:18:10 youpi kernel: do_one_initcall+0x57/0x320 Jul 30 10:18:10 youpi kernel: do_init_module+0x60/0x230 Jul 30 10:18:10 youpi kernel: init_module_from_file+0x86/0xc0 Jul 30 10:18:10 youpi kernel: idempotent_init_module+0x11b/0x2b0 Jul 30 10:18:10 youpi kernel: __x64_sys_finit_module+0x5a/0xb0 Jul 30 10:18:10 youpi kernel: do_syscall_64+0x7e/0x190 Jul 30 10:18:10 youpi kernel: ? syscall_exit_to_user_mode+0xc/0x1d0 Jul 30 10:18:10 youpi kernel: ? do_syscall_64+0x8a/0x190 Jul 30 10:18:10 youpi kernel: ? do_syscall_64+0x8a/0x190 Jul 30 10:18:10 youpi kernel: ? syscall_exit_to_user_mode+0xc/0x1d0 Jul 30 10:18:10 youpi kernel: ? do_syscall_64+0x8a/0x190 Jul 30 10:18:10 youpi kernel: ?
[PULL] drm-misc-next
Hi Dave, Sima, here's the first PR for drm-misc-next for what will become Linux v6.12. It's the ususal mix of new features and bug fixes. Nouveau got a larger refactoring, there are some improvements within TTM, work on the panic screen progresses, mgag200 now supports VBLANK interrupts. Best regards Thomas drm-misc-next-2024-08-01: drm-misc-next for v6.12: UAPI Changes: virtio: - Define DRM capset Cross-subsystem Changes: dma-buf: - heaps: Clean up documentation printk: - Pass description to kmsg_dump() Core Changes: CI: - Update IGT tests - Point upstream repo to GitLab instance modesetting: - Introduce Power Saving Policy property for connectors - Add might_fault() to drm_modeset_lock priming - Add dynamic per-crtc vblank configuration support panic: - Avoid build-time interference with framebuffer console docs: - Document Colorspace property scheduler: - Remove full_recover from drm_sched_start TTM: - Make LRU walk restartable after dropping locks - Allow direct reclaim to allocate local memory Driver Changes: amdgpu: - Support Power Saving Policy connector property ast: - astdp: Support AST2600 with VGA; Clean up HPD bridge: - Silence error message on -EPROBE_DEFER - analogix: Clean aup - bridge-connector: Fix double free - lt6505: Disable interrupt when powered off - tc358767: Make default DP port preemphasis configurable gma500: - Update i2c terminology ivpu: - Add MODULE_FIRMWARE() lcdif: - Fix pixel clock loongson: - Use GEM refcount over TTM's mgag200: - Improve BMC handling - Support VBLANK intterupts nouveau: - Refactor and clean up internals - Use GEM refcount over TTM's panel: - Shutdown fixes plus documentation - Refactor several drivers for better code sharing - boe-th101mb31ig002: Support for starry-er88577 MIPI-DSI panel plus DT; Fix porch parameter - edp: Support AOU B116XTN02.3, AUO B116XAN06.1, AOU B116XAT04.1, BOE NV140WUM-N41, BOE NV133WUM-N63, BOE NV116WHM-A4D, CMN N116BCA-EA2, CMN N116BCP-EA2, CSW MNB601LS1-4 - himax-hx8394: Support Microchip AC40T08A MIPI Display panel plus DT - ilitek-ili9806e: Support Densitron DMT028VGHMCMI-1D TFT plus DT - jd9365da: Support Melfas lmfbx101117480 MIPI-DSI panel plus DT; Refactor for code sharing sti: - Fix module owner stm: - Avoid UAF wih managed plane and CRTC helpers - Fix module owner - Fix error handling in probe - Depend on COMMON_CLK - ltdc: Fix transparency after disabling plane; Remove unused interrupt tegra: - Call drm_atomic_helper_shutdown() v3d: - Clean up perfmon vkms: - Clean up The following changes since commit d4ef5d2b7ee0cbb5f2d864716140366a618400d6: Merge tag 'amd-drm-fixes-6.11-2024-07-25' of https://gitlab.freedesktop.org/agd5f/linux into drm-next (2024-07-26 09:52:15 +1000) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-next-2024-08-01 for you to fetch changes up to d97e71e449373efbd2403f1d7a32d416599f32ac: drm/bridge: synopsys: dw-mipi-dsi: enable EoTp by default (2024-08-01 13:34:18 +0200) drm-misc-next for v6.12: UAPI Changes: virtio: - Define DRM capset Cross-subsystem Changes: dma-buf: - heaps: Clean up documentation printk: - Pass description to kmsg_dump() Core Changes: CI: - Update IGT tests - Point upstream repo to GitLab instance modesetting: - Introduce Power Saving Policy property for connectors - Add might_fault() to drm_modeset_lock priming - Add dynamic per-crtc vblank configuration support panic: - Avoid build-time interference with framebuffer console docs: - Document Colorspace property scheduler: - Remove full_recover from drm_sched_start TTM: - Make LRU walk restartable after dropping locks - Allow direct reclaim to allocate local memory Driver Changes: amdgpu: - Support Power Saving Policy connector property ast: - astdp: Support AST2600 with VGA; Clean up HPD bridge: - Silence error message on -EPROBE_DEFER - analogix: Clean aup - bridge-connector: Fix double free - lt6505: Disable interrupt when powered off - tc358767: Make default DP port preemphasis configurable gma500: - Update i2c terminology ivpu: - Add MODULE_FIRMWARE() lcdif: - Fix pixel clock loongson: - Use GEM refcount over TTM's mgag200: - Improve BMC handling - Support VBLANK intterupts nouveau: - Refactor and clean up internals - Use GEM refcount over TTM's panel: - Shutdown fixes plus documentation - Refactor several drivers for better code sharing - boe-th101mb31ig002: Support for starry-er88577 MIPI-DSI panel plus DT; Fix porch parameter - edp: Support AOU B116XTN02.3, AUO B116XAN06.1, AOU B116XAT04.1, BOE NV140WUM-N41, BOE NV133WUM-N63, BOE NV116WHM-A4D, CMN N116BCA-EA2, CMN N116BCP-EA2, CSW MNB601LS1-4 - himax-hx8394: Support Microchip AC40T08A MIPI Display panel plus DT - ilitek-ili9806e: Support Densitron DMT028VGHMCMI-1D TFT plus DT - jd9365da: Support Melfas lmfbx101117480 MIPI-DSI panel plus DT; Refactor for code sharing
[PATCH rdma-next 6/8] RDMA: Pass uverbs_attr_bundle as part of '.reg_user_mr_dmabuf' API
From: Yishai Hadas Pass uverbs_attr_bundle as part of '.reg_user_mr_dmabuf' API instead of udata. This enables passing some new ioctl attributes to the drivers, as will be introduced in the next patches for mlx5 driver. Change the involved drivers accordingly. Signed-off-by: Yishai Hadas Signed-off-by: Leon Romanovsky --- drivers/infiniband/core/uverbs_std_types_mr.c | 2 +- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 3 ++- drivers/infiniband/hw/bnxt_re/ib_verbs.h | 2 +- drivers/infiniband/hw/efa/efa.h | 2 +- drivers/infiniband/hw/efa/efa_verbs.c | 4 ++-- drivers/infiniband/hw/irdma/verbs.c | 2 +- drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +- drivers/infiniband/hw/mlx5/mr.c | 2 +- include/rdma/ib_verbs.h | 2 +- 9 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/infiniband/core/uverbs_std_types_mr.c b/drivers/infiniband/core/uverbs_std_types_mr.c index 03e1db5d1e8c..7ebc7bd3caae 100644 --- a/drivers/infiniband/core/uverbs_std_types_mr.c +++ b/drivers/infiniband/core/uverbs_std_types_mr.c @@ -239,7 +239,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_REG_DMABUF_MR)( mr = pd->device->ops.reg_user_mr_dmabuf(pd, offset, length, iova, fd, access_flags, - >driver_udata); + attrs); if (IS_ERR(mr)) return PTR_ERR(mr); diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c index 7c757351a016..43a68e7de02a 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c @@ -4122,7 +4122,8 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length, struct ib_mr *bnxt_re_reg_user_mr_dmabuf(struct ib_pd *ib_pd, u64 start, u64 length, u64 virt_addr, int fd, -int mr_access_flags, struct ib_udata *udata) +int mr_access_flags, +struct uverbs_attr_bundle *attrs) { struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd); struct bnxt_re_dev *rdev = pd->rdev; diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h index e98cb1717338..3ddeda312376 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h @@ -242,7 +242,7 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, struct ib_mr *bnxt_re_reg_user_mr_dmabuf(struct ib_pd *ib_pd, u64 start, u64 length, u64 virt_addr, int fd, int mr_access_flags, -struct ib_udata *udata); +struct uverbs_attr_bundle *attrs); int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata); void bnxt_re_dealloc_ucontext(struct ib_ucontext *context); int bnxt_re_mmap(struct ib_ucontext *context, struct vm_area_struct *vma); diff --git a/drivers/infiniband/hw/efa/efa.h b/drivers/infiniband/hw/efa/efa.h index e580e087e9da..d7fc9d5eeefd 100644 --- a/drivers/infiniband/hw/efa/efa.h +++ b/drivers/infiniband/hw/efa/efa.h @@ -168,7 +168,7 @@ struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length, struct ib_mr *efa_reg_user_mr_dmabuf(struct ib_pd *ibpd, u64 start, u64 length, u64 virt_addr, int fd, int access_flags, -struct ib_udata *udata); +struct uverbs_attr_bundle *attrs); int efa_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata); int efa_get_port_immutable(struct ib_device *ibdev, u32 port_num, struct ib_port_immutable *immutable); diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c index b1e0a1b7c59d..cc13415ff7e7 100644 --- a/drivers/infiniband/hw/efa/efa_verbs.c +++ b/drivers/infiniband/hw/efa/efa_verbs.c @@ -1684,14 +1684,14 @@ static int efa_register_mr(struct ib_pd *ibpd, struct efa_mr *mr, u64 start, struct ib_mr *efa_reg_user_mr_dmabuf(struct ib_pd *ibpd, u64 start, u64 length, u64 virt_addr, int fd, int access_flags, -struct ib_udata *udata) +struct uverbs_attr_bundle *attrs) { struct efa_dev *dev = to_edev(ibpd->device); struct ib_umem_dmabuf *umem_dmabuf; struct efa_mr *mr; int err; - mr = efa_alloc_mr(ibpd, access_flags, udata); + mr = efa_alloc_mr(ibpd, access_flags, >driver_udata); if
[PATCH rdma-next 8/8] RDMA/mlx5: Introduce GET_DATA_DIRECT_SYSFS_PATH ioctl
From: Yishai Hadas Introduce the 'GET_DATA_DIRECT_SYSFS_PATH' ioctl to return the sysfs path of the affiliated 'data direct' device for a given device. Signed-off-by: Yishai Hadas Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/mlx5/std_types.c | 55 +++- include/uapi/rdma/mlx5_user_ioctl_cmds.h | 5 +++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mlx5/std_types.c b/drivers/infiniband/hw/mlx5/std_types.c index bbfcce3bdc84..ffeb1e1a1538 100644 --- a/drivers/infiniband/hw/mlx5/std_types.c +++ b/drivers/infiniband/hw/mlx5/std_types.c @@ -10,6 +10,7 @@ #include #include #include "mlx5_ib.h" +#include "data_direct.h" #define UVERBS_MODULE_NAME mlx5_ib #include @@ -183,6 +184,50 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_QUERY_PORT)( sizeof(info)); } +static int UVERBS_HANDLER(MLX5_IB_METHOD_GET_DATA_DIRECT_SYSFS_PATH)( + struct uverbs_attr_bundle *attrs) +{ + struct mlx5_data_direct_dev *data_direct_dev; + struct mlx5_ib_ucontext *c; + struct mlx5_ib_dev *dev; + int out_len = uverbs_attr_get_len(attrs, + MLX5_IB_ATTR_GET_DATA_DIRECT_SYSFS_PATH); + u32 dev_path_len; + char *dev_path; + int ret; + + c = to_mucontext(ib_uverbs_get_ucontext(attrs)); + if (IS_ERR(c)) + return PTR_ERR(c); + dev = to_mdev(c->ibucontext.device); + mutex_lock(>data_direct_lock); + data_direct_dev = dev->data_direct_dev; + if (!data_direct_dev) { + ret = -ENODEV; + goto end; + } + + dev_path = kobject_get_path(_direct_dev->device->kobj, GFP_KERNEL); + if (!dev_path) { + ret = -ENOMEM; + goto end; + } + + dev_path_len = strlen(dev_path) + 1; + if (dev_path_len > out_len) { + ret = -ENOSPC; + goto end; + } + + ret = uverbs_copy_to(attrs, MLX5_IB_ATTR_GET_DATA_DIRECT_SYSFS_PATH, dev_path, +dev_path_len); + kfree(dev_path); + +end: + mutex_unlock(>data_direct_lock); + return ret; +} + DECLARE_UVERBS_NAMED_METHOD( MLX5_IB_METHOD_QUERY_PORT, UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_QUERY_PORT_PORT_NUM, @@ -193,9 +238,17 @@ DECLARE_UVERBS_NAMED_METHOD( reg_c0), UA_MANDATORY)); +DECLARE_UVERBS_NAMED_METHOD( + MLX5_IB_METHOD_GET_DATA_DIRECT_SYSFS_PATH, + UVERBS_ATTR_PTR_OUT( + MLX5_IB_ATTR_GET_DATA_DIRECT_SYSFS_PATH, + UVERBS_ATTR_MIN_SIZE(0), + UA_MANDATORY)); + ADD_UVERBS_METHODS(mlx5_ib_device, UVERBS_OBJECT_DEVICE, - _METHOD(MLX5_IB_METHOD_QUERY_PORT)); + _METHOD(MLX5_IB_METHOD_QUERY_PORT), + _METHOD(MLX5_IB_METHOD_GET_DATA_DIRECT_SYSFS_PATH)); DECLARE_UVERBS_NAMED_METHOD( MLX5_IB_METHOD_PD_QUERY, diff --git a/include/uapi/rdma/mlx5_user_ioctl_cmds.h b/include/uapi/rdma/mlx5_user_ioctl_cmds.h index 106276a4cce7..fd2e4a3a56b3 100644 --- a/include/uapi/rdma/mlx5_user_ioctl_cmds.h +++ b/include/uapi/rdma/mlx5_user_ioctl_cmds.h @@ -348,6 +348,7 @@ enum mlx5_ib_pd_methods { enum mlx5_ib_device_methods { MLX5_IB_METHOD_QUERY_PORT = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_METHOD_GET_DATA_DIRECT_SYSFS_PATH, }; enum mlx5_ib_query_port_attrs { @@ -355,4 +356,8 @@ enum mlx5_ib_query_port_attrs { MLX5_IB_ATTR_QUERY_PORT, }; +enum mlx5_ib_get_data_direct_sysfs_path_attrs { + MLX5_IB_ATTR_GET_DATA_DIRECT_SYSFS_PATH = (1U << UVERBS_ID_NS_SHIFT), +}; + #endif -- 2.45.2
[PATCH rdma-next 7/8] RDMA/mlx5: Add support for DMABUF MR registrations with Data-direct
From: Yishai Hadas Add support for DMABUF MR registrations with Data-direct device. Upon userspace calling to register a DMABUF MR with the data direct bit set, the below algorithm will be followed. 1) Obtain a pinned DMABUF umem from the IB core using the user input parameters (FD, offset, length) and the DMA PF device. The DMA PF device is needed to allow the IOMMU to enable the DMA PF to access the user buffer over PCI. 2) Create a KSM MKEY by setting its entries according to the user buffer VA to IOVA mapping, with the MKEY being the data direct device-crossed MKEY. This KSM MKEY is umrable and will be used as part of the MR cache. The PD for creating it is the internal device 'data direct' kernel one. 3) Create a crossing MKEY that points to the KSM MKEY using the crossing access mode. 4) Manage the KSM MKEY by adding it to a list of 'data direct' MKEYs managed on the mlx5_ib device. 5) Return the crossing MKEY to the user, created with its supplied PD. Upon DMA PF unbind flow, the driver will revoke the KSM entries. The final deregistration will occur under the hood once the application deregisters its MKEY. Notes: - This version supports only the PINNED UMEM mode, so there is no dependency on ODP. - The IOVA supplied by the application must be system page aligned due to HW translations of KSM. - The crossing MKEY will not be umrable or part of the MR cache, as we cannot change its crossed (i.e. KSM) MKEY over UMR. Signed-off-by: Yishai Hadas Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/mlx5/main.c | 11 + drivers/infiniband/hw/mlx5/mlx5_ib.h | 8 + drivers/infiniband/hw/mlx5/mr.c | 304 +++--- drivers/infiniband/hw/mlx5/odp.c | 5 +- drivers/infiniband/hw/mlx5/umr.c | 93 --- drivers/infiniband/hw/mlx5/umr.h | 1 + include/uapi/rdma/mlx5_user_ioctl_cmds.h | 4 + include/uapi/rdma/mlx5_user_ioctl_verbs.h | 4 + 8 files changed, 358 insertions(+), 72 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index fc0562f07249..b85ad3c0bfa1 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -3490,6 +3490,7 @@ static int mlx5_ib_data_direct_init(struct mlx5_ib_dev *dev) if (ret) return ret; + INIT_LIST_HEAD(>data_direct_mr_list); ret = mlx5_data_direct_ib_reg(dev, vuid); if (ret) mlx5_ib_free_data_direct_resources(dev); @@ -3882,6 +3883,14 @@ ADD_UVERBS_ATTRIBUTES_SIMPLE( dump_fill_mkey), UA_MANDATORY)); +ADD_UVERBS_ATTRIBUTES_SIMPLE( + mlx5_ib_reg_dmabuf_mr, + UVERBS_OBJECT_MR, + UVERBS_METHOD_REG_DMABUF_MR, + UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_REG_DMABUF_MR_ACCESS_FLAGS, +enum mlx5_ib_uapi_reg_dmabuf_flags, +UA_OPTIONAL)); + static const struct uapi_definition mlx5_ib_defs[] = { UAPI_DEF_CHAIN(mlx5_ib_devx_defs), UAPI_DEF_CHAIN(mlx5_ib_flow_defs), @@ -3891,6 +3900,7 @@ static const struct uapi_definition mlx5_ib_defs[] = { UAPI_DEF_CHAIN(mlx5_ib_create_cq_defs), UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_DEVICE, _ib_query_context), + UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_MR, _ib_reg_dmabuf_mr), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_VAR, UAPI_DEF_IS_OBJ_SUPPORTED(var_is_supported)), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_UAR), @@ -4396,6 +4406,7 @@ void mlx5_ib_data_direct_bind(struct mlx5_ib_dev *ibdev, void mlx5_ib_data_direct_unbind(struct mlx5_ib_dev *ibdev) { mutex_lock(>data_direct_lock); + mlx5_ib_revoke_data_direct_mrs(ibdev); ibdev->data_direct_dev = NULL; mutex_unlock(>data_direct_lock); } diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index e915a62da49c..be83a4d91a34 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h @@ -682,6 +682,8 @@ struct mlx5_ib_mr { struct mlx5_ib_mkey mmkey; struct ib_umem *umem; + /* The mr is data direct related */ + u8 data_direct :1; union { /* Used only by kernel MRs (umem == NULL) */ @@ -719,6 +721,10 @@ struct mlx5_ib_mr { } odp_destroy; struct ib_odp_counters odp_stats; bool is_odp_implicit; + /* The affilated data direct crossed mr */ + struct mlx5_ib_mr *dd_crossed_mr; + struct list_head dd_node; + u8 revoked :1; }; }; }; @@ -1169,6 +1175,7 @@ struct mlx5_ib_dev { /* protect resources needed as part of reset flow */ spinlock_t reset_flow_resource_lock; struct list_headqp_list; +
[PATCH rdma-next 2/8] RDMA/mlx5: Introduce the 'data direct' driver
From: Yishai Hadas Introduce the 'data direct' driver for a ConnectX-8 Data Direct device. The 'data direct' driver functions as the affiliated DMA device for one or more capable mlx5_ib devices. This DMA device, as the name suggests, is used exclusively for DMA operations. It can be considered a DMA engine managed by a PF/VF, lacking network capabilities and having minimal overall capabilities. Consequently, the DMA NIC PF will not be exposed to or directly used by software applications. The driver will not have any direct interface or interaction with the firmware (no command interface, no capabilities, etc.). It will operate solely over PCI to enable its DMA functionality. Registration and un-registration of the driver are handled as part of the mlx5_ib initialization and exit processes, as the mlx5_ib devices will effectively be its clients. The driver will serve as the DMA device for accessing another PCI device to achieve optimal performance (both on the same NUMA node, P2P access, etc.). Upon probing, it will read its VUID over PCI to handle mlx5_ib device registrations with the same VUID. Upon removal, it will notify its clients to allow them to clean up the resources that were mmaped with its DMA device. Signed-off-by: Yishai Hadas Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/mlx5/Makefile | 1 + drivers/infiniband/hw/mlx5/data_direct.c | 227 +++ drivers/infiniband/hw/mlx5/data_direct.h | 23 +++ drivers/infiniband/hw/mlx5/main.c| 24 +++ drivers/infiniband/hw/mlx5/mlx5_ib.h | 6 + 5 files changed, 281 insertions(+) create mode 100644 drivers/infiniband/hw/mlx5/data_direct.c create mode 100644 drivers/infiniband/hw/mlx5/data_direct.h diff --git a/drivers/infiniband/hw/mlx5/Makefile b/drivers/infiniband/hw/mlx5/Makefile index 72a526236c2e..b38961f5058e 100644 --- a/drivers/infiniband/hw/mlx5/Makefile +++ b/drivers/infiniband/hw/mlx5/Makefile @@ -6,6 +6,7 @@ mlx5_ib-y := ah.o \ cong.o \ counters.o \ cq.o \ +data_direct.o \ dm.o \ doorbell.o \ gsi.o \ diff --git a/drivers/infiniband/hw/mlx5/data_direct.c b/drivers/infiniband/hw/mlx5/data_direct.c new file mode 100644 index ..b9ba84afaae2 --- /dev/null +++ b/drivers/infiniband/hw/mlx5/data_direct.c @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB +/* + * Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved + */ + +#include "mlx5_ib.h" +#include "data_direct.h" + +static LIST_HEAD(mlx5_data_direct_dev_list); +static LIST_HEAD(mlx5_data_direct_reg_list); + +/* + * This mutex should be held when accessing either of the above lists + */ +static DEFINE_MUTEX(mlx5_data_direct_mutex); + +struct mlx5_data_direct_registration { + struct mlx5_ib_dev *ibdev; + char vuid[MLX5_ST_SZ_BYTES(array1024_auto) + 1]; + struct list_head list; +}; + +static const struct pci_device_id mlx5_data_direct_pci_table[] = { + { PCI_VDEVICE(MELLANOX, 0x2100) }, /* ConnectX-8 Data Direct */ + { 0, } +}; + +static int mlx5_data_direct_vpd_get_vuid(struct mlx5_data_direct_dev *dev) +{ + struct pci_dev *pdev = dev->pdev; + unsigned int vpd_size, kw_len; + u8 *vpd_data; + int start; + int ret; + + vpd_data = pci_vpd_alloc(pdev, _size); + if (IS_ERR(vpd_data)) { + pci_err(pdev, "Unable to read VPD, err=%ld\n", PTR_ERR(vpd_data)); + return PTR_ERR(vpd_data); + } + + start = pci_vpd_find_ro_info_keyword(vpd_data, vpd_size, "VU", _len); + if (start < 0) { + ret = start; + pci_err(pdev, "VU keyword not found, err=%d\n", ret); + goto end; + } + + dev->vuid = kmemdup_nul(vpd_data + start, kw_len, GFP_KERNEL); + ret = dev->vuid ? 0 : -ENOMEM; + +end: + kfree(vpd_data); + return ret; +} + +static void mlx5_data_direct_shutdown(struct pci_dev *pdev) +{ + pci_disable_device(pdev); +} + +static int mlx5_data_direct_set_dma_caps(struct pci_dev *pdev) +{ + int err; + + err = dma_set_mask_and_coherent(>dev, DMA_BIT_MASK(64)); + if (err) { + dev_warn(>dev, +"Warning: couldn't set 64-bit PCI DMA mask, err=%d\n", err); + err = dma_set_mask_and_coherent(>dev, DMA_BIT_MASK(32)); + if (err) { + dev_err(>dev, "Can't set PCI DMA mask, err=%d\n", err); + return err; + } + } + + dma_set_max_seg_size(>dev, SZ_2G); + return 0; +} + +int mlx5_data_direct_ib_reg(struct mlx5_ib_dev *ibdev, char *vuid) +{ + struct mlx5_data_direct_registration *reg; + struct mlx5_data_direct_dev *dev; + + reg = kzalloc(sizeof(*reg), GFP_KERNEL); + if (!reg) + return -ENOMEM; + + reg->ibdev = ibdev; + strcpy(reg->vuid,
[PATCH rdma-next 4/8] RDMA/umem: Add support for creating pinned DMABUF umem with a given dma device
From: Yishai Hadas Add support for creating pinned DMABUF umem with a specified DMA device instead of the DMA device of the given IB device. This API will be utilized in the upcoming patches of the series when multiple path DMAs are implemented. Signed-off-by: Yishai Hadas Signed-off-by: Leon Romanovsky --- drivers/infiniband/core/umem_dmabuf.c | 45 --- include/rdma/ib_umem.h| 15 + 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c index 39357dc2d229..726a09786547 100644 --- a/drivers/infiniband/core/umem_dmabuf.c +++ b/drivers/infiniband/core/umem_dmabuf.c @@ -110,10 +110,12 @@ void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf) } EXPORT_SYMBOL(ib_umem_dmabuf_unmap_pages); -struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device *device, - unsigned long offset, size_t size, - int fd, int access, - const struct dma_buf_attach_ops *ops) +static struct ib_umem_dmabuf * +ib_umem_dmabuf_get_with_dma_device(struct ib_device *device, + struct device *dma_device, + unsigned long offset, size_t size, + int fd, int access, + const struct dma_buf_attach_ops *ops) { struct dma_buf *dmabuf; struct ib_umem_dmabuf *umem_dmabuf; @@ -152,7 +154,7 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device *device, umem_dmabuf->attach = dma_buf_dynamic_attach( dmabuf, - device->dma_device, + dma_device, ops, umem_dmabuf); if (IS_ERR(umem_dmabuf->attach)) { @@ -168,6 +170,15 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device *device, dma_buf_put(dmabuf); return ret; } + +struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device *device, + unsigned long offset, size_t size, + int fd, int access, + const struct dma_buf_attach_ops *ops) +{ + return ib_umem_dmabuf_get_with_dma_device(device, device->dma_device, + offset, size, fd, access, ops); +} EXPORT_SYMBOL(ib_umem_dmabuf_get); static void @@ -184,16 +195,18 @@ static struct dma_buf_attach_ops ib_umem_dmabuf_attach_pinned_ops = { .move_notify = ib_umem_dmabuf_unsupported_move_notify, }; -struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device, -unsigned long offset, -size_t size, int fd, -int access) +struct ib_umem_dmabuf * +ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device, + struct device *dma_device, + unsigned long offset, size_t size, + int fd, int access) { struct ib_umem_dmabuf *umem_dmabuf; int err; - umem_dmabuf = ib_umem_dmabuf_get(device, offset, size, fd, access, -_umem_dmabuf_attach_pinned_ops); + umem_dmabuf = ib_umem_dmabuf_get_with_dma_device(device, dma_device, offset, +size, fd, access, + _umem_dmabuf_attach_pinned_ops); if (IS_ERR(umem_dmabuf)) return umem_dmabuf; @@ -217,6 +230,16 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device, ib_umem_release(_dmabuf->umem); return ERR_PTR(err); } +EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_with_dma_device); + +struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device, +unsigned long offset, +size_t size, int fd, +int access) +{ + return ib_umem_dmabuf_get_pinned_with_dma_device(device, device->dma_device, +offset, size, fd, access); +} EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned); void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf) diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h index 565a85044541..de05268ed632 100644 --- a/include/rdma/ib_umem.h +++ b/include/rdma/ib_umem.h @@ -150,6 +150,11 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device
[PATCH rdma-next 5/8] RDMA/umem: Introduce an option to revoke DMABUF umem
From: Yishai Hadas Introduce an option to revoke DMABUF umem. This option will retain the umem allocation while revoking its DMA mapping. Furthermore, any subsequent attempts to map the pages should fail once the umem has been revoked. This functionality will be utilized in the upcoming patches in the series, where we aim to delay umem deallocation until the mkey deregistration. However, we must unmap its pages immediately. Signed-off-by: Yishai Hadas Signed-off-by: Leon Romanovsky --- drivers/infiniband/core/umem_dmabuf.c | 21 +++-- include/rdma/ib_umem.h| 3 +++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c index 726a09786547..9fcd37761264 100644 --- a/drivers/infiniband/core/umem_dmabuf.c +++ b/drivers/infiniband/core/umem_dmabuf.c @@ -23,6 +23,9 @@ int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf) dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv); + if (umem_dmabuf->revoked) + return -EINVAL; + if (umem_dmabuf->sgt) goto wait_fence; @@ -242,15 +245,29 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device, } EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned); -void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf) +void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf) { struct dma_buf *dmabuf = umem_dmabuf->attach->dmabuf; dma_resv_lock(dmabuf->resv, NULL); + if (umem_dmabuf->revoked) + goto end; ib_umem_dmabuf_unmap_pages(umem_dmabuf); - if (umem_dmabuf->pinned) + if (umem_dmabuf->pinned) { dma_buf_unpin(umem_dmabuf->attach); + umem_dmabuf->pinned = 0; + } + umem_dmabuf->revoked = 1; +end: dma_resv_unlock(dmabuf->resv); +} +EXPORT_SYMBOL(ib_umem_dmabuf_revoke); + +void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf) +{ + struct dma_buf *dmabuf = umem_dmabuf->attach->dmabuf; + + ib_umem_dmabuf_revoke(umem_dmabuf); dma_buf_detach(dmabuf, umem_dmabuf->attach); dma_buf_put(dmabuf); diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h index de05268ed632..7dc7b1cc71b5 100644 --- a/include/rdma/ib_umem.h +++ b/include/rdma/ib_umem.h @@ -38,6 +38,7 @@ struct ib_umem_dmabuf { unsigned long last_sg_trim; void *private; u8 pinned : 1; + u8 revoked : 1; }; static inline struct ib_umem_dmabuf *to_ib_umem_dmabuf(struct ib_umem *umem) @@ -158,6 +159,7 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device, int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf); void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf); void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf); +void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf); #else /* CONFIG_INFINIBAND_USER_MEM */ @@ -217,6 +219,7 @@ static inline int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf) } static inline void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf) { } static inline void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf) { } +static inline void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf) {} #endif /* CONFIG_INFINIBAND_USER_MEM */ #endif /* IB_UMEM_H */ -- 2.45.2
[PATCH rdma-next 3/8] RDMA/mlx5: Add the initialization flow to utilize the 'data direct' device
From: Yishai Hadas Add the NET device initialization flow to utilize the 'data direct' device. When a NET mlx5_ib device is capable of 'data direct', the following sequence of actions will occur: - Find its affiliated 'data direct' VUID via a firmware command. - Create its own private PD and 'data direct' mkey. - Register to be notified when its 'data direct' driver is probed or removed. The DMA device of the affiliated 'data direct' device, including the private PD and the 'data direct' mkey, will be used later during MR registrations that request the data direct functionality. Signed-off-by: Yishai Hadas Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/mlx5/cmd.c | 21 +++ drivers/infiniband/hw/mlx5/cmd.h | 2 + drivers/infiniband/hw/mlx5/main.c| 90 drivers/infiniband/hw/mlx5/mlx5_ib.h | 6 ++ 4 files changed, 119 insertions(+) diff --git a/drivers/infiniband/hw/mlx5/cmd.c b/drivers/infiniband/hw/mlx5/cmd.c index 895b62cc528d..7c08e3008927 100644 --- a/drivers/infiniband/hw/mlx5/cmd.c +++ b/drivers/infiniband/hw/mlx5/cmd.c @@ -245,3 +245,24 @@ int mlx5_cmd_uar_dealloc(struct mlx5_core_dev *dev, u32 uarn, u16 uid) MLX5_SET(dealloc_uar_in, in, uid, uid); return mlx5_cmd_exec_in(dev, dealloc_uar, in); } + +int mlx5_cmd_query_vuid(struct mlx5_core_dev *dev, bool data_direct, + char *out_vuid) +{ + u8 out[MLX5_ST_SZ_BYTES(query_vuid_out) + + MLX5_ST_SZ_BYTES(array1024_auto)] = {}; + u8 in[MLX5_ST_SZ_BYTES(query_vuid_in)] = {}; + char *vuid; + int err; + + MLX5_SET(query_vuid_in, in, opcode, MLX5_CMD_OPCODE_QUERY_VUID); + MLX5_SET(query_vuid_in, in, vhca_id, MLX5_CAP_GEN(dev, vhca_id)); + MLX5_SET(query_vuid_in, in, data_direct, data_direct); + err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); + if (err) + return err; + + vuid = MLX5_ADDR_OF(query_vuid_out, out, vuid); + memcpy(out_vuid, vuid, MLX5_ST_SZ_BYTES(array1024_auto)); + return 0; +} diff --git a/drivers/infiniband/hw/mlx5/cmd.h b/drivers/infiniband/hw/mlx5/cmd.h index e5cd31270443..e6c88b6ebd0d 100644 --- a/drivers/infiniband/hw/mlx5/cmd.h +++ b/drivers/infiniband/hw/mlx5/cmd.h @@ -58,4 +58,6 @@ int mlx5_cmd_mad_ifc(struct mlx5_ib_dev *dev, const void *inb, void *outb, u16 opmod, u8 port); int mlx5_cmd_uar_alloc(struct mlx5_core_dev *dev, u32 *uarn, u16 uid); int mlx5_cmd_uar_dealloc(struct mlx5_core_dev *dev, u32 uarn, u16 uid); +int mlx5_cmd_query_vuid(struct mlx5_core_dev *dev, bool data_direct, + char *out_vuid); #endif /* MLX5_IB_CMD_H */ diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index de254cf03173..fc0562f07249 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -3025,6 +3025,59 @@ static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev *dev) mutex_destroy(>srq_lock); } +static int +mlx5_ib_create_data_direct_resources(struct mlx5_ib_dev *dev) +{ + int inlen = MLX5_ST_SZ_BYTES(create_mkey_in); + struct mlx5_core_dev *mdev = dev->mdev; + void *mkc; + u32 mkey; + u32 pdn; + u32 *in; + int err; + + err = mlx5_core_alloc_pd(mdev, ); + if (err) + return err; + + in = kvzalloc(inlen, GFP_KERNEL); + if (!in) { + err = -ENOMEM; + goto err; + } + + MLX5_SET(create_mkey_in, in, data_direct, 1); + mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); + MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_PA); + MLX5_SET(mkc, mkc, lw, 1); + MLX5_SET(mkc, mkc, lr, 1); + MLX5_SET(mkc, mkc, rw, 1); + MLX5_SET(mkc, mkc, rr, 1); + MLX5_SET(mkc, mkc, a, 1); + MLX5_SET(mkc, mkc, pd, pdn); + MLX5_SET(mkc, mkc, length64, 1); + MLX5_SET(mkc, mkc, qpn, 0xff); + err = mlx5_core_create_mkey(mdev, , in, inlen); + kvfree(in); + if (err) + goto err; + + dev->ddr.mkey = mkey; + dev->ddr.pdn = pdn; + return 0; + +err: + mlx5_core_dealloc_pd(mdev, pdn); + return err; +} + +static void +mlx5_ib_free_data_direct_resources(struct mlx5_ib_dev *dev) +{ + mlx5_core_destroy_mkey(dev->mdev, dev->ddr.mkey); + mlx5_core_dealloc_pd(dev->mdev, dev->ddr.pdn); +} + static u32 get_core_cap_flags(struct ib_device *ibdev, struct mlx5_hca_vport_context *rep) { @@ -3421,6 +3474,38 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev, return false; } +static int mlx5_ib_data_direct_init(struct mlx5_ib_dev *dev) +{ + char vuid[MLX5_ST_SZ_BYTES(array1024_auto) + 1] = {}; + int ret; + + if (!MLX5_CAP_GEN(dev->mdev, data_direct)) + return 0; + + ret = mlx5_cmd_query_vuid(dev->mdev, true,
[PATCH mlx5-next 1/8] net/mlx5: Add IFC related stuff for data direct
From: Yishai Hadas Add IFC related stuff for data direct. Signed-off-by: Yishai Hadas Signed-off-by: Leon Romanovsky --- include/linux/mlx5/mlx5_ifc.h | 51 +++ 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index cab228cf51c6..970c9d8473ef 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -313,6 +313,7 @@ enum { MLX5_CMD_OP_MODIFY_VHCA_STATE = 0xb0e, MLX5_CMD_OP_SYNC_CRYPTO = 0xb12, MLX5_CMD_OP_ALLOW_OTHER_VHCA_ACCESS = 0xb16, + MLX5_CMD_OPCODE_QUERY_VUID= 0xb22, MLX5_CMD_OP_MAX }; @@ -1885,7 +1886,8 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 reserved_at_5a0[0x10]; u8 enhanced_cqe_compression[0x1]; - u8 reserved_at_5b1[0x2]; + u8 reserved_at_5b1[0x1]; + u8 crossing_vhca_mkey[0x1]; u8 log_max_dek[0x5]; u8 reserved_at_5b8[0x4]; u8 mini_cqe_resp_stride_index[0x1]; @@ -1954,7 +1956,9 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 dynamic_msix_table_size[0xc]; u8 reserved_at_740[0xc]; u8 min_dynamic_vf_msix_table_size[0x4]; - u8 reserved_at_750[0x4]; + u8 reserved_at_750[0x2]; + u8 data_direct[0x1]; + u8 reserved_at_753[0x1]; u8 max_dynamic_vf_msix_table_size[0xc]; u8 reserved_at_760[0x3]; @@ -1982,7 +1986,9 @@ struct mlx5_ifc_cmd_hca_cap_2_bits { u8 reserved_at_0[0x80]; u8 migratable[0x1]; - u8 reserved_at_81[0x1f]; + u8 reserved_at_81[0x11]; + u8 query_vuid[0x1]; + u8 reserved_at_93[0xd]; u8 max_reformat_insert_size[0x8]; u8 max_reformat_insert_offset[0x8]; @@ -4154,6 +4160,7 @@ enum { MLX5_MKC_ACCESS_MODE_KSM = 0x3, MLX5_MKC_ACCESS_MODE_SW_ICM = 0x4, MLX5_MKC_ACCESS_MODE_MEMIC = 0x5, + MLX5_MKC_ACCESS_MODE_CROSSING = 0x6, }; struct mlx5_ifc_mkc_bits { @@ -4196,7 +4203,10 @@ struct mlx5_ifc_mkc_bits { u8 bsf_octword_size[0x20]; - u8 reserved_at_120[0x80]; + u8 reserved_at_120[0x60]; + + u8 crossing_target_vhca_id[0x10]; + u8 reserved_at_190[0x10]; u8 translations_octword_size[0x20]; @@ -5124,6 +5134,36 @@ struct mlx5_ifc_query_vport_state_out_bits { u8 state[0x4]; }; +struct mlx5_ifc_array1024_auto_bits { + u8 array1024_auto[32][0x20]; +}; + +struct mlx5_ifc_query_vuid_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + + u8 reserved_at_20[0x40]; + + u8 query_vfs_vuid[0x1]; + u8 data_direct[0x1]; + u8 reserved_at_62[0xe]; + u8 vhca_id[0x10]; +}; + +struct mlx5_ifc_query_vuid_out_bits { + u8status[0x8]; + u8reserved_at_8[0x18]; + + u8syndrome[0x20]; + + u8reserved_at_40[0x1a0]; + + u8reserved_at_1e0[0x10]; + u8num_of_entries[0x10]; + + struct mlx5_ifc_array1024_auto_bits vuid[]; +}; + enum { MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT = 0x0, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT = 0x1, @@ -8989,7 +9029,8 @@ struct mlx5_ifc_create_mkey_in_bits { u8 pg_access[0x1]; u8 mkey_umem_valid[0x1]; - u8 reserved_at_62[0x1e]; + u8 data_direct[0x1]; + u8 reserved_at_63[0x1d]; struct mlx5_ifc_mkc_bits memory_key_mkey_entry; -- 2.45.2
[PATCH rdma-next 0/8] Introducing Multi-Path DMA Support for mlx5 RDMA Driver
From: Leon Romanovsky >From Yishai, Overview This patch series aims to enable multi-path DMA support, allowing an mlx5 RDMA device to issue DMA commands through multiple paths. This feature is critical for improving performance and reaching line rate in certain environments where issuing PCI transactions over one path may be significantly faster than over another. These differences can arise from various PCI generations in the system or the specific system topology. To achieve this functionality, we introduced a data direct DMA device that can serve the RDMA device by issuing DMA transactions on its behalf. The main key features and changes are described below. Multi-Path Discovery API Implementation: * Introduced an API to discover multiple paths for a given mlx5 RDMA device. IOCTL Command: * Added a new IOCTL command, MLX5_IB_METHOD_GET_DATA_DIRECT_SYSFS_PATH, to the DEVICE object. When an affiliated Data-Direct/DMA device is present, its sysfs path is returned. Feature Activation by mlx5 RDMA Application --- UVERBS Extension: * Extended UVERBS_METHOD_REG_DMABUF_MR over UVERBS_OBJECT_MR to include mlx5 extended flags. Access Flag: * Introduced the MLX5_IB_UAPI_REG_DMABUF_ACCESS_DATA_DIRECT flag, allowing applications to request the use of the affiliated DMA device for DMABUF registration. Data-Direct/DMA Device -- New Driver: * Introduced a new driver to manage the new DMA PF device ID (0x2100). Its registration/un-registration is handled as part of the mlx5_ib init/exit flows, with mlx5 IB devices as its clients. Functionality: * The driver does not interface directly with the firmware (no command interface, no caps, etc.) but works over PCI to activate its DMA functionality. It serves as the DMA device for efficiently accessing other PCI devices (e.g., GPU PF) and reads its VUID over PCI to handle NICs registrations with the same VUID. mlx5 IB RDMA Device --- VUID Query: * Reads its affiliated DMA PF VUID via the QUERY_VUID command with the data_direct bit set. Driver Registration: * Registers with the DMA PF driver to be notified upon bind/unbind. Application Request Handling: * Uses the DMA PF device upon application request as described above. DMABUF over Umem Introduced an option to obtain a DMABUF UMEM using a different DMA device instead of the IB device, allowing the device to register over IOMMU with the expected DMA device for a given buffer registration. Further details are provided in the commit logs of the patches in this series. Thanks Yishai Hadas (8): net/mlx5: Add IFC related stuff for data direct RDMA/mlx5: Introduce the 'data direct' driver RDMA/mlx5: Add the initialization flow to utilize the 'data direct' device RDMA/umem: Add support for creating pinned DMABUF umem with a given dma device RDMA/umem: Introduce an option to revoke DMABUF umem RDMA: Pass uverbs_attr_bundle as part of '.reg_user_mr_dmabuf' API RDMA/mlx5: Add support for DMABUF MR registrations with Data-direct RDMA/mlx5: Introduce GET_DATA_DIRECT_SYSFS_PATH ioctl drivers/infiniband/core/umem_dmabuf.c | 66 +++- drivers/infiniband/core/uverbs_std_types_mr.c | 2 +- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 3 +- drivers/infiniband/hw/bnxt_re/ib_verbs.h | 2 +- drivers/infiniband/hw/efa/efa.h | 2 +- drivers/infiniband/hw/efa/efa_verbs.c | 4 +- drivers/infiniband/hw/irdma/verbs.c | 2 +- drivers/infiniband/hw/mlx5/Makefile | 1 + drivers/infiniband/hw/mlx5/cmd.c | 21 ++ drivers/infiniband/hw/mlx5/cmd.h | 2 + drivers/infiniband/hw/mlx5/data_direct.c | 227 + drivers/infiniband/hw/mlx5/data_direct.h | 23 ++ drivers/infiniband/hw/mlx5/main.c | 125 +++ drivers/infiniband/hw/mlx5/mlx5_ib.h | 22 +- drivers/infiniband/hw/mlx5/mr.c | 304 +++--- drivers/infiniband/hw/mlx5/odp.c | 5 +- drivers/infiniband/hw/mlx5/std_types.c| 55 +++- drivers/infiniband/hw/mlx5/umr.c | 93 -- drivers/infiniband/hw/mlx5/umr.h | 1 + include/linux/mlx5/mlx5_ifc.h | 51 ++- include/rdma/ib_umem.h| 18 ++ include/rdma/ib_verbs.h | 2 +- include/uapi/rdma/mlx5_user_ioctl_cmds.h | 9 + include/uapi/rdma/mlx5_user_ioctl_verbs.h | 4 + 24 files changed, 944 insertions(+), 100 deletions(-) create mode 100644 drivers/infiniband/hw/mlx5/data_direct.c create mode 100644 drivers/infiniband/hw/mlx5/data_direct.h -- 2.45.2
Re: [PATCH 2/9] drm/i915: Use backlight power constants
On Wed, 31 Jul 2024, Thomas Zimmermann wrote: > Hi > > Am 31.07.24 um 14:56 schrieb Jani Nikula: >> On Wed, 31 Jul 2024, Thomas Zimmermann wrote: >>> Replace FB_BLANK_ constants with their counterparts from the >>> backlight subsystem. The values are identical, so there's no >>> change in functionality or semantics. >>> >>> Signed-off-by: Thomas Zimmermann >>> Cc: Jani Nikula >>> Cc: Rodrigo Vivi >>> Cc: Joonas Lahtinen >>> Cc: Tvrtko Ursulin >> Reviewed-by: Jani Nikula > > Thanks. > >> >> Do you want us to take this via drm-intel-next, or all together via >> drm-misc? Either is fine. > > drm-intel-next is fine. Pushed to drm-intel-next, thanks for the patch. BR, Jani. -- Jani Nikula, Intel
Re: [PATCH v2 1/2] drm/mipi-dsi: add more multi functions for better error handling
On 8/1/24 4:39 PM, Jani Nikula wrote: > On Tue, 30 Jul 2024, Tejas Vipin wrote: >> Add more functions that can benefit from being multi style and mark >> older variants as deprecated to eventually convert all mipi_dsi functions >> to multi style. > > What? > > Why would a lot of regular DSI commands that are not exclusively used > for one time setup need to be deprecated or converted to _multi()? > All of the functions I've marked as deprecated here have a good amount of their usage in conjunction with other mipi_dsi functions (an exception being mipi_dsi_dcs_get_display_brightness which I have realized is not suitable for this type of conversion). Them being rewritten as multi style functions saves a lot of early returns and errors being repeated over and over again across the codebase. In the cases where they are just called by themselves, there is very little overhead in replacing them with a multi variant. These functions would be better off converted to multi variants, and the old versions removed when all the function calls are replaced. > BR, > Jani. > >> >> Signed-off-by: Tejas Vipin >> --- >> drivers/gpu/drm/drm_mipi_dsi.c | 226 + >> include/drm/drm_mipi_dsi.h | 12 ++ >> 2 files changed, 238 insertions(+) >> >> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c >> index a471c46f5ca6..05ea7df5dec1 100644 >> --- a/drivers/gpu/drm/drm_mipi_dsi.c >> +++ b/drivers/gpu/drm/drm_mipi_dsi.c >> @@ -603,6 +603,8 @@ EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral); >> * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command >> * @dsi: DSI peripheral device >> * >> + * This function is deprecated. Use mipi_dsi_turn_on_peripheral_multi() >> instead. >> + * >> * Return: 0 on success or a negative error code on failure. >> */ >> int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi) >> @@ -652,6 +654,7 @@ EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); >> * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS >> entries >> * >> * Enable or disable Display Stream Compression on the peripheral. >> + * This function is deprecated. Use mipi_dsi_compression_mode_ext_multi() >> instead. >> * >> * Return: 0 on success or a negative error code on failure. >> */ >> @@ -703,6 +706,7 @@ EXPORT_SYMBOL(mipi_dsi_compression_mode); >> * @pps: VESA DSC 1.1 Picture Parameter Set >> * >> * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral. >> + * This function is deprecated. Use mipi_dsi_picture_parameter_set_multi() >> instead. >> * >> * Return: 0 on success or a negative error code on failure. >> */ >> @@ -1037,6 +1041,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_read); >> * mipi_dsi_dcs_nop() - send DCS nop packet >> * @dsi: DSI peripheral device >> * >> + * This function is deprecated. Use mipi_dsi_dcs_nop_multi() instead. >> + * >> * Return: 0 on success or a negative error code on failure. >> */ >> int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi) >> @@ -1055,6 +1061,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_nop); >> * mipi_dsi_dcs_soft_reset() - perform a software reset of the display >> module >> * @dsi: DSI peripheral device >> * >> + * This function is deprecated. Use mipi_dsi_dcs_soft_reset_multi() instead. >> + * >> * Return: 0 on success or a negative error code on failure. >> */ >> int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi) >> @@ -1124,6 +1132,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format); >> *display module except interface communication >> * @dsi: DSI peripheral device >> * >> + * This function is deprecated. Use mipi_dsi_dcs_enter_sleep_mode_multi() >> instead. >> + * >> * Return: 0 on success or a negative error code on failure. >> */ >> int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi) >> @@ -1143,6 +1153,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode); >> *module >> * @dsi: DSI peripheral device >> * >> + * This function is deprecated. Use mipi_dsi_dcs_exit_sleep_mode_multi() >> instead. >> + * >> * Return: 0 on success or a negative error code on failure. >> */ >> int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi) >> @@ -1162,6 +1174,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode); >> *display device >> * @dsi: DSI peripheral device >> * >> + * This function is deprecated. Use mipi_dsi_dcs_set_display_off_multi() >> instead. >> + * >> * Return: 0 on success or a negative error code on failure. >> */ >> int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi) >> @@ -1181,6 +1195,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off); >> *display device >> * @dsi: DSI peripheral device >> * >> + * This function is deprecated. Use mipi_dsi_dcs_set_display_on_multi() >> instead. >> + * >> * Return: 0 on success or a negative error code on failure >> */ >> int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi) >> @@ -1202,6 +1218,9
Re: [PATCH] drm: Add documentation for struct drm_pane_size_hint
On Thu, 01 Aug 2024, abid-sayyad wrote: > Fixed warning for the following: > ./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct > member > 'width' not described in 'drm_plane_size_hint' > ./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct > member > 'height' not described in 'drm_plane_size_hint' > > Signed-off-by: abid-sayyad > --- > include/uapi/drm/drm_mode.h | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h > index d390011b89b4..b581d384d4b5 100644 > --- a/include/uapi/drm/drm_mode.h > +++ b/include/uapi/drm/drm_mode.h > @@ -864,7 +864,13 @@ struct drm_color_lut { > * array of struct drm_plane_size_hint. > */ > struct drm_plane_size_hint { > + /** > + * @width : width of the plane in pixels. Please no space before :. BR, Jani. > + */ > __u16 width; > + /** > + * @height : height of the plane in pixels. > + */ > __u16 height; > }; -- Jani Nikula, Intel
Re: [PATCH v2 1/2] drm/mipi-dsi: add more multi functions for better error handling
On Tue, 30 Jul 2024, Tejas Vipin wrote: > Add more functions that can benefit from being multi style and mark > older variants as deprecated to eventually convert all mipi_dsi functions > to multi style. What? Why would a lot of regular DSI commands that are not exclusively used for one time setup need to be deprecated or converted to _multi()? BR, Jani. > > Signed-off-by: Tejas Vipin > --- > drivers/gpu/drm/drm_mipi_dsi.c | 226 + > include/drm/drm_mipi_dsi.h | 12 ++ > 2 files changed, 238 insertions(+) > > diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c > index a471c46f5ca6..05ea7df5dec1 100644 > --- a/drivers/gpu/drm/drm_mipi_dsi.c > +++ b/drivers/gpu/drm/drm_mipi_dsi.c > @@ -603,6 +603,8 @@ EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral); > * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command > * @dsi: DSI peripheral device > * > + * This function is deprecated. Use mipi_dsi_turn_on_peripheral_multi() > instead. > + * > * Return: 0 on success or a negative error code on failure. > */ > int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi) > @@ -652,6 +654,7 @@ EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); > * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS > entries > * > * Enable or disable Display Stream Compression on the peripheral. > + * This function is deprecated. Use mipi_dsi_compression_mode_ext_multi() > instead. > * > * Return: 0 on success or a negative error code on failure. > */ > @@ -703,6 +706,7 @@ EXPORT_SYMBOL(mipi_dsi_compression_mode); > * @pps: VESA DSC 1.1 Picture Parameter Set > * > * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral. > + * This function is deprecated. Use mipi_dsi_picture_parameter_set_multi() > instead. > * > * Return: 0 on success or a negative error code on failure. > */ > @@ -1037,6 +1041,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_read); > * mipi_dsi_dcs_nop() - send DCS nop packet > * @dsi: DSI peripheral device > * > + * This function is deprecated. Use mipi_dsi_dcs_nop_multi() instead. > + * > * Return: 0 on success or a negative error code on failure. > */ > int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi) > @@ -1055,6 +1061,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_nop); > * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module > * @dsi: DSI peripheral device > * > + * This function is deprecated. Use mipi_dsi_dcs_soft_reset_multi() instead. > + * > * Return: 0 on success or a negative error code on failure. > */ > int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi) > @@ -1124,6 +1132,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format); > *display module except interface communication > * @dsi: DSI peripheral device > * > + * This function is deprecated. Use mipi_dsi_dcs_enter_sleep_mode_multi() > instead. > + * > * Return: 0 on success or a negative error code on failure. > */ > int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi) > @@ -1143,6 +1153,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode); > *module > * @dsi: DSI peripheral device > * > + * This function is deprecated. Use mipi_dsi_dcs_exit_sleep_mode_multi() > instead. > + * > * Return: 0 on success or a negative error code on failure. > */ > int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi) > @@ -1162,6 +1174,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode); > *display device > * @dsi: DSI peripheral device > * > + * This function is deprecated. Use mipi_dsi_dcs_set_display_off_multi() > instead. > + * > * Return: 0 on success or a negative error code on failure. > */ > int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi) > @@ -1181,6 +1195,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off); > *display device > * @dsi: DSI peripheral device > * > + * This function is deprecated. Use mipi_dsi_dcs_set_display_on_multi() > instead. > + * > * Return: 0 on success or a negative error code on failure > */ > int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi) > @@ -1202,6 +1218,9 @@ EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on); > * @start: first column of frame memory > * @end: last column of frame memory > * > + * This function is deprecated. Use mipi_dsi_dcs_set_column_address_multi() > + * instead. > + * > * Return: 0 on success or a negative error code on failure. > */ > int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, > @@ -1226,6 +1245,9 @@ EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address); > * @start: first page of frame memory > * @end: last page of frame memory > * > + * This function is deprecated. Use mipi_dsi_dcs_set_page_address_multi() > + * instead. > + * > * Return: 0 on success or a negative error code on failure. > */ > int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, > @@ -1268,6 +1290,8 @@
Re: [PATCH 1/5] udmabuf: cancel mmap page fault, direct map it
在 2024/8/1 18:50, Christian König 写道: Am 01.08.24 um 12:45 schrieb Huan Yang: The current udmabuf mmap uses a page fault mechanism to populate the vma. However, the current udmabuf has already obtained and pinned the folio upon completion of the creation.This means that the physical memory has already been acquired, rather than being accessed dynamically. The current page fault method only saves some page table memory. As a result, the page fault mechanism has lost its purpose as a demanding page. Due to the fact that page fault requires trapping into kernel mode and filling in when accessing the corresponding virtual address in mmap, this means that user mode access to virtual addresses needs to trap into kernel mode. Therefore, when creating a large size udmabuf, this represents a considerable overhead. Therefore, the current patch removes the page fault method of mmap and instead fills it directly when mmap is triggered. Signed-off-by: Huan Yang --- drivers/dma-buf/udmabuf.c | 70 ++- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 047c3cd2ceff..d69aeada7367 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -38,36 +38,39 @@ struct udmabuf_folio { struct list_head list; }; -static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf) -{ - struct vm_area_struct *vma = vmf->vma; - struct udmabuf *ubuf = vma->vm_private_data; - pgoff_t pgoff = vmf->pgoff; - unsigned long pfn; - - if (pgoff >= ubuf->pagecount) - return VM_FAULT_SIGBUS; - - pfn = folio_pfn(ubuf->folios[pgoff]); - pfn += ubuf->offsets[pgoff] >> PAGE_SHIFT; - - return vmf_insert_pfn(vma, vmf->address, pfn); -} - -static const struct vm_operations_struct udmabuf_vm_ops = { - .fault = udmabuf_vm_fault, -}; +static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, + enum dma_data_direction direction); static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) { struct udmabuf *ubuf = buf->priv; + struct sg_table *table = ubuf->sg; + unsigned long addr = vma->vm_start; + struct sg_page_iter piter; + int ret; if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0) return -EINVAL; - vma->vm_ops = _vm_ops; - vma->vm_private_data = ubuf; - vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP); + if (!table) { + table = get_sg_table(NULL, buf, 0); + if (IS_ERR(table)) + return PTR_ERR(table); + ubuf->sg = table; + } + + for_each_sgtable_page(table, , vma->vm_pgoff) { That might not work correctly. We intentionally remove the pages from the sgtable when it is shared between devices. Additional to that the sgtable is *not* a page container, but rather a DMA address container. So that here is also a rather bad idea from the design side. Sorry for that and patch 1 3 4's ops. I was not aware of this before. All idea to do this in mmap/vmap is just like system_heap and any other heaps that I learned. But well to learn it. BTW, sgtable is a wrong idea to maintain page, maybe we need to both setup page's array(order 0 page), and folio's array(only the folio, use for unpin)? Or else, mapping page to vm_off and vma solely through folio's array is quite challenging. Moreover, even in this way, the memory overhead is smaller than the current unpin list. Thanks for your correct.:) Regards, Christian. + struct page *page = sg_page_iter_page(); + + ret = remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE, + vma->vm_page_prot); + if (ret) + return ret; + addr += PAGE_SIZE; + if (addr >= vma->vm_end) + return 0; + } + return 0; } @@ -126,6 +129,10 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, sg_set_folio(sgl, ubuf->folios[i], PAGE_SIZE, ubuf->offsets[i]); + // if dev is NULL, no need to sync. + if (!dev) + return sg; + ret = dma_map_sgtable(dev, sg, direction, 0); if (ret < 0) goto err_map; @@ -206,20 +213,21 @@ static int begin_cpu_udmabuf(struct dma_buf *buf, { struct udmabuf *ubuf = buf->priv; struct device *dev = ubuf->device->this_device; - int ret = 0; + struct sg_table *sg; - if (!ubuf->sg) { - ubuf->sg = get_sg_table(dev, buf, direction); - if (IS_ERR(ubuf->sg)) { - ret = PTR_ERR(ubuf->sg); - ubuf->sg = NULL; - } - } else { + if (ubuf->sg) { dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents, direction); + return 0; } - return ret; + sg = get_sg_table(dev, buf, direction); + if (IS_ERR(sg)) + return PTR_ERR(sg); + + ubuf->sg = sg; + + return 0; }
Re: [PATCH] backlight: pwm_bl: print errno for probe errors
Am Donnerstag, dem 01.08.2024 um 12:09 +0200 schrieb Uwe Kleine-König: > Hello Martin, > > On Thu, Aug 01, 2024 at 09:52:01AM +, Kepplinger-Novakovic Martin > wrote: > > Am Donnerstag, dem 01.08.2024 um 11:26 +0200 schrieb Uwe Kleine- > > König: > > > On Thu, Aug 01, 2024 at 11:12:55AM +0200, Martin Kepplinger- > > > Novaković > > > wrote: > > > > diff --git a/drivers/video/backlight/pwm_bl.c > > > > b/drivers/video/backlight/pwm_bl.c > > > > index f1005bd0c41e3..cc7e7af71891f 100644 > > > > --- a/drivers/video/backlight/pwm_bl.c > > > > +++ b/drivers/video/backlight/pwm_bl.c > > > > @@ -502,7 +502,8 @@ static int pwm_backlight_probe(struct > > > > platform_device *pdev) > > > > GPIOD_ASIS); > > > > if (IS_ERR(pb->enable_gpio)) { > > > > ret = dev_err_probe(>dev, PTR_ERR(pb- > > > > > enable_gpio), > > > > - "failed to acquire enable > > > > GPIO\n"); > > > > + "failed to acquire enable > > > > GPIO: > > > > %ld\n", > > > > + PTR_ERR(pb->enable_gpio)); > > > > > > AFAIK dev_err_probe already emits the error code passed as 2nd > > > parameter. So I wonder about this patch's benefit. > > > > > > > It does. Other messages only take the deferred_probe_reason without > > the > > error code. It's actually fine if users properly enable debugging > > after > > seeing an error and then this change is not needed :) > > I'm unsure what you intend to say here. Do you agree that this patch > doesn't need to be applied as it doesn't add any information to the > emitted messages? Or do you think there is a value because "users > don't > need to enable debugging" then. In the latter case I don't see where > users would see "failed to acquire enable GPIO" before, but not the > value of the error code. > hi Uwe, sorry, I agree that this patch doesn't add any information. I think it can be expected to look at debug when drivers don't probe. thanks, martin smime.p7s Description: S/MIME cryptographic signature
[PATCH] backlight: pwm_bl: print errno for probe errors
This makes debugging often easier. Signed-off-by: Martin Kepplinger-Novaković --- drivers/video/backlight/pwm_bl.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index f1005bd0c41e3..cc7e7af71891f 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -502,7 +502,8 @@ static int pwm_backlight_probe(struct platform_device *pdev) GPIOD_ASIS); if (IS_ERR(pb->enable_gpio)) { ret = dev_err_probe(>dev, PTR_ERR(pb->enable_gpio), - "failed to acquire enable GPIO\n"); + "failed to acquire enable GPIO: %ld\n", + PTR_ERR(pb->enable_gpio)); goto err_alloc; } @@ -513,7 +514,8 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->power_supply = NULL; } else { dev_err_probe(>dev, ret, - "failed to acquire power regulator\n"); + "failed to acquire power regulator: %d\n", + ret); goto err_alloc; } } @@ -521,7 +523,8 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->pwm = devm_pwm_get(>dev, NULL); if (IS_ERR(pb->pwm)) { ret = dev_err_probe(>dev, PTR_ERR(pb->pwm), - "unable to request PWM\n"); + "unable to request PWM: %ld\n", + PTR_ERR(pb->pwm)); goto err_alloc; } -- 2.39.2 smime.p7s Description: S/MIME cryptographic signature
Re: [PATCH] backlight: pwm_bl: print errno for probe errors
Am Donnerstag, dem 01.08.2024 um 11:26 +0200 schrieb Uwe Kleine-König: > Hello Martin, > > On Thu, Aug 01, 2024 at 11:12:55AM +0200, Martin Kepplinger-Novaković > wrote: > > This makes debugging often easier. > > > > Signed-off-by: Martin Kepplinger-Novaković > > > > --- > > drivers/video/backlight/pwm_bl.c | 9 ++--- > > 1 file changed, 6 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/video/backlight/pwm_bl.c > > b/drivers/video/backlight/pwm_bl.c > > index f1005bd0c41e3..cc7e7af71891f 100644 > > --- a/drivers/video/backlight/pwm_bl.c > > +++ b/drivers/video/backlight/pwm_bl.c > > @@ -502,7 +502,8 @@ static int pwm_backlight_probe(struct > > platform_device *pdev) > > GPIOD_ASIS); > > if (IS_ERR(pb->enable_gpio)) { > > ret = dev_err_probe(>dev, PTR_ERR(pb- > > >enable_gpio), > > - "failed to acquire enable > > GPIO\n"); > > + "failed to acquire enable GPIO: > > %ld\n", > > + PTR_ERR(pb->enable_gpio)); > > AFAIK dev_err_probe already emits the error code passed as 2nd > parameter. So I wonder about this patch's benefit. > It does. Other messages only take the deferred_probe_reason without the error code. It's actually fine if users properly enable debugging after seeing an error and then this change is not needed :) thanks, martin smime.p7s Description: S/MIME cryptographic signature
[PATCH] drm: Add documentation for struct drm_pane_size_hint
Fixed warning for the following: ./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct member 'width' not described in 'drm_plane_size_hint' ./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct member 'height' not described in 'drm_plane_size_hint' Signed-off-by: abid-sayyad --- include/uapi/drm/drm_mode.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index d390011b89b4..b581d384d4b5 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -864,7 +864,13 @@ struct drm_color_lut { * array of struct drm_plane_size_hint. */ struct drm_plane_size_hint { + /** +* @width : width of the plane in pixels. +*/ __u16 width; + /** +* @height : height of the plane in pixels. +*/ __u16 height; }; -- 2.39.2
[PATCH] [V2] drm: panel-orientation-quirks: Also handle rotation for DeckHD equipped LCDs units
From: Marco Rodolfi This patch also take account of the different resolution for the aftermarket DeckHD panel, which hasn't been accounted for yet in kernel, since these quirks are applied based on BIOS information + panel resolution. This patch correct that problem and make the panel oriented the right way. Changes in V2: Had some issues with gmail and this mailinglist that I completely mistyped the panel resolution in the original patch. It is still a 16:10 panel, not a 16:9, so the original one is wrong. It's fixed now. Signed-off-by: Marco Rodolfi --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index 3860a8ce1e2d..32582dbdc184 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -420,13 +420,20 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galaxy Book 10.6"), }, .driver_data = (void *)_rightside_up, - }, {/* Valve Steam Deck (Jupiter) */ + }, {/* Valve Steam Deck (Jupiter) Stock Display */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"), DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), }, .driver_data = (void *)_rightside_up, + }, {/* Valve Steam Deck (Jupiter) DeckHD Display */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), + }, + .driver_data = (void *)_rightside_up, }, {/* Valve Steam Deck (Galileo) */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), -- 2.46.0
Re: [PATCH 4/5] udmabuf: add get_sg_table helper function
Am 01.08.24 um 12:45 schrieb Huan Yang: Currently, there are three duplicate pieces of code that retrieve sg_table and update uduf->sg. Since the sgt is used to populate the page in both mmap and vmap.It is necessary to ensure that ubuf->sg is set correctly. That is a really bad idea. Why are sg tables used to populated the page tables? Regards, Christian. This patch add a helper function, if ubuf->sg exist, just return it. Or else, try alloc a new sgt, and cmpxchg to set it. When the swap fails, it means that another process has set sg correctly. Therefore, we reuse the new sg. If trigger by device, need invoke map to sync it. Signed-off-by: Huan Yang --- drivers/dma-buf/udmabuf.c | 60 --- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 7ed532342d7f..677ebb2d462f 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -38,8 +38,9 @@ struct udmabuf_folio { struct list_head list; }; -static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, -enum dma_data_direction direction); +static struct sg_table *udmabuf_get_sg_table(struct device *dev, +struct dma_buf *buf, +enum dma_data_direction direction); static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) { @@ -52,12 +53,9 @@ static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0) return -EINVAL; - if (!table) { - table = get_sg_table(NULL, buf, 0); - if (IS_ERR(table)) - return PTR_ERR(table); - ubuf->sg = table; - } + table = udmabuf_get_sg_table(NULL, buf, 0); + if (IS_ERR(table)) + return PTR_ERR(table); for_each_sgtable_page(table, , vma->vm_pgoff) { struct page *page = sg_page_iter_page(); @@ -84,12 +82,9 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map) dma_resv_assert_held(buf->resv); - if (!sg) { - sg = get_sg_table(NULL, buf, 0); - if (IS_ERR(sg)) - return PTR_ERR(sg); - ubuf->sg = sg; - } + sg = udmabuf_get_sg_table(NULL, buf, 0); + if (IS_ERR(sg)) + return PTR_ERR(sg); pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL); if (!pages) @@ -154,6 +149,39 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, return ERR_PTR(ret); } +static struct sg_table *udmabuf_get_sg_table(struct device *dev, +struct dma_buf *buf, +enum dma_data_direction direction) +{ + struct udmabuf *ubuf = buf->priv; + struct sg_table *sg = READ_ONCE(ubuf->sg); + int ret = 0; + + if (sg) + return sg; + + sg = get_sg_table(dev, buf, direction); + if (IS_ERR(sg)) + return sg; + + // Success update ubuf's sg, just return. + if (!cmpxchg(>sg, NULL, sg)) + return sg; + + // use the new sg table. + sg_free_table(sg); + kfree(sg); + sg = READ_ONCE(ubuf->sg); + + if (dev) + ret = dma_map_sgtable(dev, sg, direction, 0); + + if (ret < 0) + return ERR_PTR(ret); + + return sg; +} + static void put_sg_table(struct device *dev, struct sg_table *sg, enum dma_data_direction direction) { @@ -230,12 +258,10 @@ static int begin_cpu_udmabuf(struct dma_buf *buf, return 0; } - sg = get_sg_table(dev, buf, direction); + sg = udmabuf_get_sg_table(dev, buf, direction); if (IS_ERR(sg)) return PTR_ERR(sg); - ubuf->sg = sg; - return 0; }
[syzbot] [dri?] WARNING in drm_wait_one_vblank (2)
Hello, syzbot found the following issue on: HEAD commit:6342649c33d2 Merge tag 'block-6.11-20240726' of git://git... git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=1443cb0398 kernel config: https://syzkaller.appspot.com/x/.config?x=5efb917b1462a973 dashboard link: https://syzkaller.appspot.com/bug?extid=147ba789658184f0ce04 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 Unfortunately, I don't have any reproducer for this issue yet. Downloadable assets: disk image: https://storage.googleapis.com/syzbot-assets/6057dd16bc1c/disk-6342649c.raw.xz vmlinux: https://storage.googleapis.com/syzbot-assets/4121b87a6477/vmlinux-6342649c.xz kernel image: https://storage.googleapis.com/syzbot-assets/57d676edb7cb/bzImage-6342649c.xz IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+147ba789658184f0c...@syzkaller.appspotmail.com [ cut here ] platform vkms: [drm] vblank wait timed out on crtc 0 WARNING: CPU: 1 PID: 7412 at drivers/gpu/drm/drm_vblank.c:1307 drm_wait_one_vblank+0x976/0x9f0 drivers/gpu/drm/drm_vblank.c:1307 Modules linked in: CPU: 1 UID: 0 PID: 7412 Comm: syz.1.410 Not tainted 6.10.0-syzkaller-12881-g6342649c33d2 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 06/27/2024 RIP: 0010:drm_wait_one_vblank+0x976/0x9f0 drivers/gpu/drm/drm_vblank.c:1307 Code: 80 3c 08 00 74 08 4c 89 ff e8 76 0a 9c fc 49 8b 1f 48 c7 c7 e0 f4 72 8c 4c 89 f6 48 89 da 8b 5c 24 0c 89 d9 e8 0b e1 f6 fb 90 <0f> 0b 90 90 49 be 00 00 00 00 00 fc ff df e9 68 fb ff ff 44 89 e9 RSP: 0018:c90003f87ac0 EFLAGS: 00010246 RAX: 1af066dba6c5c900 RBX: RCX: 0004 RDX: c900041f9000 RSI: 00031631 RDI: 00031632 RBP: c90003f87c00 R08: 815592f2 R09: fbfff1cf9f80 R10: dc00 R11: fbfff1cf9f80 R12: 1920007f0f64 R13: 2635 R14: 8c861520 R15: 888020618010 FS: 7ff6598ef6c0() GS:8880b930() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: 7ff6598ced58 CR3: 4b096000 CR4: 003506f0 DR0: DR1: DR2: DR3: DR6: fffe0ff0 DR7: 0400 Call Trace: drm_fb_helper_ioctl+0x114/0x140 drivers/gpu/drm/drm_fb_helper.c:1088 do_fb_ioctl+0x40a/0x7b0 drivers/video/fbdev/core/fb_chrdev.c:155 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7ff658b77299 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:7ff6598ef048 EFLAGS: 0246 ORIG_RAX: 0010 RAX: ffda RBX: 7ff658d05f80 RCX: 7ff658b77299 RDX: RSI: 40044620 RDI: 0003 RBP: 7ff658be48e6 R08: R09: R10: R11: 0246 R12: R13: 000b R14: 7ff658d05f80 R15: 7ff658e2fa38 --- This report is generated by a bot. It may contain errors. See https://goo.gl/tpsmEJ for more information about syzbot. syzbot engineers can be reached at syzkal...@googlegroups.com. syzbot will keep track of this issue. See: https://goo.gl/tpsmEJ#status for how to communicate with syzbot. If the report is already addressed, let syzbot know by replying with: #syz fix: exact-commit-title If you want to overwrite report's subsystems, reply with: #syz set subsystems: new-subsystem (See the list of subsystem names on the web dashboard) If the report is a duplicate of another one, reply with: #syz dup: exact-subject-of-another-report If you want to undo deduplication, reply with: #syz undup
Re: [PATCH 3/5] udmabuf: fix vmap_udmabuf error page set
Am 01.08.24 um 12:45 schrieb Huan Yang: Currently vmap_udmabuf set page's array by each folio. But, ubuf->folios is only contain's the folio's head page. That mean we repeatedly mapped the folio head page to the vmalloc area. This patch fix it, set each folio's page correct, so that pages array contains right page, and then map into vmalloc area Signed-off-by: Huan Yang --- drivers/dma-buf/udmabuf.c | 17 + 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index a915714c5dce..7ed532342d7f 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -77,18 +77,27 @@ static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map) { struct udmabuf *ubuf = buf->priv; - struct page **pages; + struct page **pages, **tmp; + struct sg_table *sg = ubuf->sg; + struct sg_page_iter piter; void *vaddr; - pgoff_t pg; dma_resv_assert_held(buf->resv); + if (!sg) { + sg = get_sg_table(NULL, buf, 0); + if (IS_ERR(sg)) + return PTR_ERR(sg); + ubuf->sg = sg; + } + pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL); if (!pages) return -ENOMEM; + tmp = pages; - for (pg = 0; pg < ubuf->pagecount; pg++) - pages[pg] = >folios[pg]->page; + for_each_sgtable_page(sg, , 0) + *tmp++ = sg_page_iter_page(); Again don't abuse the sg table for that! Regards, Christian. vaddr = vm_map_ram(pages, ubuf->pagecount, -1); kvfree(pages);
Re: [PATCH 2/5] udmabuf: change folios array from kmalloc to kvmalloc
Am 01.08.24 um 12:45 schrieb Huan Yang: When PAGE_SIZE 4096, MAX_PAGE_ORDER 10, 64bit machine, page_alloc only support 4MB. If above this, trigger this warn and return NULL. udmabuf can change size limit, if change it to 3072(3GB), and then alloc 3GB udmabuf, will fail create. [ 4080.876581] [ cut here ] [ 4080.876843] WARNING: CPU: 3 PID: 2015 at mm/page_alloc.c:4556 __alloc_pages+0x2c8/0x350 [ 4080.878839] RIP: 0010:__alloc_pages+0x2c8/0x350 [ 4080.879470] Call Trace: [ 4080.879473] [ 4080.879473] ? __alloc_pages+0x2c8/0x350 [ 4080.879475] ? __warn.cold+0x8e/0xe8 [ 4080.880647] ? __alloc_pages+0x2c8/0x350 [ 4080.880909] ? report_bug+0xff/0x140 [ 4080.881175] ? handle_bug+0x3c/0x80 [ 4080.881556] ? exc_invalid_op+0x17/0x70 [ 4080.881559] ? asm_exc_invalid_op+0x1a/0x20 [ 4080.882077] ? udmabuf_create+0x131/0x400 Because MAX_PAGE_ORDER, kmalloc can max alloc 4096 * (1 << 10), 4MB memory, each array entry is pointer(8byte), so can save 524288 pages(2GB). Further more, costly order(order 3) may not be guaranteed that it can be applied for, due to fragmentation. This patch change udmabuf array use kvmalloc_array, this can fallback alloc into vmalloc, which can guarantee allocation for any size and does not affect the performance of kmalloc allocations. Signed-off-by: Huan Yang Acked-by: Christian König --- drivers/dma-buf/udmabuf.c | 26 +- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index d69aeada7367..a915714c5dce 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -83,7 +83,7 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map) dma_resv_assert_held(buf->resv); - pages = kmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL); + pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL); if (!pages) return -ENOMEM; @@ -91,7 +91,7 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map) pages[pg] = >folios[pg]->page; vaddr = vm_map_ram(pages, ubuf->pagecount, -1); - kfree(pages); + kvfree(pages); if (!vaddr) return -EINVAL; @@ -203,8 +203,8 @@ static void release_udmabuf(struct dma_buf *buf) put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL); unpin_all_folios(>unpin_list); - kfree(ubuf->offsets); - kfree(ubuf->folios); + kvfree(ubuf->offsets); + kvfree(ubuf->folios); kfree(ubuf); } @@ -330,14 +330,14 @@ static long udmabuf_create(struct miscdevice *device, if (!ubuf->pagecount) goto err; - ubuf->folios = kmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios), - GFP_KERNEL); + ubuf->folios = kvmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios), + GFP_KERNEL); if (!ubuf->folios) { ret = -ENOMEM; goto err; } - ubuf->offsets = kcalloc(ubuf->pagecount, sizeof(*ubuf->offsets), - GFP_KERNEL); + ubuf->offsets = + kvcalloc(ubuf->pagecount, sizeof(*ubuf->offsets), GFP_KERNEL); if (!ubuf->offsets) { ret = -ENOMEM; goto err; @@ -351,7 +351,7 @@ static long udmabuf_create(struct miscdevice *device, goto err; pgcnt = list[i].size >> PAGE_SHIFT; - folios = kmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL); + folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL); if (!folios) { ret = -ENOMEM; goto err; @@ -361,7 +361,7 @@ static long udmabuf_create(struct miscdevice *device, ret = memfd_pin_folios(memfd, list[i].offset, end, folios, pgcnt, ); if (ret <= 0) { - kfree(folios); + kvfree(folios); if (!ret) ret = -EINVAL; goto err; @@ -390,7 +390,7 @@ static long udmabuf_create(struct miscdevice *device, } } - kfree(folios); + kvfree(folios); fput(memfd); memfd = NULL; } @@ -406,8 +406,8 @@ static long udmabuf_create(struct miscdevice *device, if (memfd) fput(memfd); unpin_all_folios(>unpin_list); - kfree(ubuf->offsets); - kfree(ubuf->folios); + kvfree(ubuf->offsets); + kvfree(ubuf->folios); kfree(ubuf); return ret; }
RE: [PATCH v2 3/9] dt-bindings: display: renesas,rzg2l-du: Document RZ/G2UL DU bindings
Hi Laurent Pinchart, Thanks for the feedback. > -Original Message- > From: Laurent Pinchart > Sent: Wednesday, July 31, 2024 2:47 PM > Subject: Re: [PATCH v2 3/9] dt-bindings: display: renesas,rzg2l-du: Document > RZ/G2UL DU bindings > > Hi Biju, > > On Mon, Jul 29, 2024 at 09:05:59AM +, Biju Das wrote: > > On Saturday, July 27, 2024 1:50 AM, Laurent Pinchart wrote: > > > On Tue, Jul 09, 2024 at 02:51:41PM +0100, Biju Das wrote: > > > > Document DU found in RZ/G2UL SoC. The DU block is identical to > > > > RZ/G2L SoC, but has only DPI interface. > > > > > > > > While at it, add missing required property port@1 for RZ/G2L and > > > > RZ/V2L SoCs. Currently there is no user for the DPI interface and > > > > hence there won't be any ABI breakage for adding port@1 as > > > > required property for RZ/G2L and RZ/V2L SoCs. > > > > > > > > Signed-off-by: Biju Das > > > > Acked-by: Conor Dooley > > > > --- > > > > v1->v2: > > > > * Updated commit description related to non ABI breakage. > > > > * Added Ack from Conor. > > > > --- > > > > .../bindings/display/renesas,rzg2l-du.yaml| 32 +-- > > > > 1 file changed, 29 insertions(+), 3 deletions(-) > > > > > > > > diff --git > > > > a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml > > > > b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml > > > > index 08e5b9478051..c0fec282fa45 100644 > > > > --- > > > > a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml > > > > +++ b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.y > > > > +++ aml > > > > @@ -18,6 +18,7 @@ properties: > > > >compatible: > > > > oneOf: > > > >- enum: > > > > + - renesas,r9a07g043u-du # RZ/G2UL > > > >- renesas,r9a07g044-du # RZ/G2{L,LC} > > > >- items: > > > >- enum: > > > > @@ -60,9 +61,6 @@ properties: > > > > $ref: /schemas/graph.yaml#/properties/port > > > > unevaluatedProperties: false > > > > > > > > -required: > > > > - - port@0 > > > > - > > > > unevaluatedProperties: false > > > > > > > >renesas,vsps: > > > > @@ -88,6 +86,34 @@ required: > > > > > > > > additionalProperties: false > > > > > > > > +allOf: > > > > + - if: > > > > + properties: > > > > +compatible: > > > > + contains: > > > > +const: renesas,r9a07g043u-du > > > > +then: > > > > + properties: > > > > +ports: > > > > + properties: > > > > +port@0: false > > > > +port@1: > > > > + description: DPI > > > > + > > > > + required: > > > > +- port@1 > > > > > > Why do you use port@1 for the DPI output here, and not port@0 ? > > > > Currently the output is based on port number and port = 1 corresponds to > > DPI. See [1]. > > > > For consistency, I documented bindings for RZ/G2L family DU's similar to > > RZ/G2{H,M,N,E} DU [2]. > > > > So please let me know, are you ok with this? > > I won't insist strongly, but I don't think that using the port number to > indicate the output type is > the best idea. In the R-Car DU driver at least, that wouldn't have scaled. We > have multiple outputs of > the same type on some SoCs. Furthemore, the same DU hardware channel number > (i.e. > the offset of the registers specific to that channel in the DU register > space) is not the same across SoCs for the same output type. I recommend > numbering the ports based on > the hardware number of the output (the exact meaning of this is specific to > your device, I haven't > checked what it means for RZ/G2L), not on the output type. OK, will update the bindings to use port for RZ/G2UL and Ports for RZ/{G2L, V2L} as it has multiple DU outputs. From the driver will remove using port number to indicate the output type. - if (rcdu->info->routes[i].port == ep.port) { - output = i; + if (i == rcdu->info->routes[i].du_output) { + output = rcdu->info->routes[i].du_output; Cheers, Biju > > > [1] > > https://elixir.bootlin.com/linux/v6.10.2/source/drivers/gpu/drm/renesa > > s/rz-du/rzg2l_du_kms.c#L187 > > > > [2] > > https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tr > > ee/Documentation/devicetree/bindings/display/renesas,du.yaml?h=next-20 > > 240729#n546 > > > > > > +else: > > > > + properties: > > > > +ports: > > > > + properties: > > > > +port@0: > > > > + description: DSI > > > > +port@1: > > > > + description: DPI > > > > + > > > > + required: > > > > +- port@0 > > > > +- port@1 > > > > > > You're missing a blank line here. > > > > OK, will fix this' > > -- > Regards, > > Laurent Pinchart
Re: [RFC PATCH 3/3] drm/log: Introduce a new boot logger to draw the kmsg on the screen
On 2024-08-01, Jocelyn Falempe wrote: > * It uses a circular buffer so the console->write() callback is very >quick, and will never stall. > * Drawing is done asynchronously using a workqueue. For CON_NBCON, neither of the above points are necessary. You can draw directly from the write_thread() callback. See below: > +static bool drm_log_work_draw(void) > +{ > + unsigned int len; > + char buf[512]; > + > + len = drm_log_buf_read(buf, sizeof(buf)); > + if (len) > + drm_log_draw_all(buf, len); > + return len != 0; > +} For CON_NBCON, this is essentially your write_thread() callback: void drm_log_write_thread(struct console *con, struct nbcon_write_context *wctxt) { drm_log_draw_all(wctxt->outbuf, wctxt->len); } You cannot implement a write_atomic() callback because the console must be able to print directly in NMI context and must not defer. But write_atomic() is optional, so you should be fine there. Disclaimer: Only in PREEMPT_RT patchset at the moment. John Ogness
Re: [PATCH 1/5] udmabuf: cancel mmap page fault, direct map it
Am 01.08.24 um 12:45 schrieb Huan Yang: The current udmabuf mmap uses a page fault mechanism to populate the vma. However, the current udmabuf has already obtained and pinned the folio upon completion of the creation.This means that the physical memory has already been acquired, rather than being accessed dynamically. The current page fault method only saves some page table memory. As a result, the page fault mechanism has lost its purpose as a demanding page. Due to the fact that page fault requires trapping into kernel mode and filling in when accessing the corresponding virtual address in mmap, this means that user mode access to virtual addresses needs to trap into kernel mode. Therefore, when creating a large size udmabuf, this represents a considerable overhead. Therefore, the current patch removes the page fault method of mmap and instead fills it directly when mmap is triggered. Signed-off-by: Huan Yang --- drivers/dma-buf/udmabuf.c | 70 ++- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 047c3cd2ceff..d69aeada7367 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -38,36 +38,39 @@ struct udmabuf_folio { struct list_head list; }; -static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf) -{ - struct vm_area_struct *vma = vmf->vma; - struct udmabuf *ubuf = vma->vm_private_data; - pgoff_t pgoff = vmf->pgoff; - unsigned long pfn; - - if (pgoff >= ubuf->pagecount) - return VM_FAULT_SIGBUS; - - pfn = folio_pfn(ubuf->folios[pgoff]); - pfn += ubuf->offsets[pgoff] >> PAGE_SHIFT; - - return vmf_insert_pfn(vma, vmf->address, pfn); -} - -static const struct vm_operations_struct udmabuf_vm_ops = { - .fault = udmabuf_vm_fault, -}; +static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, +enum dma_data_direction direction); static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) { struct udmabuf *ubuf = buf->priv; + struct sg_table *table = ubuf->sg; + unsigned long addr = vma->vm_start; + struct sg_page_iter piter; + int ret; if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0) return -EINVAL; - vma->vm_ops = _vm_ops; - vma->vm_private_data = ubuf; - vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP); + if (!table) { + table = get_sg_table(NULL, buf, 0); + if (IS_ERR(table)) + return PTR_ERR(table); + ubuf->sg = table; + } + + for_each_sgtable_page(table, , vma->vm_pgoff) { That might not work correctly. We intentionally remove the pages from the sgtable when it is shared between devices. Additional to that the sgtable is *not* a page container, but rather a DMA address container. So that here is also a rather bad idea from the design side. Regards, Christian. + struct page *page = sg_page_iter_page(); + + ret = remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE, + vma->vm_page_prot); + if (ret) + return ret; + addr += PAGE_SIZE; + if (addr >= vma->vm_end) + return 0; + } + return 0; } @@ -126,6 +129,10 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, sg_set_folio(sgl, ubuf->folios[i], PAGE_SIZE, ubuf->offsets[i]); + // if dev is NULL, no need to sync. + if (!dev) + return sg; + ret = dma_map_sgtable(dev, sg, direction, 0); if (ret < 0) goto err_map; @@ -206,20 +213,21 @@ static int begin_cpu_udmabuf(struct dma_buf *buf, { struct udmabuf *ubuf = buf->priv; struct device *dev = ubuf->device->this_device; - int ret = 0; + struct sg_table *sg; - if (!ubuf->sg) { - ubuf->sg = get_sg_table(dev, buf, direction); - if (IS_ERR(ubuf->sg)) { - ret = PTR_ERR(ubuf->sg); - ubuf->sg = NULL; - } - } else { + if (ubuf->sg) { dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents, direction); + return 0; } - return ret; + sg = get_sg_table(dev, buf, direction); + if (IS_ERR(sg)) + return PTR_ERR(sg); + + ubuf->sg = sg; + + return 0; } static int end_cpu_udmabuf(struct dma_buf *buf,
[PATCH 5/5] udmabuf: remove folio pin list
Currently, udmabuf handles folio by creating an unpin list to record each folio obtained from the list and unpinning them when released. To maintain this approach, many data structures have been established. However, maintaining this type of data structure requires a significant amount of memory and traversing the list is a substantial overhead, which is not friendly to the CPU cache, TLB, and so on. Therefore, this patch removes the relationship between the folio and its offset in the linear address mapping. As an alternative, udmabuf only tracks all folio structures and splits them into individual pages when needed by traversing them in the required locations.(mmap/vmap, sg table.) So, udmabuf's folios_array only save the folio struct, add nr_folios to point how many folio saved in it. offset is removed, and add item's offset and size to replace, due to memfd create may have offset, we must set correctly page in folio. So, when setup sg_table, we must start correct offset in each item at begin, and then set each folio's page into sgtable. Both item's offset and size number just the create list number, so, memory size will not too large. By doing this, we can accept the overhead of the udmabuf_folio structure and the performance loss of traversing the list during unpinning. Signed-off-by: Huan Yang --- drivers/dma-buf/udmabuf.c | 149 +- 1 file changed, 66 insertions(+), 83 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 677ebb2d462f..1106e0b1e746 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -25,17 +25,19 @@ module_param(size_limit_mb, int, 0644); MODULE_PARM_DESC(size_limit_mb, "Max size of a dmabuf, in megabytes. Default is 64."); struct udmabuf { + // all page's count, pagecount * PAGE_SIZE is the udmabuf's size pgoff_t pagecount; + + // folios array only point to each folio, do not duplicate set. struct folio **folios; + // folios array's number + pgoff_t nr_folios; + struct sg_table *sg; struct miscdevice *device; - pgoff_t *offsets; - struct list_head unpin_list; -}; -struct udmabuf_folio { - struct folio *folio; - struct list_head list; + pgoff_t *item_offset; + size_t *item_size; }; static struct sg_table *udmabuf_get_sg_table(struct device *dev, @@ -118,7 +120,10 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, struct udmabuf *ubuf = buf->priv; struct sg_table *sg; struct scatterlist *sgl; - unsigned int i = 0; + struct folio *folio = NULL; + size_t fsize, foffset; + unsigned int i = 0, item_idx = 0, findex = 0; + size_t cur_size, item_size; int ret; sg = kzalloc(sizeof(*sg), GFP_KERNEL); @@ -129,9 +134,33 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, if (ret < 0) goto err_alloc; - for_each_sg(sg->sgl, sgl, ubuf->pagecount, i) - sg_set_folio(sgl, ubuf->folios[i], PAGE_SIZE, -ubuf->offsets[i]); + cur_size = 0; + item_size = ubuf->item_size[0]; + foffset = ubuf->item_offset[0]; + folio = ubuf->folios[0]; + fsize = folio_size(folio); + + for_each_sg(sg->sgl, sgl, ubuf->pagecount, i) { + sg_set_folio(sgl, folio, PAGE_SIZE, foffset); + foffset += PAGE_SIZE; + cur_size += PAGE_SIZE; + + // move to next folio. + if (foffset == fsize) { + ++findex; + folio = ubuf->folios[findex]; + fsize = folio_size(folio); + foffset = 0; + } + + // if reach to next item, must check the start offset. + if (cur_size == item_size) { + ++item_idx; + foffset = ubuf->item_offset[item_idx]; + item_size = ubuf->item_size[item_idx]; + cur_size = 0; + } + } // if dev is NULL, no need to sync. if (!dev) @@ -203,34 +232,6 @@ static void unmap_udmabuf(struct dma_buf_attachment *at, return put_sg_table(at->dev, sg, direction); } -static void unpin_all_folios(struct list_head *unpin_list) -{ - struct udmabuf_folio *ubuf_folio; - - while (!list_empty(unpin_list)) { - ubuf_folio = list_first_entry(unpin_list, - struct udmabuf_folio, list); - unpin_folio(ubuf_folio->folio); - - list_del(_folio->list); - kfree(ubuf_folio); - } -} - -static int add_to_unpin_list(struct list_head *unpin_list, -struct folio *folio) -{ - struct udmabuf_folio *ubuf_folio; - - ubuf_folio =
[PATCH 0/5] udmbuf bug fix and some improvements
This patchset attempts to fix some errors in udmabuf and remove the upin_list structure. Some of this fix just gather the patches which I upload before. Patch1 === Try to remove page fault mmap and direct map it. Due to current udmabuf has already obtained and pinned the folio upon completion of the creation.This means that the physical memory has already been acquired, rather than being accessed dynamically. The current page fault method only saves some page table memory. As a result, the page fault mechanism has lost its purpose as a demanding page. Due to the fact that page fault requires trapping into kernel mode and filling in when accessing the corresponding virtual address in mmap, this means that user mode access to virtual addresses needs to trap into kernel mode. Therefore, when creating a large size udmabuf, this represents a considerable overhead. Therefore, the current patch removes the page fault method of mmap and instead fills it directly when mmap is triggered. This is achieved by using the scatter-gather table to establish a linear relationship for the page. Calling remap_pfn_range does not cause the previously set VMA flags to become invalid. Patch2 === This is the same to patch: https://lore.kernel.org/all/20240725021349.580574-1-l...@vivo.com/ I just gather it to this patchset. Patch3 === The current implementation of udmabuf's vmap has issues. It does not correctly set each page of the folio to the page structure, so that when vmap is called, all pages are the head page of the folio. This implementation is not the same as this patch: https://lore.kernel.org/all/20240731090233.1343559-1-l...@vivo.com/ This reuse sgt table to map all page into vmalloc area. Patch4 === Wrap the repeated calls to get_sg_table, add a helper function to do it. Set to udmabuf->sg use cmpxchg, It should be able to prevent concurrent access situations. (I see mmap do not use lock) Patch5 === Attempt to remove unpin_list and other related data structures. In order to adapt to Folio, we established the unpin_list data structure to unpin all folios and maintain the page mapping relationship. However, this data structure requires 24 bytes for each page and has low traversal performance for the list. And maintaining the offset structure also consumes a portion of memory. This patch attempts to remove these data structures and modify the semantics of some existing data structures. udmabuf: folios -> folios array, which only contain's the folio, org contains duplicate. add item_offset -> base on create item count, record it's start offset in every memfd. add item_size -> base on create item count, record it's size in every memfd. add nr_folios -> folios array number So, when building the sg table, it is necessary to iterate in this way: if size cross item->size, take care of it's start offset in folio. if got folio, set each page into sgl until reach into folio size. This patch also remove single folios' create on each create item, use it be the ubuf->folios arrays' pointer, slide to fill the corresponding folio under the item into the array. After the modification, the various data structures in udmabuf have the following corresponding relationships: pagecount * PAGESIZE = sum(folios_size(folios[i])) i=0->nr_folios pagecount * PAGESIZE = sum(item_size[i]) i=0, item_count (do not record) item_offset use to record each memfd offset if exist, else 0. Huan Yang (5): udmabuf: cancel mmap page fault, direct map it udmabuf: change folios array from kmalloc to kvmalloc udmabuf: fix vmap_udmabuf error page set udmabuf: add get_sg_table helper function udmabuf: remove folio pin list drivers/dma-buf/udmabuf.c | 270 +- 1 file changed, 148 insertions(+), 122 deletions(-) base-commit: cd19ac2f903276b820f5d0d89de0c896c27036ed -- 2.45.2
[PATCH 3/5] udmabuf: fix vmap_udmabuf error page set
Currently vmap_udmabuf set page's array by each folio. But, ubuf->folios is only contain's the folio's head page. That mean we repeatedly mapped the folio head page to the vmalloc area. This patch fix it, set each folio's page correct, so that pages array contains right page, and then map into vmalloc area Signed-off-by: Huan Yang --- drivers/dma-buf/udmabuf.c | 17 + 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index a915714c5dce..7ed532342d7f 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -77,18 +77,27 @@ static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map) { struct udmabuf *ubuf = buf->priv; - struct page **pages; + struct page **pages, **tmp; + struct sg_table *sg = ubuf->sg; + struct sg_page_iter piter; void *vaddr; - pgoff_t pg; dma_resv_assert_held(buf->resv); + if (!sg) { + sg = get_sg_table(NULL, buf, 0); + if (IS_ERR(sg)) + return PTR_ERR(sg); + ubuf->sg = sg; + } + pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL); if (!pages) return -ENOMEM; + tmp = pages; - for (pg = 0; pg < ubuf->pagecount; pg++) - pages[pg] = >folios[pg]->page; + for_each_sgtable_page(sg, , 0) + *tmp++ = sg_page_iter_page(); vaddr = vm_map_ram(pages, ubuf->pagecount, -1); kvfree(pages); -- 2.45.2
[PATCH 1/5] udmabuf: cancel mmap page fault, direct map it
The current udmabuf mmap uses a page fault mechanism to populate the vma. However, the current udmabuf has already obtained and pinned the folio upon completion of the creation.This means that the physical memory has already been acquired, rather than being accessed dynamically. The current page fault method only saves some page table memory. As a result, the page fault mechanism has lost its purpose as a demanding page. Due to the fact that page fault requires trapping into kernel mode and filling in when accessing the corresponding virtual address in mmap, this means that user mode access to virtual addresses needs to trap into kernel mode. Therefore, when creating a large size udmabuf, this represents a considerable overhead. Therefore, the current patch removes the page fault method of mmap and instead fills it directly when mmap is triggered. Signed-off-by: Huan Yang --- drivers/dma-buf/udmabuf.c | 70 ++- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 047c3cd2ceff..d69aeada7367 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -38,36 +38,39 @@ struct udmabuf_folio { struct list_head list; }; -static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf) -{ - struct vm_area_struct *vma = vmf->vma; - struct udmabuf *ubuf = vma->vm_private_data; - pgoff_t pgoff = vmf->pgoff; - unsigned long pfn; - - if (pgoff >= ubuf->pagecount) - return VM_FAULT_SIGBUS; - - pfn = folio_pfn(ubuf->folios[pgoff]); - pfn += ubuf->offsets[pgoff] >> PAGE_SHIFT; - - return vmf_insert_pfn(vma, vmf->address, pfn); -} - -static const struct vm_operations_struct udmabuf_vm_ops = { - .fault = udmabuf_vm_fault, -}; +static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, +enum dma_data_direction direction); static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) { struct udmabuf *ubuf = buf->priv; + struct sg_table *table = ubuf->sg; + unsigned long addr = vma->vm_start; + struct sg_page_iter piter; + int ret; if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0) return -EINVAL; - vma->vm_ops = _vm_ops; - vma->vm_private_data = ubuf; - vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP); + if (!table) { + table = get_sg_table(NULL, buf, 0); + if (IS_ERR(table)) + return PTR_ERR(table); + ubuf->sg = table; + } + + for_each_sgtable_page(table, , vma->vm_pgoff) { + struct page *page = sg_page_iter_page(); + + ret = remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE, + vma->vm_page_prot); + if (ret) + return ret; + addr += PAGE_SIZE; + if (addr >= vma->vm_end) + return 0; + } + return 0; } @@ -126,6 +129,10 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, sg_set_folio(sgl, ubuf->folios[i], PAGE_SIZE, ubuf->offsets[i]); + // if dev is NULL, no need to sync. + if (!dev) + return sg; + ret = dma_map_sgtable(dev, sg, direction, 0); if (ret < 0) goto err_map; @@ -206,20 +213,21 @@ static int begin_cpu_udmabuf(struct dma_buf *buf, { struct udmabuf *ubuf = buf->priv; struct device *dev = ubuf->device->this_device; - int ret = 0; + struct sg_table *sg; - if (!ubuf->sg) { - ubuf->sg = get_sg_table(dev, buf, direction); - if (IS_ERR(ubuf->sg)) { - ret = PTR_ERR(ubuf->sg); - ubuf->sg = NULL; - } - } else { + if (ubuf->sg) { dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents, direction); + return 0; } - return ret; + sg = get_sg_table(dev, buf, direction); + if (IS_ERR(sg)) + return PTR_ERR(sg); + + ubuf->sg = sg; + + return 0; } static int end_cpu_udmabuf(struct dma_buf *buf, -- 2.45.2
[PATCH 2/5] udmabuf: change folios array from kmalloc to kvmalloc
When PAGE_SIZE 4096, MAX_PAGE_ORDER 10, 64bit machine, page_alloc only support 4MB. If above this, trigger this warn and return NULL. udmabuf can change size limit, if change it to 3072(3GB), and then alloc 3GB udmabuf, will fail create. [ 4080.876581] [ cut here ] [ 4080.876843] WARNING: CPU: 3 PID: 2015 at mm/page_alloc.c:4556 __alloc_pages+0x2c8/0x350 [ 4080.878839] RIP: 0010:__alloc_pages+0x2c8/0x350 [ 4080.879470] Call Trace: [ 4080.879473] [ 4080.879473] ? __alloc_pages+0x2c8/0x350 [ 4080.879475] ? __warn.cold+0x8e/0xe8 [ 4080.880647] ? __alloc_pages+0x2c8/0x350 [ 4080.880909] ? report_bug+0xff/0x140 [ 4080.881175] ? handle_bug+0x3c/0x80 [ 4080.881556] ? exc_invalid_op+0x17/0x70 [ 4080.881559] ? asm_exc_invalid_op+0x1a/0x20 [ 4080.882077] ? udmabuf_create+0x131/0x400 Because MAX_PAGE_ORDER, kmalloc can max alloc 4096 * (1 << 10), 4MB memory, each array entry is pointer(8byte), so can save 524288 pages(2GB). Further more, costly order(order 3) may not be guaranteed that it can be applied for, due to fragmentation. This patch change udmabuf array use kvmalloc_array, this can fallback alloc into vmalloc, which can guarantee allocation for any size and does not affect the performance of kmalloc allocations. Signed-off-by: Huan Yang --- drivers/dma-buf/udmabuf.c | 26 +- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index d69aeada7367..a915714c5dce 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -83,7 +83,7 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map) dma_resv_assert_held(buf->resv); - pages = kmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL); + pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL); if (!pages) return -ENOMEM; @@ -91,7 +91,7 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map) pages[pg] = >folios[pg]->page; vaddr = vm_map_ram(pages, ubuf->pagecount, -1); - kfree(pages); + kvfree(pages); if (!vaddr) return -EINVAL; @@ -203,8 +203,8 @@ static void release_udmabuf(struct dma_buf *buf) put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL); unpin_all_folios(>unpin_list); - kfree(ubuf->offsets); - kfree(ubuf->folios); + kvfree(ubuf->offsets); + kvfree(ubuf->folios); kfree(ubuf); } @@ -330,14 +330,14 @@ static long udmabuf_create(struct miscdevice *device, if (!ubuf->pagecount) goto err; - ubuf->folios = kmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios), - GFP_KERNEL); + ubuf->folios = kvmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios), + GFP_KERNEL); if (!ubuf->folios) { ret = -ENOMEM; goto err; } - ubuf->offsets = kcalloc(ubuf->pagecount, sizeof(*ubuf->offsets), - GFP_KERNEL); + ubuf->offsets = + kvcalloc(ubuf->pagecount, sizeof(*ubuf->offsets), GFP_KERNEL); if (!ubuf->offsets) { ret = -ENOMEM; goto err; @@ -351,7 +351,7 @@ static long udmabuf_create(struct miscdevice *device, goto err; pgcnt = list[i].size >> PAGE_SHIFT; - folios = kmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL); + folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL); if (!folios) { ret = -ENOMEM; goto err; @@ -361,7 +361,7 @@ static long udmabuf_create(struct miscdevice *device, ret = memfd_pin_folios(memfd, list[i].offset, end, folios, pgcnt, ); if (ret <= 0) { - kfree(folios); + kvfree(folios); if (!ret) ret = -EINVAL; goto err; @@ -390,7 +390,7 @@ static long udmabuf_create(struct miscdevice *device, } } - kfree(folios); + kvfree(folios); fput(memfd); memfd = NULL; } @@ -406,8 +406,8 @@ static long udmabuf_create(struct miscdevice *device, if (memfd) fput(memfd); unpin_all_folios(>unpin_list); - kfree(ubuf->offsets); - kfree(ubuf->folios); + kvfree(ubuf->offsets); + kvfree(ubuf->folios); kfree(ubuf); return ret; } -- 2.45.2
[PATCH 4/5] udmabuf: add get_sg_table helper function
Currently, there are three duplicate pieces of code that retrieve sg_table and update uduf->sg. Since the sgt is used to populate the page in both mmap and vmap.It is necessary to ensure that ubuf->sg is set correctly. This patch add a helper function, if ubuf->sg exist, just return it. Or else, try alloc a new sgt, and cmpxchg to set it. When the swap fails, it means that another process has set sg correctly. Therefore, we reuse the new sg. If trigger by device, need invoke map to sync it. Signed-off-by: Huan Yang --- drivers/dma-buf/udmabuf.c | 60 --- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 7ed532342d7f..677ebb2d462f 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -38,8 +38,9 @@ struct udmabuf_folio { struct list_head list; }; -static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, -enum dma_data_direction direction); +static struct sg_table *udmabuf_get_sg_table(struct device *dev, +struct dma_buf *buf, +enum dma_data_direction direction); static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) { @@ -52,12 +53,9 @@ static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0) return -EINVAL; - if (!table) { - table = get_sg_table(NULL, buf, 0); - if (IS_ERR(table)) - return PTR_ERR(table); - ubuf->sg = table; - } + table = udmabuf_get_sg_table(NULL, buf, 0); + if (IS_ERR(table)) + return PTR_ERR(table); for_each_sgtable_page(table, , vma->vm_pgoff) { struct page *page = sg_page_iter_page(); @@ -84,12 +82,9 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map) dma_resv_assert_held(buf->resv); - if (!sg) { - sg = get_sg_table(NULL, buf, 0); - if (IS_ERR(sg)) - return PTR_ERR(sg); - ubuf->sg = sg; - } + sg = udmabuf_get_sg_table(NULL, buf, 0); + if (IS_ERR(sg)) + return PTR_ERR(sg); pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL); if (!pages) @@ -154,6 +149,39 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, return ERR_PTR(ret); } +static struct sg_table *udmabuf_get_sg_table(struct device *dev, +struct dma_buf *buf, +enum dma_data_direction direction) +{ + struct udmabuf *ubuf = buf->priv; + struct sg_table *sg = READ_ONCE(ubuf->sg); + int ret = 0; + + if (sg) + return sg; + + sg = get_sg_table(dev, buf, direction); + if (IS_ERR(sg)) + return sg; + + // Success update ubuf's sg, just return. + if (!cmpxchg(>sg, NULL, sg)) + return sg; + + // use the new sg table. + sg_free_table(sg); + kfree(sg); + sg = READ_ONCE(ubuf->sg); + + if (dev) + ret = dma_map_sgtable(dev, sg, direction, 0); + + if (ret < 0) + return ERR_PTR(ret); + + return sg; +} + static void put_sg_table(struct device *dev, struct sg_table *sg, enum dma_data_direction direction) { @@ -230,12 +258,10 @@ static int begin_cpu_udmabuf(struct dma_buf *buf, return 0; } - sg = get_sg_table(dev, buf, direction); + sg = udmabuf_get_sg_table(dev, buf, direction); if (IS_ERR(sg)) return PTR_ERR(sg); - ubuf->sg = sg; - return 0; } -- 2.45.2
Re: [RFC PATCH 0/3] drm/log: Introduce a new boot logger to draw the kmsg on the screen
On 2024-08-01, Jocelyn Falempe wrote: > * I tried to use the new nbcon interface, but didn't get any message > from the write_atomic() callback, but the goal is to use that when > it's ready. Be aware that the write_atomic() callback _must_ also print from NMI context. write_thread() may be the callback you are interested instead. Note that for CON_NBCON, write_atomic() is optional, write_thread() is mandatory. Disclaimer: All of this currently only available in the PREEMPT_RT patchset. So until it hits mainline, semantics may yet change. John Ogness
Re: [PATCH] backlight: pwm_bl: print errno for probe errors
Hello Martin, On Thu, Aug 01, 2024 at 09:52:01AM +, Kepplinger-Novakovic Martin wrote: > Am Donnerstag, dem 01.08.2024 um 11:26 +0200 schrieb Uwe Kleine-König: > > On Thu, Aug 01, 2024 at 11:12:55AM +0200, Martin Kepplinger-Novaković > > wrote: > > > diff --git a/drivers/video/backlight/pwm_bl.c > > > b/drivers/video/backlight/pwm_bl.c > > > index f1005bd0c41e3..cc7e7af71891f 100644 > > > --- a/drivers/video/backlight/pwm_bl.c > > > +++ b/drivers/video/backlight/pwm_bl.c > > > @@ -502,7 +502,8 @@ static int pwm_backlight_probe(struct > > > platform_device *pdev) > > > GPIOD_ASIS); > > > if (IS_ERR(pb->enable_gpio)) { > > > ret = dev_err_probe(>dev, PTR_ERR(pb- > > > >enable_gpio), > > > - "failed to acquire enable > > > GPIO\n"); > > > + "failed to acquire enable GPIO: > > > %ld\n", > > > + PTR_ERR(pb->enable_gpio)); > > > > AFAIK dev_err_probe already emits the error code passed as 2nd > > parameter. So I wonder about this patch's benefit. > > > > It does. Other messages only take the deferred_probe_reason without the > error code. It's actually fine if users properly enable debugging after > seeing an error and then this change is not needed :) I'm unsure what you intend to say here. Do you agree that this patch doesn't need to be applied as it doesn't add any information to the emitted messages? Or do you think there is a value because "users don't need to enable debugging" then. In the latter case I don't see where users would see "failed to acquire enable GPIO" before, but not the value of the error code. Best regards Uwe signature.asc Description: PGP signature
[RFC PATCH 3/3] drm/log: Introduce a new boot logger to draw the kmsg on the screen
drm_log is a simple logger that uses the drm_client API to print the kmsg boot log on the screen. This is not a full replacement to fbcon, as it will only print the kmsg. It will never handle user input, or a terminal because this is better done in userspace. Design decisions: * It uses the drm_client API, so it should work on all drm drivers from the start. * It doesn't scroll the message, that way it doesn't need to redraw the whole screen for each new message. It also means it doesn't have to keep drawn messages in memory, to redraw them when scrolling. * It uses a circular buffer so the console->write() callback is very quick, and will never stall. * Drawing is done asynchronously using a workqueue. * drm_log can only be built-in (and drm must be built-in too). The reason is that, if you build it as a module, then a userspace application will be more appropriate than this module. Signed-off-by: Jocelyn Falempe --- drivers/gpu/drm/Kconfig | 11 + drivers/gpu/drm/Makefile | 2 + drivers/gpu/drm/drm_drv.c | 2 + drivers/gpu/drm/drm_log.c | 477 ++ drivers/gpu/drm/drm_log.h | 8 + 5 files changed, 500 insertions(+) create mode 100644 drivers/gpu/drm/drm_log.c create mode 100644 drivers/gpu/drm/drm_log.h diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index c39bf143d705..b98e8b1755a9 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -185,6 +185,17 @@ config DRM_PANIC_SCREEN_QR_VERSION Smaller QR code are easier to read, but will contain less debugging data. Default is 40. +config DRM_LOG + bool "Print the kernel boot message on the screen" + depends on DRM=y + depends on !FRAMEBUFFER_CONSOLE + select DRM_DRAW + help + This enable a drm logger, that will print the kernel messages to the + screen until the userspace is ready to take over. + It only makes sense to have it built-in, because otherwise it would + be loaded after userspace. + config DRM_DEBUG_DP_MST_TOPOLOGY_REFS bool "Enable refcount backtrace history in the DP MST helpers" depends on STACKTRACE_SUPPORT diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 632247cddac9..ac06b6f2aa10 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -149,6 +149,8 @@ drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o +obj-$(CONFIG_DRM_LOG) += drm_log.o + # # Drivers and the rest # diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 27007b53a8c8..471960a6c0c9 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -48,6 +48,7 @@ #include #include "drm_crtc_internal.h" +#include "drm_log.h" #include "drm_internal.h" MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl"); @@ -946,6 +947,7 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) goto err_unload; } drm_panic_register(dev); + drm_log_register(dev); DRM_INFO("Initialized %s %d.%d.%d for %s on minor %d\n", driver->name, driver->major, driver->minor, diff --git a/drivers/gpu/drm/drm_log.c b/drivers/gpu/drm/drm_log.c new file mode 100644 index ..a5f1502e3dc3 --- /dev/null +++ b/drivers/gpu/drm/drm_log.c @@ -0,0 +1,477 @@ +// SPDX-License-Identifier: GPL-2.0 or MIT +/* + * Copyright (c) 2024 Red Hat. + * Author: Jocelyn Falempe + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "drm_draw.h" +#include "drm_log.h" + +MODULE_AUTHOR("Jocelyn Falempe"); +MODULE_DESCRIPTION("DRM boot logger"); +MODULE_LICENSE("GPL"); + +/** + * DOC: overview + * + * This is a simple graphic logger, to print the kernel message on screen, until + * a userspace application is able to take over. + * It is only for debugging purpose. + */ + +struct drm_log_scanout { + struct drm_client_buffer *buffer; + const struct font_desc *font; + struct iosys_map map; + u32 rows; + u32 columns; + u32 line; + u32 format; + u32 px_width; + u32 front_color; +}; + +struct drm_log_client { + struct list_head head; + struct drm_client_dev client; + u32 n_scanout; + struct drm_log_scanout *scanout; +}; + +static LIST_HEAD(drm_log_clients); +static DEFINE_MUTEX(drm_log_lock); + +/* + * A circular buffer, with the last kmsg logs to print. + * 8K is more than what can be drawn on most monitors. + */ +#define CIRC_BUF_SIZE (1 << 13) +#define CIRC_BUF_MASK (CIRC_BUF_SIZE - 1) +struct circ_buf drm_log_buf; +static DEFINE_SPINLOCK(drm_log_writer_lock); +static DEFINE_SPINLOCK(drm_log_reader_lock); + +/* + * Circular buffer functions +
[RFC PATCH 2/3] drm/panic: Move drawing functions to drm_draw
Move the color conversions, blit and fill functions to drm_draw.c, so that they can be re-used by drm_log. drm_draw is internal to the drm subsystem, and shouldn't be used by gpu drivers. Signed-off-by: Jocelyn Falempe --- drivers/gpu/drm/Kconfig | 5 + drivers/gpu/drm/Makefile| 1 + drivers/gpu/drm/drm_draw.c | 216 +++ drivers/gpu/drm/drm_draw.h | 56 drivers/gpu/drm/drm_panic.c | 247 5 files changed, 301 insertions(+), 224 deletions(-) create mode 100644 drivers/gpu/drm/drm_draw.c create mode 100644 drivers/gpu/drm/drm_draw.h diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index b3ab3ace7f8e..c39bf143d705 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -105,10 +105,15 @@ config DRM_KMS_HELPER help CRTC helpers for KMS drivers. +config DRM_DRAW + bool + depends on DRM + config DRM_PANIC bool "Display a user-friendly message when a kernel panic occurs" depends on DRM select FONT_SUPPORT + select DRM_DRAW help Enable a drm panic handler, which will display a user-friendly message when a kernel panic occurs. It's useful when using a user-space diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index c62339b89d46..632247cddac9 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -89,6 +89,7 @@ drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \ drm_privacy_screen_x86.o drm-$(CONFIG_DRM_ACCEL) += ../../accel/drm_accel.o drm-$(CONFIG_DRM_PANIC) += drm_panic.o +drm-$(CONFIG_DRM_DRAW) += drm_draw.o drm-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) += drm_panic_qr.o obj-$(CONFIG_DRM) += drm.o diff --git a/drivers/gpu/drm/drm_draw.c b/drivers/gpu/drm/drm_draw.c new file mode 100644 index ..79fe6577d3aa --- /dev/null +++ b/drivers/gpu/drm/drm_draw.c @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: GPL-2.0 or MIT +/* + * Copyright (c) 2023 Red Hat. + * Author: Jocelyn Falempe + */ + +#include +#include +#include + +#include + +#include "drm_draw.h" + +/* + * Conversions from xrgb + */ + +static u16 convert_xrgb_to_rgb565(u32 pix) +{ + return ((pix & 0x00F8) >> 8) | + ((pix & 0xFC00) >> 5) | + ((pix & 0x00F8) >> 3); +} + +static u16 convert_xrgb_to_rgba5551(u32 pix) +{ + return ((pix & 0x00f8) >> 8) | + ((pix & 0xf800) >> 5) | + ((pix & 0x00f8) >> 2) | + BIT(0); /* set alpha bit */ +} + +static u16 convert_xrgb_to_xrgb1555(u32 pix) +{ + return ((pix & 0x00f8) >> 9) | + ((pix & 0xf800) >> 6) | + ((pix & 0x00f8) >> 3); +} + +static u16 convert_xrgb_to_argb1555(u32 pix) +{ + return BIT(15) | /* set alpha bit */ + ((pix & 0x00f8) >> 9) | + ((pix & 0xf800) >> 6) | + ((pix & 0x00f8) >> 3); +} + +static u32 convert_xrgb_to_argb(u32 pix) +{ + return pix | GENMASK(31, 24); /* fill alpha bits */ +} + +static u32 convert_xrgb_to_xbgr(u32 pix) +{ + return ((pix & 0x00ff) >> 16) << 0 | + ((pix & 0xff00) >> 8) << 8 | + ((pix & 0x00ff) >> 0) << 16 | + ((pix & 0xff00) >> 24) << 24; +} + +static u32 convert_xrgb_to_abgr(u32 pix) +{ + return ((pix & 0x00ff) >> 16) << 0 | + ((pix & 0xff00) >> 8) << 8 | + ((pix & 0x00ff) >> 0) << 16 | + GENMASK(31, 24); /* fill alpha bits */ +} + +static u32 convert_xrgb_to_xrgb2101010(u32 pix) +{ + pix = ((pix & 0x00FF) << 2) | + ((pix & 0xFF00) << 4) | + ((pix & 0x00FF) << 6); + return pix | ((pix >> 8) & 0x00300C03); +} + +static u32 convert_xrgb_to_argb2101010(u32 pix) +{ + pix = ((pix & 0x00FF) << 2) | + ((pix & 0xFF00) << 4) | + ((pix & 0x00FF) << 6); + return GENMASK(31, 30) /* set alpha bits */ | pix | ((pix >> 8) & 0x00300C03); +} + +/** + * drm_draw_color_from_xrgb - convert one pixel from xrgb to the desired format + * @color: input color, in xrgb format + * @format: output format + * + * Returns: + * Color in the format specified, casted to u32. + * Or 0 if the format is not supported. + */ +u32 drm_draw_color_from_xrgb(u32 color, u32 format) +{ + switch (format) { + case DRM_FORMAT_RGB565: + return convert_xrgb_to_rgb565(color); + case DRM_FORMAT_RGBA5551: + return convert_xrgb_to_rgba5551(color); + case DRM_FORMAT_XRGB1555: + return convert_xrgb_to_xrgb1555(color); + case DRM_FORMAT_ARGB1555: + return convert_xrgb_to_argb1555(color); + case DRM_FORMAT_RGB888: + case DRM_FORMAT_XRGB: + return color; +
[RFC PATCH 1/3] [NOT FOR REVIEW] drm/panic: Squash of pending series
This is a squashed patch of: https://patchwork.freedesktop.org/series/136377/ https://patchwork.freedesktop.org/series/135944/ This is to avoid to rebase when they are merged. Signed-off-by: Jocelyn Falempe --- drivers/gpu/drm/Kconfig | 31 + drivers/gpu/drm/Makefile|1 + drivers/gpu/drm/drm_crtc_internal.h |8 + drivers/gpu/drm/drm_drv.c |3 + drivers/gpu/drm/drm_panic.c | 367 -- drivers/gpu/drm/drm_panic_qr.rs | 1003 +++ include/drm/drm_panic.h | 21 +- include/drm/drm_rect.h | 15 + 8 files changed, 1389 insertions(+), 60 deletions(-) create mode 100644 drivers/gpu/drm/drm_panic_qr.rs diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index b6ea88d228e1..b3ab3ace7f8e 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -149,6 +149,37 @@ config DRM_PANIC_SCREEN or by writing to /sys/module/drm/parameters/panic_screen sysfs entry Default is "user" +config DRM_PANIC_SCREEN_QR_CODE + bool "Add a panic screen with a QR code" + depends on DRM_PANIC && RUST + help + This option adds a QR code generator, and a panic screen with a QR + code. The QR code will contain the last lines of kmsg and other debug + information. This should be easier for the user to report a kernel + panic, with all debug information available. + To use this panic screen, also set DRM_PANIC_SCREEN to "qr_code" + +config DRM_PANIC_SCREEN_QR_CODE_URL + string "Base URL of the QR code in the panic screen" + depends on DRM_PANIC_SCREEN_QR_CODE + help + This option sets the base URL to report the kernel panic. If it's set + the QR code will contain the URL and the kmsg compressed with zlib as + a URL parameter. If it's empty, the QR code will contain the kmsg as + uncompressed text only. + There is a demo code in javascript, to decode and uncompress the kmsg + data from the URL parameter at https://github.com/kdj0c/panic_report + +config DRM_PANIC_SCREEN_QR_VERSION + int "Maximum version (size) of the QR code." + depends on DRM_PANIC_SCREEN_QR_CODE + default 40 + help + This option limits the version (or size) of the QR code. QR code + version ranges from Version 1 (21x21) to Version 40 (177x177). + Smaller QR code are easier to read, but will contain less debugging + data. Default is 40. + config DRM_DEBUG_DP_MST_TOPOLOGY_REFS bool "Enable refcount backtrace history in the DP MST helpers" depends on STACKTRACE_SUPPORT diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 68cc9258ffc4..c62339b89d46 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -89,6 +89,7 @@ drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \ drm_privacy_screen_x86.o drm-$(CONFIG_DRM_ACCEL) += ../../accel/drm_accel.o drm-$(CONFIG_DRM_PANIC) += drm_panic.o +drm-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) += drm_panic_qr.o obj-$(CONFIG_DRM) += drm.o obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index 061436361998..89706aa8232f 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -318,8 +318,16 @@ drm_edid_load_firmware(struct drm_connector *connector) /* drm_panic.c */ #ifdef CONFIG_DRM_PANIC bool drm_panic_is_enabled(struct drm_device *dev); +void drm_panic_register(struct drm_device *dev); +void drm_panic_unregister(struct drm_device *dev); +void drm_panic_init(void); +void drm_panic_exit(void); #else static inline bool drm_panic_is_enabled(struct drm_device *dev) { return false; } +static inline void drm_panic_register(struct drm_device *dev) {} +static inline void drm_panic_unregister(struct drm_device *dev) {} +static inline void drm_panic_init(void) {} +static inline void drm_panic_exit(void) {} #endif #endif /* __DRM_CRTC_INTERNAL_H__ */ diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 93543071a500..27007b53a8c8 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -1067,6 +1067,7 @@ static const struct file_operations drm_stub_fops = { static void drm_core_exit(void) { drm_privacy_screen_lookup_exit(); + drm_panic_exit(); accel_core_exit(); unregister_chrdev(DRM_MAJOR, "drm"); debugfs_remove(drm_debugfs_root); @@ -1099,6 +1100,8 @@ static int __init drm_core_init(void) if (ret < 0) goto error; + drm_panic_init(); + drm_privacy_screen_lookup_init(); drm_core_init_complete = true; diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c index 072752b658f0..ec708ff9c40c 100644 --- a/drivers/gpu/drm/drm_panic.c +++ b/drivers/gpu/drm/drm_panic.c @@
[RFC PATCH 0/3] drm/log: Introduce a new boot logger to draw the kmsg on the screen
drm_log is a simple logger that uses the drm_client API to print the kmsg boot log on the screen. This is not a full replacement to fbcon, as it will only print the kmsg. It will never handle user input, or a terminal because this is better done in userspace. If you're curious on how it looks like, I've put a small demo here: https://people.redhat.com/jfalempe/drm_log/drm_log_draft_preview.webm Design decisions: * It uses the drm_client API, so it should work on all drm drivers from the start. * It doesn't scroll the message, that way it doesn't need to redraw the whole screen for each new message. It also means it doesn't have to keep drawn messages in memory, to redraw them when scrolling. * It uses a circular buffer so the console->write() callback is very quick, and will never stall. * Drawing is done asynchronously using a workqueue. * drm_log can only be built-in (and drm must be built-in too). The reason is that, if you build it as a module, then a userspace application will be more appropriate than this module. TODO items: * It currently only handles the first drm_client hotplug event, I need a bit more time to fix that. * I didn't find a way to know when drm_log loses focus, I would like to unregister it, so it won't waste CPU cycles in the background. * I copied the drm_client API usage from drm_fbdev_shmem, so there might be some adjustment to work on DMA GPU (I didn't try yet). * Flicker-free boot: I don't want drm_log to introduce new modeset during the boot, so it may need some adjustment. * I tried to use the new nbcon interface, but didn't get any message from the write_atomic() callback, but the goal is to use that when it's ready. * Add color support, to make timestamp, or error message, in different color for better visibility. * If built with VT_CONSOLE=n and FRAMEBUFFER_CONSOLE=y, fbcon is taking the focus, and you won't see the drm_log. It would be nice to have drm_log for boot logs, and still use fbcon for terminal, when userspace is started. The first patch is not for review/merge, it's a squash of my pending drm_panic series: https://patchwork.freedesktop.org/series/136377/ https://patchwork.freedesktop.org/series/135944/ The second patch, moves the drawing function from drm_panic.c, to drm_draw.c, so they can be re-used by drm_log. The third patch is the actual drm_log implementation. I want to get some feedbacks before spending more time on this, and make sure I'm heading in the right direction. Thanks and best regards, -- Jocelyn Jocelyn Falempe (3): [NOT FOR REVIEW] drm/panic: Squash of pending series drm/panic: Move drawing functions to drm_draw drm/log: Introduce a new boot logger to draw the kmsg on the screen drivers/gpu/drm/Kconfig | 47 ++ drivers/gpu/drm/Makefile|4 + drivers/gpu/drm/drm_crtc_internal.h |8 + drivers/gpu/drm/drm_draw.c | 216 ++ drivers/gpu/drm/drm_draw.h | 56 ++ drivers/gpu/drm/drm_drv.c |5 + drivers/gpu/drm/drm_log.c | 477 + drivers/gpu/drm/drm_log.h |8 + drivers/gpu/drm/drm_panic.c | 596 +--- drivers/gpu/drm/drm_panic_qr.rs | 1003 +++ include/drm/drm_panic.h | 21 +- include/drm/drm_rect.h | 15 + 12 files changed, 2181 insertions(+), 275 deletions(-) create mode 100644 drivers/gpu/drm/drm_draw.c create mode 100644 drivers/gpu/drm/drm_draw.h create mode 100644 drivers/gpu/drm/drm_log.c create mode 100644 drivers/gpu/drm/drm_log.h create mode 100644 drivers/gpu/drm/drm_panic_qr.rs base-commit: bb99c51bdaa846bddb85a1e7acca3a3aa5e9f082 -- 2.45.2
Re: [PATCH v2 1/3] dt-bindings: display: rockchip: Add schema for RK3588 HDMI TX Controller
On 8/1/24 6:37 AM, Rob Herring (Arm) wrote: > > On Thu, 01 Aug 2024 05:25:52 +0300, Cristian Ciocaltea wrote: >> Rockchip RK3588 SoC integrates the Synopsys DesignWare HDMI 2.1 >> Quad-Pixel (QP) TX controller IP. >> >> Since this is a new IP block, quite different from those used in the >> previous generations of Rockchip SoCs, add a dedicated binding file. >> >> Signed-off-by: Cristian Ciocaltea >> --- >> .../display/rockchip/rockchip,dw-hdmi-qp.yaml | 188 >> + >> 1 file changed, 188 insertions(+) >> > > My bot found errors running 'make dt_binding_check' on your patch: This is because the referenced synopsys,dw-hdmi-qp.yaml is provided by a separate patchset: https://lore.kernel.org/lkml/20240801-dw-hdmi-qp-tx-v1-1-148f542de...@collabora.com/ > yamllint warnings/errors: > > dtschema/dtc warnings/errors: > /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi-qp.example.dtb: > hdmi@fde8: False schema does not allow {'compatible': > ['rockchip,rk3588-dw-hdmi-qp'], 'reg': [[0, 425984, 0, 131072]], > 'clocks': [[4294967295, 528], [4294967295, 529], [4294967295, 530], > [4294967295, 564], [4294967295, 594], [4294967295, 717]], 'clock-names': > ['pclk', 'earc', 'ref', 'aud', 'hdp', 'hclk_vo1'], 'interrupts': [[0, 169, 4, > 0], [0, 170, 4, 0], [0, 171, 4, 0], [0, 172, 4, 0], [0, 360, 4, 0]], > 'interrupt-names': ['avp', 'cec', 'earc', 'main', 'hpd'], 'phys': > [[4294967295]], 'phy-names': ['hdmi'], 'power-domains': [[4294967295, 26]], > 'resets': [[4294967295, 462], [4294967295, 560]], 'reset-names': ['ref', > 'hdp'], 'rockchip,grf': [[4294967295]], 'rockchip,vo1_grf': [[4294967295]], > '#sound-dai-cells': 0, 'ports': {'#address-cells': 1, '#size-cells': 0, > 'port@0': {'reg': [[0]], 'endpoint': {'remote-endpoint': [[4294967295]]}}, > 'port@1': {'reg': [[1]] > , 'endpoint': {'remote-endpoint': [[4294967295]]}}}, '$nodename': > ['hdmi@fde8']} > from schema $id: > http://devicetree.org/schemas/display/rockchip/rockchip,dw-hdmi-qp.yaml# > /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi-qp.example.dtb: > hdmi@fde8: Unevaluated properties are not allowed ('reg' was unexpected) > from schema $id: > http://devicetree.org/schemas/display/rockchip/rockchip,dw-hdmi-qp.yaml# > > doc reference errors (make refcheckdocs): > > See > https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240801-b4-rk3588-bridge-upstream-v2-1-9fa657a4e...@collabora.com > > The base for the series is generally the latest rc1. A different dependency > should be noted in *this* patch. > > If you already ran 'make dt_binding_check' and didn't see the above > error(s), then make sure 'yamllint' is installed and dt-schema is up to > date: > > pip3 install dtschema --upgrade > > Please check and re-submit after running the above command yourself. Note > that DT_SCHEMA_FILES can be set to your schema file to speed up checking > your schema. However, it must be unset to test all examples with your schema. >
Re: [PATCH 2/2] drm/bridge: synopsys: Add DW HDMI QP TX Controller driver
On 8/1/24 11:50 AM, Krzysztof Kozlowski wrote: > On 01/08/2024 04:05, Cristian Ciocaltea wrote: >> The Synopsys DesignWare HDMI 2.1 Quad-Pixel (QP) TX Controller supports >> the following features, among others: > > ... > >> + >> +void dw_hdmi_qp_unbind(struct dw_hdmi_qp *hdmi) >> +{ >> +} >> +EXPORT_SYMBOL_GPL(dw_hdmi_qp_unbind); > > This looks like quite useless export. Drop. > > >> + >> +void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi) >> +{ >> +dw_hdmi_qp_init_hw(hdmi); >> +} >> +EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume); >> + >> +MODULE_AUTHOR("Algea Cao "); >> +MODULE_AUTHOR("Cristian Ciocaltea "); >> +MODULE_DESCRIPTION("DW HDMI QP transmitter driver"); >> +MODULE_LICENSE("GPL"); >> +MODULE_ALIAS("platform:dw-hdmi-qp"); > > That's not a platform driver. That does not look like driver at all, > just some helper code without any user This is actually used to provide RK3588 HDMI output support: https://lore.kernel.org/lkml/20240801-b4-rk3588-bridge-upstream-v2-3-9fa657a4e...@collabora.com/ > 1. Drop alias. > 2. Provide users for this code. You cannot add some helper functions > which nothing uses. > 3. Fix subject, commit msg, module description - there is no driver > here, but helper functions. Otherwise how does it bind? Indeed, that's just a left over from the initial dw-hdmi based implementation. Will clean this up for v2. Thanks for reviewing, Cristian
Re: [PATCH 1/2] dt-bindings: display: bridge: Add schema for Synopsys DW HDMI QP TX IP
On 8/1/24 11:38 AM, Krzysztof Kozlowski wrote:> On 01/08/2024 04:05, Cristian Ciocaltea wrote: >> Add dt-binding schema containing the common properties for the Synopsys >> DesignWare HDMI QP TX controller. >> >> Note this is not a full dt-binding specification, but is meant to be >> referenced by platform-specific bindings for this IP core. > > Please provide an user for this binding. Otherwise it is a no-op. The first user of this is RK3588 HDMI TX Controller [1]. >> >> Signed-off-by: Cristian Ciocaltea >> --- >> .../display/bridge/synopsys,dw-hdmi-qp.yaml| 66 >> ++ >> 1 file changed, 66 insertions(+) >> >> diff --git >> a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml >> b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml >> new file mode 100644 >> index ..d8aee12b121d >> --- /dev/null >> +++ >> b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml >> @@ -0,0 +1,66 @@ >> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) >> +%YAML 1.2 >> +--- >> +$id: http://devicetree.org/schemas/display/bridge/synopsys,dw-hdmi-qp.yaml# >> +$schema: http://devicetree.org/meta-schemas/core.yaml# >> + >> +title: Common Properties for Synopsys DesignWare HDMI QP TX Controller IP >> + >> +maintainers: >> + - Cristian Ciocaltea >> + >> +description: | >> + This document defines device tree properties for the Synopsys DesignWare >> + HDMI 2.1 Quad-Pixel (QP) TX controller IP core. >> + It doesn't constitute a device tree binding specification by itself, but >> + is meant to be referenced by platform-specific device tree bindings. >> + >> + When referenced from platform device tree bindings, the properties defined >> + in this document are defined as follows. The platform device tree bindings >> + are responsible for defining whether each property is required or >> optional. > > Drop this all description and re-write it not to say what bindings are > or are not. Describe the hardware. I just tried to keep it similar with synopsys,dw-hdmi.yaml. > >> + >> +properties: >> + reg: >> +maxItems: 1 >> + >> + clocks: >> +minItems: 4 >> +maxItems: 6 >> +items: >> + - description: Peripheral/APB bus clock >> + - description: EARC RX biphase clock >> + - description: Reference clock >> + - description: Audio interface clock >> +additionalItems: true > > ??? What's the point of such common schema if it is not common at all? The schema is referenced by [1]. >> + >> + clock-names: >> +minItems: 4 >> +maxItems: 6 >> +items: >> + - const: pclk >> + - const: earc >> + - const: ref >> + - const: aud >> +additionalItems: true >> + >> + interrupts: >> +minItems: 4 >> +maxItems: 5 >> +items: >> + - description: AVP Unit interrupt >> + - description: CEC interrupt >> + - description: eARC RX interrupt >> + - description: Main Unit interrupt >> +additionalItems: true >> + >> + interrupt-names: >> +minItems: 4 >> +maxItems: 5 >> +items: >> + - const: avp >> + - const: cec >> + - const: earc >> + - const: main >> +additionalItems: true > > Sorry, there is no user of this and nothing here is actually common > except first entries in clocks and interrupts properties. > > I don't see any benefit of this. Sorry, I should have better indicated this is part of a larger changeset - the cover mentions this is a reworked version of an initial (larger) series and the split has been explicitly suggested during the review. > Best regards, > Krzysztof Thanks for reviewing, Cristian [1]: https://lore.kernel.org/lkml/20240801-b4-rk3588-bridge-upstream-v2-1-9fa657a4e...@collabora.com/
Re: [PATCH] backlight: pwm_bl: print errno for probe errors
Hello Martin, On Thu, Aug 01, 2024 at 11:12:55AM +0200, Martin Kepplinger-Novaković wrote: > This makes debugging often easier. > > Signed-off-by: Martin Kepplinger-Novaković > > --- > drivers/video/backlight/pwm_bl.c | 9 ++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > > diff --git a/drivers/video/backlight/pwm_bl.c > b/drivers/video/backlight/pwm_bl.c > index f1005bd0c41e3..cc7e7af71891f 100644 > --- a/drivers/video/backlight/pwm_bl.c > +++ b/drivers/video/backlight/pwm_bl.c > @@ -502,7 +502,8 @@ static int pwm_backlight_probe(struct platform_device > *pdev) > GPIOD_ASIS); > if (IS_ERR(pb->enable_gpio)) { > ret = dev_err_probe(>dev, PTR_ERR(pb->enable_gpio), > - "failed to acquire enable GPIO\n"); > + "failed to acquire enable GPIO: %ld\n", > + PTR_ERR(pb->enable_gpio)); AFAIK dev_err_probe already emits the error code passed as 2nd parameter. So I wonder about this patch's benefit. Best regards Uwe signature.asc Description: PGP signature
Re: [PATCH v15 01/29] drm/connector: Introduce an HDMI connector initialization function
Hi Am 27.05.24 um 15:57 schrieb Maxime Ripard: A lot of the various HDMI drivers duplicate some logic that depends on the HDMI spec itself and not really a particular hardware implementation. Output BPC or format selection, infoframe generation are good examples of such areas. This creates a lot of boilerplate, with a lot of variations, which makes it hard for userspace to rely on, and makes it difficult to get it right for drivers. In the next patches, we'll add a lot of infrastructure around the drm_connector and drm_connector_state structures, which will allow to abstract away the duplicated logic. This infrastructure comes with a few requirements though, and thus we need a new initialization function. Hopefully, this will make drivers simpler to handle, and their behaviour more consistent. Reviewed-by: Dave Stevenson Reviewed-by: Sui Jingfeng Reviewed-by: Dmitry Baryshkov Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_connector.c | 39 +++ include/drm/drm_connector.h | 5 + 2 files changed, 44 insertions(+) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index b0516505f7ae..d9961cce8245 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -450,10 +450,49 @@ int drmm_connector_init(struct drm_device *dev, return 0; } EXPORT_SYMBOL(drmm_connector_init); +/** + * drmm_connector_hdmi_init - Init a preallocated HDMI connector + * @dev: DRM device + * @connector: A pointer to the HDMI connector to init + * @funcs: callbacks for this connector + * @connector_type: user visible type of the connector + * @ddc: optional pointer to the associated ddc adapter + * + * Initialises a preallocated HDMI connector. Connectors can be + * subclassed as part of driver connector objects. + * + * Cleanup is automatically handled with a call to + * drm_connector_cleanup() in a DRM-managed action. + * + * The connector structure should be allocated with drmm_kzalloc(). + * + * Returns: + * Zero on success, error code on failure. + */ +int drmm_connector_hdmi_init(struct drm_device *dev, +struct drm_connector *connector, +const struct drm_connector_funcs *funcs, +int connector_type, +struct i2c_adapter *ddc) I know I'm late to the review. Wouldn't it be better to make a separate HDMI-setup helper instead of yet another init function? The type of init function to use is mostly about memory management within the driver, while the new HDMI state is about features. Maybe rather add something like drm_connector_init_hdmi_state(), which takes an initialized connector and sets all the values coming the other patches. Drivers would not have to subscribe to a certain way of memory management. AFAICT this would also allow to protect the helper and the new drm_connector.hdmi field behind DRM_DISPLAY_HDMI_STATE_HELPER. Best regards Thomas +{ + int ret; + + if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA || + connector_type == DRM_MODE_CONNECTOR_HDMIB)) + return -EINVAL; + + ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc); + if (ret) + return ret; + + return 0; +} +EXPORT_SYMBOL(drmm_connector_hdmi_init); + /** * drm_connector_attach_edid_property - attach edid property. * @connector: the connector * * Some connector types like DRM_MODE_CONNECTOR_VIRTUAL do not get a diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index fe88d7fc6b8f..4491c4c2fb6e 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1902,10 +1902,15 @@ int drm_connector_init_with_ddc(struct drm_device *dev, int drmm_connector_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, int connector_type, struct i2c_adapter *ddc); +int drmm_connector_hdmi_init(struct drm_device *dev, +struct drm_connector *connector, +const struct drm_connector_funcs *funcs, +int connector_type, +struct i2c_adapter *ddc); void drm_connector_attach_edid_property(struct drm_connector *connector); int drm_connector_register(struct drm_connector *connector); void drm_connector_unregister(struct drm_connector *connector); int drm_connector_attach_encoder(struct drm_connector *connector, struct drm_encoder *encoder); -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [Linux-stm32] [PATCH RESEND v3 0/3] Update STM DSI PHY driver
Le 29/07/2024 à 15:28, Yanjun Yang a écrit : On Fri, Jul 26, 2024 at 09:55:35AM +0200, Philippe CORNU wrote: On 7/22/24 10:38, Yanjun Yang wrote: This patch (commit id:185f99b614427360) seems to break the dsi of stm32f469 chip. I'm not familiar with the drm and the clock framework, maybe it's because there is no "ck_dsi_phy" defined for stm32f469. PS: Sorry for receiving multiple copies of this email, I forgot to use plain text mode last time. Hi, Thank you for letting us know that there was this error. We should have detected this before merging, really sorry for the problems caused by this patch. We will investigate the issue and get back to you as soon as possible. In the meantime, I think you can revert this patch in your git tree. Philippe :-) Hi, Hi, FYI DSI clock tree for stm32f469 can be found here: https://www.st.com/resource/en/reference_manual/rm0386-stm32f469xx-and-stm32f479xx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf Refer to Figure 17: DSI clock tree. After some research I think "ck_dsi_phy" was introduced in stm32h7 platforms. There is a mux which interfaces between various clocks (among ck_hse) and the byte lane clock. stm32f469 has a much simpler clock tree in which we did not bother to implement this "go-between" clock, even though they is an equivalent of the mux. After some testing, the reason behind my problem is the parent's name of 'clk_dsi_phy' for stm32f4 is 'clk-hse' other than 'ck_hse'. I don't know which is the better why to fix it: 1. Change "ck_hse" to "clk-hse" in where "clk_dsi_phy" is defined. Doing so will definitely break other platforms. 2. Use "pll_in_khz = clk_get_rate(dsi->pllref_clk) / 1000" instead of "pll_in_khz = (unsigned int)(parent_rate / 1000)" when get the clock rate. dsi->pllref_clk refers to the HSE clock if you take a look in the device-tree. This is the reason why this work on your setup. I doubt nevertheless that it wouldn't work on other platforms. But this would be a semantic nonsense, since the DSI byte lane clock is not always derived from HSE clock on other platforms. Looking again at the clk-stm32f4 driver and the DSI clock tree linked, we can maybe implement the desired clock even if it is not represented on the diagram. Eventually if this solution does not work we will go to the second solution you suggested and we will test it on all platforms. @Philippe, @Yannick Do you agree with this workflow ? Regards, Raphaël Both method can fix my problem. The first one might break other platforms. Maybe I should change the clock name of 'clk-hse'. However, I can't find the defination of this clock name for stm32f4.
[PULL] drm-misc-fixes
Hi Dave, Daniel, Here's this week drm-misc-fixes PR Maxime drm-misc-fixes-2024-08-01: A couple drm_panic fixes, several v3d fixes to increase the new timestamp API safety, several fixes for vmwgfx for various modesetting issues, PM fixes for ast, async flips improvements and two fixes for nouveau to fix resource refcounting and buffer placement. The following changes since commit 8400291e289ee6b2bf9779ff1c83a291501f017b: Linux 6.11-rc1 (2024-07-28 14:19:55 -0700) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-fixes-2024-08-01 for you to fetch changes up to 9c685f61722d30a22d55bb8a48f7a48bb2e19bcc: nouveau: set placement to original placement on uvmm validate. (2024-08-01 01:22:12 +0200) A couple drm_panic fixes, several v3d fixes to increase the new timestamp API safety, several fixes for vmwgfx for various modesetting issues, PM fixes for ast, async flips improvements and two fixes for nouveau to fix resource refcounting and buffer placement. André Almeida (2): drm/atomic: Allow userspace to use explicit sync with atomic async flips drm/atomic: Allow userspace to use damage clips with async flips Dan Carpenter (1): drm/client: Fix error code in drm_client_buffer_vmap_local() Danilo Krummrich (2): drm/gpuvm: fix missing dependency to DRM_EXEC drm/nouveau: prime: fix refcount underflow Dave Airlie (1): nouveau: set placement to original placement on uvmm validate. Dmitry Osipenko (1): drm/virtio: Fix type of dma-fence context variable Ian Forbes (2): drm/vmwgfx: Fix overlay when using Screen Targets drm/vmwgfx: Trigger a modeset when the screen moves Jammy Huang (1): drm/ast: Fix black screen after resume Maxime Ripard (2): Merge drm/drm-fixes into drm-misc-fixes Merge drm-misc/drm-misc-next-fixes into drm-misc-fixes Philip Mueller (1): drm: panel-orientation-quirks: Add quirk for OrangePi Neo Qiuxu Zhuo (1): drm/fb-helper: Don't schedule_work() to flush frame buffer during panic() Thomas Zimmermann (1): drm/ast: astdp: Wake up during connector status detection Tvrtko Ursulin (5): drm/v3d: Prevent out of bounds access in performance query extensions drm/v3d: Fix potential memory leak in the timestamp extension drm/v3d: Fix potential memory leak in the performance extension drm/v3d: Validate passed in drm syncobj handles in the timestamp extension drm/v3d: Validate passed in drm syncobj handles in the performance extension Zack Rusin (4): drm/vmwgfx: Fix a deadlock in dma buf fence polling drm/vmwgfx: Make sure the screen surface is ref counted drm/vmwgfx: Fix handling of dumb buffers drm/vmwgfx: Add basic support for external buffers Zenghui Yu (1): kselftests: dmabuf-heaps: Ensure the driver name is null-terminated drivers/gpu/drm/Kconfig| 1 + drivers/gpu/drm/ast/ast_dp.c | 7 + drivers/gpu/drm/ast/ast_drv.c | 5 + drivers/gpu/drm/ast/ast_drv.h | 1 + drivers/gpu/drm/ast/ast_mode.c | 29 +- drivers/gpu/drm/drm_atomic_uapi.c | 5 +- drivers/gpu/drm/drm_client.c | 2 +- drivers/gpu/drm/drm_fb_helper.c| 11 + drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 + drivers/gpu/drm/nouveau/nouveau_prime.c| 3 +- drivers/gpu/drm/nouveau/nouveau_uvmm.c | 1 + drivers/gpu/drm/v3d/v3d_drv.h | 4 + drivers/gpu/drm/v3d/v3d_sched.c| 44 +- drivers/gpu/drm/v3d/v3d_submit.c | 121 +++-- drivers/gpu/drm/virtio/virtgpu_submit.c| 2 +- drivers/gpu/drm/vmwgfx/vmw_surface_cache.h | 10 +- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 127 +++--- drivers/gpu/drm/vmwgfx/vmwgfx_bo.h | 15 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h| 40 +- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 17 +- drivers/gpu/drm/vmwgfx/vmwgfx_gem.c| 62 ++- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c| 504 + drivers/gpu/drm/vmwgfx/vmwgfx_kms.h| 17 +- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c| 14 +- drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c| 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_prime.c | 32 +- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 27 +- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 33 +- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 174 --- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c| 280 +++- drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c | 40 +-
Re: [PATCH v3 0/2] drm: minimum backlight overrides and implementation for amdgpu
Hi, On 7/31/24 10:55 PM, Daniel Vetter wrote: > On Wed, Jul 31, 2024 at 08:40:12PM +0300, Jani Nikula wrote: >> On Wed, 31 Jul 2024, Thomas Weißschuh wrote: >>> The value of "min_input_signal" returned from ATIF on a Framework AMD 13 >>> is "12". This leads to a fairly bright minimum display backlight. >>> >>> Add a generic override helper for the user to override the settings >>> provided by the firmware through the kernel cmdline. >>> Also add amdgpu as a user of that helper. >>> >>> One solution would be a fixed firmware version, which was announced but >>> has no timeline. >> >> The flip side is that if we add this now, it pretty much has a timeline: >> We'll have to carry and support it forever. >> >> It's not a great prospect for something so specific. Not to mention that >> the limits are generally there for electrical minimums that should not >> be overridden. And before you know it, we'll have bug reports about >> flickering screens... > > Yeah I think for this specific case where a fixed firmware is already > kinda promised, a quirk is the right fix. Otherwise we open up a can of > worms here ... so personally I like v2 a lot more. > -Sima Ok, with both Jani and Sima preferring the quirk approach from v2, I withdraw my objection against v2. So lets go with that version. Thomas, sorry about this. I see that other then a remark from Jeff Johnson about a missing MODULE_DESCRIPTION() v2 does not have any reviews yet though. So we will need to review that version now. Might be best for visibility of the patches in people's review queue to repost v2 as v4 with the MODULE_DESCRIPTION() fixed ? Regards, Hans >>> This helper does conflict with the mode override via the cmdline. >>> Only one can be specified. >>> IMO the mode override can be extended to also handle "min-brightness" >>> when that becomes necessary. >>> >>> --- >>> Changes in v3: >>> - Switch to cmdline override parameter >>> - Link to v2: >>> https://lore.kernel.org/r/20240623-amdgpu-min-backlight-quirk-v2-0-cecf7f49d...@weissschuh.net >>> >>> Changes in v2: >>> - Introduce proper drm backlight quirk infrastructure >>> - Quirk by EDID and DMI instead of only DMI >>> - Limit quirk to only single Framework 13 matte panel >>> - Link to v1: >>> https://lore.kernel.org/r/20240610-amdgpu-min-backlight-quirk-v1-1-8459895a5...@weissschuh.net >>> >>> --- >>> Thomas Weißschuh (2): >>> drm/connector: add drm_connector_get_cmdline_min_brightness_override() >>> drm/amd/display: implement minimum brightness override >>> >>> drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 >>> drivers/gpu/drm/drm_connector.c | 34 >>> +++ >>> include/drm/drm_connector.h | 2 ++ >>> 3 files changed, 42 insertions(+) >>> --- >>> base-commit: 36821612eb3091a21f7f4a907b497064725080c3 >>> change-id: 20240610-amdgpu-min-backlight-quirk-8402fd8e736a >>> >>> Best regards, >> >> -- >> Jani Nikula, Intel >
Re: [PATCH 2/2] drm/bridge: synopsys: Add DW HDMI QP TX Controller driver
On 01/08/2024 04:05, Cristian Ciocaltea wrote: > The Synopsys DesignWare HDMI 2.1 Quad-Pixel (QP) TX Controller supports > the following features, among others: ... > + > +void dw_hdmi_qp_unbind(struct dw_hdmi_qp *hdmi) > +{ > +} > +EXPORT_SYMBOL_GPL(dw_hdmi_qp_unbind); This looks like quite useless export. Drop. > + > +void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi) > +{ > + dw_hdmi_qp_init_hw(hdmi); > +} > +EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume); > + > +MODULE_AUTHOR("Algea Cao "); > +MODULE_AUTHOR("Cristian Ciocaltea "); > +MODULE_DESCRIPTION("DW HDMI QP transmitter driver"); > +MODULE_LICENSE("GPL"); > +MODULE_ALIAS("platform:dw-hdmi-qp"); That's not a platform driver. That does not look like driver at all, just some helper code without any user 1. Drop alias. 2. Provide users for this code. You cannot add some helper functions which nothing uses. 3. Fix subject, commit msg, module description - there is no driver here, but helper functions. Otherwise how does it bind? Best regards, Krzysztof
Re: [PATCH v4] drm/mediatek: dsi: Add dsi per-frame lp code for mt8188
Il 01/08/24 10:11, Shuijing Li ha scritto: Adding the per-frame lp function of mt8188, which can keep HFP in HS and reduce the time required for each line to enter and exit low power. Per Frame LP: |<--One Active Frame>| --_____ ^HSA+HBP^^RGB^^HFP^^HSA+HBP^^RGB^^HFP^^HSA+HBP^^RGB^^HFP^ Per Line LP: |<---One Active Frame--->| --__--__--____ ^HSA+HBP^^RGB^ ^HSA+HBP^^RGB^ ^HSA+HBP^^RGB^^HSA+HBP^^RGB^ Signed-off-by: Shuijing Li --- Changes in v4: Drop the code related to bllp_en and bllp_wc, adjust ps_wc to dsi->vm.hactive * dsi_buf_bpp. Changes in v3: Use function in bitfield.h and get value from phy timing, per suggestion from previous thread: https://patchwork.kernel.org/project/linux-mediatek/patch/20240424091639.22759-1-shuijing...@mediatek.com/ Changes in v2: Use bitfield macros and add new function for per prame lp and improve the format, per suggestion from previous thread: https://patchwork.kernel.org/project/linux-mediatek/patch/20240314094238.3315-1-shuijing...@mediatek.com/ --- drivers/gpu/drm/mediatek/mtk_dsi.c | 210 ++--- 1 file changed, 163 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index b6e3c011a12d..4bda8fa17c3d 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -88,12 +88,16 @@ #define DSI_HSA_WC0x50 #define DSI_HBP_WC0x54 #define DSI_HFP_WC0x58 +#define HFP_HS_EN 31 #define HFP_HS_VB_PS_WC GENMASK(30, 16) #define HFP_HS_EN BIT(31) +#define HFP_HS_VB_PS_WC_SHIFT 16 ...you don't need this definition #define DSI_CMDQ_SIZE 0x60 #define CMDQ_SIZE 0x3f #define CMDQ_SIZE_SEL BIT(15) #define DSI_HSTX_CKL_WC 0x64 +#define HSTX_CKL_WCGENMASK(15, 2) +#define HSTX_CKL_WC_SHIFT 2 This one is already defined in your GENMASK(...), and you should avoid having to define that at all. Check below for a solution. #define DSI_RX_DATA0 0x74 #define DSI_RX_DATA1 0x78 @@ -187,6 +191,7 @@ struct mtk_dsi_driver_data { bool has_shadow_ctl; bool has_size_ctl; bool cmdq_long_packet_ctl; + bool support_per_frame_lp; }; struct mtk_dsi { @@ -426,6 +431,112 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact) writel(ps_val, dsi->regs + DSI_PSCTRL); } +static void mtk_dsi_config_vdo_timing_per_frame_lp(struct mtk_dsi *dsi) +{ + u32 horizontal_sync_active_byte; + u32 horizontal_backporch_byte; + u32 horizontal_frontporch_byte; + u32 dsi_tmp_buf_bpp; + unsigned int lpx, da_hs_exit, da_hs_prep, da_hs_trail; + unsigned int da_hs_zero, ps_wc, hs_vb_ps_wc; + u32 v_active_roundup, hstx_cklp_wc; + u32 hstx_cklp_wc_max, hstx_cklp_wc_min; + struct videomode *vm = >vm; + + if (dsi->format == MIPI_DSI_FMT_RGB565) + dsi_tmp_buf_bpp = 2; + else + dsi_tmp_buf_bpp = 3; + + da_hs_trail = dsi->phy_timing.da_hs_trail; + ps_wc = dsi->vm.hactive * dsi_tmp_buf_bpp; + + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { + horizontal_sync_active_byte = + vm->hsync_len * dsi_tmp_buf_bpp - 10; + horizontal_backporch_byte = + vm->hback_porch * dsi_tmp_buf_bpp - 10; + horizontal_frontporch_byte = + vm->hfront_porch * dsi_tmp_buf_bpp - 12; + + v_active_roundup = (32 + horizontal_sync_active_byte + + horizontal_backporch_byte + ps_wc + + horizontal_frontporch_byte) % dsi->lanes; + if (v_active_roundup) + horizontal_backporch_byte = horizontal_backporch_byte + + dsi->lanes - v_active_roundup; + hstx_cklp_wc_min = (DIV_ROUND_UP((12 + 2 + 4 + + horizontal_sync_active_byte), dsi->lanes) + da_hs_trail + 1) + * dsi->lanes / 6 - 1; + hstx_cklp_wc_max = (DIV_ROUND_UP((20 + 6 + 4 + + horizontal_sync_active_byte + horizontal_backporch_byte + + ps_wc), dsi->lanes) + da_hs_trail + 1) * dsi->lanes / 6 - 1; + } else { + horizontal_sync_active_byte = vm->hsync_len * dsi_tmp_buf_bpp - 4; + + horizontal_backporch_byte = (vm->hback_porch + vm->hsync_len) * + dsi_tmp_buf_bpp - 10; + hstx_cklp_wc_min = (DIV_ROUND_UP(4, dsi->lanes) + da_hs_trail + 1) + * dsi->lanes / 6 - 1; + + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) { +
Re: [PATCH 1/2] dt-bindings: display: bridge: Add schema for Synopsys DW HDMI QP TX IP
On 01/08/2024 04:05, Cristian Ciocaltea wrote: > Add dt-binding schema containing the common properties for the Synopsys > DesignWare HDMI QP TX controller. > > Note this is not a full dt-binding specification, but is meant to be > referenced by platform-specific bindings for this IP core. Please provide an user for this binding. Otherwise it is a no-op. > > Signed-off-by: Cristian Ciocaltea > --- > .../display/bridge/synopsys,dw-hdmi-qp.yaml| 66 > ++ > 1 file changed, 66 insertions(+) > > diff --git > a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml > b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml > new file mode 100644 > index ..d8aee12b121d > --- /dev/null > +++ > b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml > @@ -0,0 +1,66 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/bridge/synopsys,dw-hdmi-qp.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Common Properties for Synopsys DesignWare HDMI QP TX Controller IP > + > +maintainers: > + - Cristian Ciocaltea > + > +description: | > + This document defines device tree properties for the Synopsys DesignWare > + HDMI 2.1 Quad-Pixel (QP) TX controller IP core. > + It doesn't constitute a device tree binding specification by itself, but > + is meant to be referenced by platform-specific device tree bindings. > + > + When referenced from platform device tree bindings, the properties defined > + in this document are defined as follows. The platform device tree bindings > + are responsible for defining whether each property is required or optional. Drop this all description and re-write it not to say what bindings are or are not. Describe the hardware. > + > +properties: > + reg: > +maxItems: 1 > + > + clocks: > +minItems: 4 > +maxItems: 6 > +items: > + - description: Peripheral/APB bus clock > + - description: EARC RX biphase clock > + - description: Reference clock > + - description: Audio interface clock > +additionalItems: true ??? What's the point of such common schema if it is not common at all? > + > + clock-names: > +minItems: 4 > +maxItems: 6 > +items: > + - const: pclk > + - const: earc > + - const: ref > + - const: aud > +additionalItems: true > + > + interrupts: > +minItems: 4 > +maxItems: 5 > +items: > + - description: AVP Unit interrupt > + - description: CEC interrupt > + - description: eARC RX interrupt > + - description: Main Unit interrupt > +additionalItems: true > + > + interrupt-names: > +minItems: 4 > +maxItems: 5 > +items: > + - const: avp > + - const: cec > + - const: earc > + - const: main > +additionalItems: true Sorry, there is no user of this and nothing here is actually common except first entries in clocks and interrupts properties. I don't see any benefit of this. Best regards, Krzysztof
Re: [PATCH v2 1/2] drm: bridge: samsung-dsim: Initialize bridge on attach
Hi, with more and more patches for TC9595 support got meged into linux-next, only a few remain on my patch stack. This is one of them and is necessary for DP support: Tested-by: Alexander Stein Am Dienstag, 25. Juni 2024, 14:26:10 CEST schrieb Marek Vasut: > Initialize the bridge on attach already, to force lanes into LP11 > state, since attach does trigger attach of downstream bridges which > may trigger (e)DP AUX channel mode read. > > This fixes a corner case where DSIM with TC9595 attached to it fails > to operate the DP AUX channel, because the TC9595 enters some debug > mode when it is released from reset without lanes in LP11 mode. By > ensuring the DSIM lanes are in LP11, the TC9595 (tc358767.c driver) > can be reset in its attach callback called from DSIM attach callback, > and recovered out of the debug mode just before TC9595 performs first > AUX channel access later in its attach callback. > > Signed-off-by: Marek Vasut > --- > Cc: Adam Ford > Cc: Alexander Stein > Cc: Andrzej Hajda > Cc: Daniel Vetter > Cc: David Airlie > Cc: Frieder Schrempf > Cc: Inki Dae > Cc: Jagan Teki > Cc: Jernej Skrabec > Cc: Jonas Karlman > Cc: Laurent Pinchart > Cc: Lucas Stach > Cc: Maarten Lankhorst > Cc: Marek Szyprowski > Cc: Maxime Ripard > Cc: Michael Walle > Cc: Neil Armstrong > Cc: Robert Foss > Cc: Thomas Zimmermann > Cc: dri-devel@lists.freedesktop.org > Cc: ker...@dh-electronics.com > --- > V2: Handle case where mode is not set yet > --- > drivers/gpu/drm/bridge/samsung-dsim.c | 32 --- > 1 file changed, 24 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c > b/drivers/gpu/drm/bridge/samsung-dsim.c > index e7e53a9e42afb..22d3bbd866d97 100644 > --- a/drivers/gpu/drm/bridge/samsung-dsim.c > +++ b/drivers/gpu/drm/bridge/samsung-dsim.c > @@ -699,20 +699,24 @@ static unsigned long samsung_dsim_set_pll(struct > samsung_dsim *dsi, > > static int samsung_dsim_enable_clock(struct samsung_dsim *dsi) > { > - unsigned long hs_clk, byte_clk, esc_clk, pix_clk; > + unsigned long hs_clk, byte_clk, esc_clk; > unsigned long esc_div; > u32 reg; > struct drm_display_mode *m = >mode; > int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); > > - /* m->clock is in KHz */ > - pix_clk = m->clock * 1000; > - > - /* Use burst_clk_rate if available, otherwise use the pix_clk */ > + /* > + * Use burst_clk_rate if available, otherwise use the mode clock > + * if mode is already set and available, otherwise fall back to > + * PLL input clock and operate in 1:1 lowest frequency mode until > + * a mode is set. > + */ > if (dsi->burst_clk_rate) > hs_clk = samsung_dsim_set_pll(dsi, dsi->burst_clk_rate); > + else if (m) /* m->clock is in KHz */ > + hs_clk = samsung_dsim_set_pll(dsi, DIV_ROUND_UP(m->clock * 1000 > * bpp, dsi->lanes)); > else > - hs_clk = samsung_dsim_set_pll(dsi, DIV_ROUND_UP(pix_clk * bpp, > dsi->lanes)); > + hs_clk = dsi->pll_clk_rate; > > if (!hs_clk) { > dev_err(dsi->dev, "failed to configure DSI PLL\n"); > @@ -1643,9 +1647,21 @@ static int samsung_dsim_attach(struct drm_bridge > *bridge, > enum drm_bridge_attach_flags flags) > { > struct samsung_dsim *dsi = bridge_to_dsi(bridge); > + int ret; > > - return drm_bridge_attach(bridge->encoder, dsi->out_bridge, bridge, > - flags); > + ret = pm_runtime_resume_and_get(dsi->dev); > + if (ret < 0) > + return ret; > + > + ret = samsung_dsim_init(dsi); > + if (ret < 0) > + goto err; > + > + ret = drm_bridge_attach(bridge->encoder, dsi->out_bridge, bridge, > + flags); > +err: > + pm_runtime_put_sync(dsi->dev); > + return ret; > } > > static const struct drm_bridge_funcs samsung_dsim_bridge_funcs = { > -- TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany Amtsgericht München, HRB 105018 Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider http://www.tq-group.com/
Re: [PATCH] drm: mediatek: Drop unnecessary check for property presence
Il 31/07/24 22:13, Rob Herring (Arm) ha scritto: of_property_read_u32() returns -EINVAL if a property is not present, so the preceeding check for presence with of_find_property() can be dropped. Really, what the errno is shouldn't matter. Either the property can be read and used or it can't and is ignored. This is part of a larger effort to remove callers of of_find_property() and similar functions. of_find_property() leaks the DT struct property and data pointers which is a problem for dynamically allocated nodes which may be freed. Signed-off-by: Rob Herring (Arm) Reviewed-by: AngeloGioacchino Del Regno
Re: [PATCH v15 00/29] drm/connector: Create HDMI Connector infrastructure
Hi Hans, On Wed, Jul 31, 2024 at 04:56:16PM GMT, Hans Verkuil wrote: > Hi Maxime, > > On 27/05/2024 15:57, Maxime Ripard wrote: > > > > Hans Verkuil also expressed interest in implementing a mechanism in v4l2 > > to retrieve infoframes from HDMI receiver and implementing a tool to > > decode (and eventually check) infoframes. His current work on > > edid-decode to enable that based on that series can be found here: > > https://git.linuxtv.org/hverkuil/edid-decode.git/log/?h=hverkuil > > Since this patch series is now merged in mainline I also pushed support > for parsing InfoFrames to the edid-decode git repo. > > I believe the parsing part of the InfoFrames is complete, but the conformity > checks for the AVI and HDMI InfoFrames are still work-in-progress. But it > should be easier to develop this now that is merged. > > The git repo for edid-decode is here: https://git.linuxtv.org/edid-decode.git/ > > I added test files to the test/if directory, and if you run: > > edid-decode -I audio.test -I avi.test -I vendor.test -I spd.test edid.test -c > > you'll get the output below. That's awesome to hear, I'll send a patch for the KMS documentation to mention it Thanks! Maxime signature.asc Description: PGP signature
[PATCH v4] drm/mediatek: dsi: Add dsi per-frame lp code for mt8188
Adding the per-frame lp function of mt8188, which can keep HFP in HS and reduce the time required for each line to enter and exit low power. Per Frame LP: |<--One Active Frame>| --_____ ^HSA+HBP^^RGB^^HFP^^HSA+HBP^^RGB^^HFP^^HSA+HBP^^RGB^^HFP^ Per Line LP: |<---One Active Frame--->| --__--__--____ ^HSA+HBP^^RGB^ ^HSA+HBP^^RGB^ ^HSA+HBP^^RGB^^HSA+HBP^^RGB^ Signed-off-by: Shuijing Li --- Changes in v4: Drop the code related to bllp_en and bllp_wc, adjust ps_wc to dsi->vm.hactive * dsi_buf_bpp. Changes in v3: Use function in bitfield.h and get value from phy timing, per suggestion from previous thread: https://patchwork.kernel.org/project/linux-mediatek/patch/20240424091639.22759-1-shuijing...@mediatek.com/ Changes in v2: Use bitfield macros and add new function for per prame lp and improve the format, per suggestion from previous thread: https://patchwork.kernel.org/project/linux-mediatek/patch/20240314094238.3315-1-shuijing...@mediatek.com/ --- drivers/gpu/drm/mediatek/mtk_dsi.c | 210 ++--- 1 file changed, 163 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index b6e3c011a12d..4bda8fa17c3d 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -88,12 +88,16 @@ #define DSI_HSA_WC 0x50 #define DSI_HBP_WC 0x54 #define DSI_HFP_WC 0x58 +#define HFP_HS_EN 31 +#define HFP_HS_VB_PS_WC_SHIFT 16 #define DSI_CMDQ_SIZE 0x60 #define CMDQ_SIZE 0x3f #define CMDQ_SIZE_SEL BIT(15) #define DSI_HSTX_CKL_WC0x64 +#define HSTX_CKL_WCGENMASK(15, 2) +#define HSTX_CKL_WC_SHIFT 2 #define DSI_RX_DATA0 0x74 #define DSI_RX_DATA1 0x78 @@ -187,6 +191,7 @@ struct mtk_dsi_driver_data { bool has_shadow_ctl; bool has_size_ctl; bool cmdq_long_packet_ctl; + bool support_per_frame_lp; }; struct mtk_dsi { @@ -426,6 +431,112 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact) writel(ps_val, dsi->regs + DSI_PSCTRL); } +static void mtk_dsi_config_vdo_timing_per_frame_lp(struct mtk_dsi *dsi) +{ + u32 horizontal_sync_active_byte; + u32 horizontal_backporch_byte; + u32 horizontal_frontporch_byte; + u32 dsi_tmp_buf_bpp; + unsigned int lpx, da_hs_exit, da_hs_prep, da_hs_trail; + unsigned int da_hs_zero, ps_wc, hs_vb_ps_wc; + u32 v_active_roundup, hstx_cklp_wc; + u32 hstx_cklp_wc_max, hstx_cklp_wc_min; + struct videomode *vm = >vm; + + if (dsi->format == MIPI_DSI_FMT_RGB565) + dsi_tmp_buf_bpp = 2; + else + dsi_tmp_buf_bpp = 3; + + da_hs_trail = dsi->phy_timing.da_hs_trail; + ps_wc = dsi->vm.hactive * dsi_tmp_buf_bpp; + + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { + horizontal_sync_active_byte = + vm->hsync_len * dsi_tmp_buf_bpp - 10; + horizontal_backporch_byte = + vm->hback_porch * dsi_tmp_buf_bpp - 10; + horizontal_frontporch_byte = + vm->hfront_porch * dsi_tmp_buf_bpp - 12; + + v_active_roundup = (32 + horizontal_sync_active_byte + + horizontal_backporch_byte + ps_wc + + horizontal_frontporch_byte) % dsi->lanes; + if (v_active_roundup) + horizontal_backporch_byte = horizontal_backporch_byte + + dsi->lanes - v_active_roundup; + hstx_cklp_wc_min = (DIV_ROUND_UP((12 + 2 + 4 + + horizontal_sync_active_byte), dsi->lanes) + da_hs_trail + 1) + * dsi->lanes / 6 - 1; + hstx_cklp_wc_max = (DIV_ROUND_UP((20 + 6 + 4 + + horizontal_sync_active_byte + horizontal_backporch_byte + + ps_wc), dsi->lanes) + da_hs_trail + 1) * dsi->lanes / 6 - 1; + } else { + horizontal_sync_active_byte = vm->hsync_len * dsi_tmp_buf_bpp - 4; + + horizontal_backporch_byte = (vm->hback_porch + vm->hsync_len) * + dsi_tmp_buf_bpp - 10; + hstx_cklp_wc_min = (DIV_ROUND_UP(4, dsi->lanes) + da_hs_trail + 1) + * dsi->lanes / 6 - 1; + + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) { + horizontal_frontporch_byte = (vm->hfront_porch * + dsi_tmp_buf_bpp - 18); + + v_active_roundup = (28 + horizontal_backporch_byte + ps_wc + + horizontal_frontporch_byte) % dsi->lanes; + if
Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer
On Wed, 31 Jul 2024, Matthew Brost wrote: > Useful to determine size of devcoreump before writing it out. I find it useful to have this special case documented, with an example, so it's easier to see how handy this really is. BR, Jani. > > Cc: Maarten Lankhorst > Signed-off-by: Matthew Brost > --- > drivers/gpu/drm/drm_print.c | 13 - > 1 file changed, 8 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c > index cf24dfdeb6b2..a1a4de9f9c44 100644 > --- a/drivers/gpu/drm/drm_print.c > +++ b/drivers/gpu/drm/drm_print.c > @@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, const > char *str) > copy = iterator->remain; > > /* Copy out the bit of the string that we need */ > - memcpy(iterator->data, > - str + (iterator->start - iterator->offset), copy); > + if (iterator->data) > + memcpy(iterator->data, > + str + (iterator->start - iterator->offset), > copy); > > iterator->offset = iterator->start + copy; > iterator->remain -= copy; > @@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, const > char *str) > > len = min_t(ssize_t, strlen(str), iterator->remain); > > - memcpy(iterator->data + pos, str, len); > + if (iterator->data) > + memcpy(iterator->data + pos, str, len); > > iterator->offset += len; > iterator->remain -= len; > @@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer *p, struct > va_format *vaf) > if ((iterator->offset >= iterator->start) && (len < iterator->remain)) { > ssize_t pos = iterator->offset - iterator->start; > > - snprintf(((char *) iterator->data) + pos, > - iterator->remain, "%pV", vaf); > + if (iterator->data) > + snprintf(((char *) iterator->data) + pos, > + iterator->remain, "%pV", vaf); > > iterator->offset += len; > iterator->remain -= len; -- Jani Nikula, Intel
Re: [PATCH v2] drm/edid: add CTA Video Format Data Block support
On Wed, 31 Jul 2024, Hamza Mahfooz wrote: > Video Format Data Blocks (VFDBs) contain the necessary information that > needs to be fed to the Optimized Video Timings (OVT) Algorithm. > Also, we require OVT support to cover modes that aren't supported by > earlier standards (e.g. CVT). So, parse all of the relevant VFDB data > and feed it to the OVT Algorithm, to extract all of the missing OVT > modes. > > Suggested-by: Karol Herbst > Signed-off-by: Hamza Mahfooz > --- > v2: address comments from Jani > --- > drivers/gpu/drm/drm_edid.c | 456 ++--- > 1 file changed, 428 insertions(+), 28 deletions(-) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index f68a41eeb1fa..f608ab4e32ae 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -31,6 +31,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -741,6 +742,93 @@ static const struct minimode extra_modes[] = { > { 2048, 1536, 60, 0 }, > }; > > +struct cta_rid { > + u16 hactive; > + u16 vactive; > + u8 hratio; > + u8 vratio; > +}; > + > +/* CTA-861-I Table 11 - Resolution Identification (RID) */ > +static const struct cta_rid rids[] = { > + /* RID 0-9 */ > + { 0, 0, 0, 0 }, > + { 1280, 720, 16, 9 }, > + { 1280, 720, 64, 27 }, > + { 1680, 720, 64, 27 }, > + { 1920, 1080, 16, 9 }, > + { 1920, 1080, 64, 27 }, > + { 2560, 1080, 64, 27 }, > + { 3840, 1080, 32, 9 }, > + { 2560, 1440, 16, 9 }, > + { 3440, 1440, 64, 27 }, > + /* RID 10-19 */ > + { 5120, 1440, 32, 9 }, > + { 3840, 2160, 16, 9 }, > + { 3840, 2160, 64, 27 }, > + { 5120, 2160, 64, 27 }, > + { 7680, 2160, 32, 9 }, > + { 5120, 2880, 16, 9 }, > + { 5120, 2880, 64, 27 }, > + { 6880, 2880, 64, 27 }, > + { 10240, 2880, 32, 9 }, > + { 7680, 4320, 16, 9 }, > + /* RID 20-28 */ > + { 7680, 4320, 64, 27 }, > + { 10240, 4320, 64, 27 }, > + { 15360, 4320, 32, 9 }, > + { 11520, 6480, 16, 9 }, > + { 11520, 6480, 64, 27 }, > + { 15360, 6480, 64, 27 }, > + { 15360, 8640, 16, 9 }, > + { 15360, 8640, 64, 27 }, > + { 20480, 8640, 64, 27 }, > +}; > + > +/* CTA-861-I Table 12 - AVI InfoFrame Video Format Frame Rate */ > +static const u16 cta_vf_fr[] = { > + /* Frame Rate 0-7 */ > + 0, 24, 25, 30, 48, 50, 60, 100, > + /* Frame Rate 8-15 */ > + 120, 144, 200, 240, 300, 360, 400, 480, > +}; > + > +/* CTA-861-I Table 13 - RID To VIC Mapping */ > +static const u8 rid_to_vic[][8] = { > + /* RID 0-9 */ > + {}, > + { 60, 61, 62, 108, 19, 4, 41, 47 }, > + { 65, 66, 67, 109, 68, 69, 70, 71 }, > + { 79, 80, 81, 110, 82, 83, 84, 85 }, > + { 32, 33, 34, 111, 31, 16, 64, 63 }, > + { 72, 73, 74, 112, 75, 76, 77, 78 }, > + { 86, 87, 88, 113, 89, 90, 91, 92 }, > + {}, > + {}, > + {}, > + /* RID 10-19 */ > + {}, > + { 93, 94, 95, 114, 96, 97, 117, 118 }, > + { 103, 104, 105, 116, 106, 107, 119, 120 }, > + { 121, 122, 123, 124, 125, 126, 127, 193 }, > + {}, > + {}, > + {}, > + {}, > + {}, > + { 194, 195, 196, 197, 198, 199, 200, 201 }, > + /* RID 20-28 */ > + { 202, 203, 204, 205, 206, 207, 208, 209 }, > + { 210, 211, 212, 213, 214, 215, 216, 217 }, > + {}, > + {}, > + {}, > + {}, > + {}, > + {}, > + {}, > +}; > + > /* > * From CEA/CTA-861 spec. > * > @@ -4140,6 +4228,7 @@ static int add_detailed_modes(struct drm_connector > *connector, > #define CTA_DB_VIDEO 2 > #define CTA_DB_VENDOR3 > #define CTA_DB_SPEAKER 4 > +#define CTA_DB_VIDEO_FORMAT 6 > #define CTA_DB_EXTENDED_TAG 7 > > /* CTA-861-H Table 62 - CTA Extended Tag Codes */ > @@ -4981,6 +5070,16 @@ struct cea_db { > u8 data[]; > } __packed; > > +struct cta_vfd { > + u8 rid; > + u8 fr_fact; > + bool bfr50; > + bool fr24; > + bool bfr60; > + bool fr144; > + bool fr48; > +}; > + > static int cea_db_tag(const struct cea_db *db) > { > return db->tag_length >> 5; > @@ -5306,34 +5405,6 @@ static void parse_cta_y420cmdb(struct drm_connector > *connector, > *y420cmdb_map = map; > } > > -static int add_cea_modes(struct drm_connector *connector, > - const struct drm_edid *drm_edid) > -{ > - const struct cea_db *db; > - struct cea_db_iter iter; > - int modes; > - > - /* CTA VDB block VICs parsed earlier */ > - modes = add_cta_vdb_modes(connector); > - > - cea_db_iter_edid_begin(drm_edid, ); > - cea_db_iter_for_each(db, ) { > - if (cea_db_is_hdmi_vsdb(db)) { > - modes += do_hdmi_vsdb_modes(connector, (const u8 *)db, > - cea_db_payload_len(db)); > - } else if (cea_db_is_y420vdb(db)) { > -
linux-next: build warnings after merge of the drm-misc tree
Hi all, After merging the drm-misc tree, today's linux-next build (htmldocs) produced these warnings: Documentation/gpu/drm-kms:538: drivers/gpu/drm/drm_connector.c:1641: ERROR: Unexpected indentation. Documentation/gpu/drm-kms:538: drivers/gpu/drm/drm_connector.c:1643: WARNING: Block quote ends without a blank line; unexpected unindent. Documentation/gpu/drm-kms:538: drivers/gpu/drm/drm_connector.c:2388: WARNING: Definition list ends without a blank line; unexpected unindent. Documentation/gpu/drm-kms:538: drivers/gpu/drm/drm_connector.c:2390: ERROR: Unexpected indentation. Documentation/gpu/drm-kms:538: drivers/gpu/drm/drm_connector.c:2412: WARNING: Block quote ends without a blank line; unexpected unindent. Documentation/gpu/drm-kms:538: drivers/gpu/drm/drm_connector.c:2425: ERROR: Unexpected indentation. Introduced by commits f592e01664b4 ("drm/drm_connector: Document Colorspace property variants") 76299a557f36 ("drm: Introduce 'power saving policy' drm property") -- Cheers, Stephen Rothwell pgp01cgicrMXk.pgp Description: OpenPGP digital signature
[PULL] drm-intel-fixes
Hi Dave & Sima, Just three smaller fixups. CI is again all over the place after -rc1, but below changes shouldn't make it any worse. Regards, Joonas *** drm-intel-fixes-2024-08-01: - Static analysis fix for int overflow - Fix for HDCP2_STREAM_STATUS macro and removal of PWR_CLK_STATE for gen12 The following changes since commit 8400291e289ee6b2bf9779ff1c83a291501f017b: Linux 6.11-rc1 (2024-07-28 14:19:55 -0700) are available in the Git repository at: https://gitlab.freedesktop.org/drm/i915/kernel.git tags/drm-intel-fixes-2024-08-01 for you to fetch changes up to 5b511572660190db1dc8ba412efd0be0d3781ab6: drm/i915: Fix possible int overflow in skl_ddi_calculate_wrpll() (2024-07-30 16:57:24 +0300) - Static analysis fix for int overflow - Fix for HDCP2_STREAM_STATUS macro and removal of PWR_CLK_STATE for gen12 Nikita Zhandarovich (1): drm/i915: Fix possible int overflow in skl_ddi_calculate_wrpll() Suraj Kandpal (1): drm/i915/hdcp: Fix HDCP2_STREAM_STATUS macro Umesh Nerlige Ramappa (1): i915/perf: Remove code to update PWR_CLK_STATE for gen12 drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 6 ++--- drivers/gpu/drm/i915/display/intel_hdcp_regs.h | 2 +- drivers/gpu/drm/i915/i915_perf.c | 33 -- 3 files changed, 4 insertions(+), 37 deletions(-)
Re: [PATCH v2 1/2] drm/mipi-dsi: add more multi functions for better error handling
On 8/1/24 2:59 AM, Doug Anderson wrote: > Hi, > > On Mon, Jul 29, 2024 at 11:07 PM Tejas Vipin wrote: >> +/** >> + * mipi_dsi_dcs_get_display_brightness_multi() - gets the current >> brightness value >> + *of the display >> + * @ctx: Context for multiple DSI transactions >> + * @brightness: brightness value >> + * >> + * Like mipi_dsi_dcs_get_display_brightness() but deals with errors in a >> way that >> + * makes it convenient to make several calls in a row. >> + */ >> +void mipi_dsi_dcs_get_display_brightness_multi(struct >> mipi_dsi_multi_context *ctx, >> + u16 *brightness) >> +{ >> + struct mipi_dsi_device *dsi = ctx->dsi; >> + struct device *dev = >dev; >> + int ret; >> + >> + if (ctx->accum_err) >> + return; >> + >> + ret = mipi_dsi_dcs_get_display_brightness(dsi, brightness); >> + if (ret < 0) { >> + ctx->accum_err = ret; >> + dev_err(dev, "Failed to get display brightness: %d\n", >> + ctx->accum_err); >> + } >> +} >> +EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_multi); > > I'd be interested in others' opinions, but this function strikes me as > one that *shouldn't* be converted to _multi. > Only reason I converted the function at all was really for uniformity's sake. But I don't think that's valid anymore seeing how there's already other mipi_dsi funtions that I'm not converting and this function probably wouldn't show up in the context of the other multi functions. > Specifically the whole point of the _multi abstraction is that you can > fire off a whole pile of initialization commands without needing to > check for errors constantly. You can check for errors once at the end > of a sequence of commands and you can be sure that an error message > was printed for the command that failed and that all of the future > commands didn't do anything. > > I have a hard time believing that _get_ brightness would be part of > this pile of initialization commands. ...and looking at how you use it > in the next patch I can see that, indeed, it's a bit awkward using the > _multi variant in the case you're using it. > > The one advantage of the _multi functions is that they are also > "chatty" and we don't need to print the error everywhere. However, it > seems like we could just make the existing function print an error > message but still return the error directly. If this automatic > printing an error message is a problem for someone then I guess maybe > we've already reached the "tomorrow" [1] and need to figure out if we > need to keep two variants of the function around instead of marking > one as deprecated. > One thing that struck me as odd was that the callers of mipi_dsi_dcs_get_display_brightness never bothered to print errors at all? If we want to print errors for non-multi functions, then I think it would be best to just modify the existing function. And in the case that someone doesn't want those errors showing up, I agree with what Maxime said [2] and let users handle it. > NOTE: If we don't convert this then the "set" function will still be > _multi but the "get" one won't be. I think that's fine since the "set" > function could plausibly be in a big sequence of commands but the > "get" function not so much... > > [1] > https://lore.kernel.org/r/CAD=FV=wbxdnm4or3ae+nyoqw1sce0jp6fwtchshsaluefnh...@mail.gmail.com [2] https://lore.kernel.org/all/20240726-cerise-civet-of-reverence-ebeb9d@houat/ -- Tejas Vipin