Re: [PATCH 2/2] drm/i915/gem: Migrate to system at dma-buf attach time (v5)
On Wed, Jul 14, 2021 at 11:01 PM Jason Ekstrand wrote: > > On Tue, Jul 13, 2021 at 10:23 AM Daniel Vetter wrote: > > > > On Tue, Jul 13, 2021 at 04:06:13PM +0100, Matthew Auld wrote: > > > On Tue, 13 Jul 2021 at 15:44, Daniel Vetter wrote: > > > > > > > > On Mon, Jul 12, 2021 at 06:12:34PM -0500, Jason Ekstrand wrote: > > > > > From: Thomas Hellström > > > > > > > > > > Until we support p2p dma or as a complement to that, migrate data > > > > > to system memory at dma-buf attach time if possible. > > > > > > > > > > v2: > > > > > - Rebase on dynamic exporter. Update the igt_dmabuf_import_same_driver > > > > > selftest to migrate if we are LMEM capable. > > > > > v3: > > > > > - Migrate also in the pin() callback. > > > > > v4: > > > > > - Migrate in attach > > > > > v5: (jason) > > > > > - Lock around the migration > > > > > > > > > > Signed-off-by: Thomas Hellström > > > > > Signed-off-by: Michael J. Ruhl > > > > > Reported-by: kernel test robot > > > > > Signed-off-by: Jason Ekstrand > > > > > Reviewed-by: Jason Ekstrand > > > > > --- > > > > > drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c| 25 > > > > > ++- > > > > > .../drm/i915/gem/selftests/i915_gem_dmabuf.c | 4 ++- > > > > > 2 files changed, 27 insertions(+), 2 deletions(-) > > > > > > > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c > > > > > b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c > > > > > index 9a655f69a0671..3163f00554476 100644 > > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c > > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c > > > > > @@ -170,8 +170,31 @@ static int i915_gem_dmabuf_attach(struct dma_buf > > > > > *dmabuf, > > > > > struct dma_buf_attachment *attach) > > > > > { > > > > > struct drm_i915_gem_object *obj = dma_buf_to_obj(dmabuf); > > > > > + struct i915_gem_ww_ctx ww; > > > > > + int err; > > > > > + > > > > > + for_i915_gem_ww(, err, true) { > > > > > + err = i915_gem_object_lock(obj, ); > > > > > + if (err) > > > > > + continue; > > > > > + > > > > > + if (!i915_gem_object_can_migrate(obj, > > > > > INTEL_REGION_SMEM)) { > > > > > + err = -EOPNOTSUPP; > > > > > + continue; > > > > > + } > > > > > + > > > > > + err = i915_gem_object_migrate(obj, , > > > > > INTEL_REGION_SMEM); > > > > > + if (err) > > > > > + continue; > > > > > > > > > > - return i915_gem_object_pin_pages_unlocked(obj); > > > > > + err = i915_gem_object_wait_migration(obj, 0); > > > > > + if (err) > > > > > + continue; > > > > > + > > > > > + err = i915_gem_object_pin_pages(obj); > > > > > + } > > > > > + > > > > > + return err; > > > > > } > > > > > > > > > > static void i915_gem_dmabuf_detach(struct dma_buf *dmabuf, > > > > > diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c > > > > > b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c > > > > > index 3dc0f8b3cdab0..4f7e77b1c0152 100644 > > > > > --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c > > > > > +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c > > > > > @@ -106,7 +106,9 @@ static int igt_dmabuf_import_same_driver(void > > > > > *arg) > > > > > int err; > > > > > > > > > > force_different_devices = true; > > > > > - obj = i915_gem_object_create_shmem(i915, PAGE_SIZE); > > > > > + obj = i915_gem_object_create_lmem(i915, PAGE_SIZE, 0); > > > > > > > > I'm wondering (and couldn't answer) whether this creates an lmem+smem > > > > buffer, since if we create an lmem-only buffer then the migration above > > > > should fail. > > > > > > It's lmem-only, but it's also a kernel internal object, so the > > > migration path will still happily migrate it if asked. On the other > > > hand if it's a userspace object then we always have to respect the > > > placements. > > > > > > I think for now the only usecase for that is in the selftests. > > > > Yeah I've read the kerneldoc, it's all nicely documented but feels a bit > > dangerous. What I proposed on irc: > > - i915_gem_object_migrate does the placement check, i.e. as strict as > > can_migrate. > > - A new __i915_gem_object_migrate is for selftest that do special stuff. > > I just sent out a patch which does this except we don't actually need > the __ version because there are no self-tests that want to do a > dangerous migrate. We could add such a helper later if we needed. > > > - In the import selftest we check that lmem-only fails (because we can't > > pin it into smem) for a non-dynamic importer, but lmem+smem works and > > gets migrated. > > I think we maybe want multiple things here? The test we have right > now is useful because, by creating an internal LMEM buffer we ensure > that the migration actually happens. If we create LMEM+SMEM, then
Re: [pull] amdgpu, amdkfd drm-fixes-5.14
Hi Alex, On Wed, Jul 14, 2021 at 06:08:58PM -0400, Alex Deucher wrote: > Hi Dave, Daniel, > > Fixes for 5.14. The big change here is unifying the SMU13 code. This was > new code added in 5.14 to support Yellow Carp, but we've since cleaned it > up and removed a lot of duplication, so better to merge it now to facilitate > any bug fixes in the future that need to go back to this kernel via stable. > Only affects Yellow Carp which is new for 5.14 anyway so not much chance for > regressions. The rest is just standard bug fixes. This pull seems not to include any fixes for the W=1 warnings that has crept in again. It would be nice if the amdgpu could be warning free again, this would maybe motivate the others to fix theirs too so we could keep most/all of drivers/gpu/ free of W=1 warnings. Sam
[tegra-drm:drm/tegra/for-next 9/14] drivers/gpu/drm/tegra/uapi.c:278:5: warning: no previous prototype for function 'tegra_drm_ioctl_gem_create'
tree: git://anongit.freedesktop.org/tegra/linux.git drm/tegra/for-next head: b19502d1a683c11f6f2c92ad63c61288b0fbe1a1 commit: cdf631031f3e574b76afed51bda0ccc9d71d4a4e [9/14] drm/tegra: Implement new UAPI config: arm64-randconfig-r025-20210714 (attached as .config) compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 0e49c54a8cbd3e779e5526a5888c683c01cc3c50) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm64 cross compiling tool for clang build # apt-get install binutils-aarch64-linux-gnu git remote add tegra-drm git://anongit.freedesktop.org/tegra/linux.git git fetch --no-tags tegra-drm drm/tegra/for-next git checkout cdf631031f3e574b76afed51bda0ccc9d71d4a4e # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/gpu/drm/tegra/uapi.c:278:5: warning: no previous prototype for >> function 'tegra_drm_ioctl_gem_create' [-Wmissing-prototypes] int tegra_drm_ioctl_gem_create(struct drm_device *drm, void *data, ^ drivers/gpu/drm/tegra/uapi.c:278:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int tegra_drm_ioctl_gem_create(struct drm_device *drm, void *data, ^ static >> drivers/gpu/drm/tegra/uapi.c:295:5: warning: no previous prototype for >> function 'tegra_drm_ioctl_gem_mmap' [-Wmissing-prototypes] int tegra_drm_ioctl_gem_mmap(struct drm_device *drm, void *data, ^ drivers/gpu/drm/tegra/uapi.c:295:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int tegra_drm_ioctl_gem_mmap(struct drm_device *drm, void *data, ^ static 2 warnings generated. vim +/tegra_drm_ioctl_gem_create +278 drivers/gpu/drm/tegra/uapi.c 277 > 278 int tegra_drm_ioctl_gem_create(struct drm_device *drm, void *data, 279 struct drm_file *file) 280 { 281 struct drm_tegra_gem_create *args = data; 282 struct tegra_bo *bo; 283 284 if (args->flags) 285 return -EINVAL; 286 287 bo = tegra_bo_create_with_handle(file, drm, args->size, args->flags, 288 >handle); 289 if (IS_ERR(bo)) 290 return PTR_ERR(bo); 291 292 return 0; 293 } 294 > 295 int tegra_drm_ioctl_gem_mmap(struct drm_device *drm, void *data, --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
[PATCH 11/13] vfio/ap, ccw: Fix open/close when multiple device FDs are open
The user can open multiple device FDs if it likes, however these open() functions call vfio_register_notifier() on some device global state. Calling vfio_register_notifier() twice in will trigger a WARN_ON from notifier_chain_register() and the first close will wrongly delete the notifier and more. Since these really want the new open/close_device() semantics just change the functions over. Signed-off-by: Jason Gunthorpe --- drivers/s390/cio/vfio_ccw_ops.c | 8 drivers/s390/crypto/vfio_ap_ops.c | 8 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index c57d2a7f091975..7f540ad0b568bc 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -159,7 +159,7 @@ static int vfio_ccw_mdev_remove(struct mdev_device *mdev) return 0; } -static int vfio_ccw_mdev_open(struct mdev_device *mdev) +static int vfio_ccw_mdev_open_device(struct mdev_device *mdev) { struct vfio_ccw_private *private = dev_get_drvdata(mdev_parent_dev(mdev)); @@ -194,7 +194,7 @@ static int vfio_ccw_mdev_open(struct mdev_device *mdev) return ret; } -static void vfio_ccw_mdev_release(struct mdev_device *mdev) +static void vfio_ccw_mdev_close_device(struct mdev_device *mdev) { struct vfio_ccw_private *private = dev_get_drvdata(mdev_parent_dev(mdev)); @@ -638,8 +638,8 @@ static const struct mdev_parent_ops vfio_ccw_mdev_ops = { .supported_type_groups = mdev_type_groups, .create = vfio_ccw_mdev_create, .remove = vfio_ccw_mdev_remove, - .open = vfio_ccw_mdev_open, - .release= vfio_ccw_mdev_release, + .open_device= vfio_ccw_mdev_open_device, + .close_device = vfio_ccw_mdev_close_device, .read = vfio_ccw_mdev_read, .write = vfio_ccw_mdev_write, .ioctl = vfio_ccw_mdev_ioctl, diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 122c85c224695e..cee5626fe0a4ef 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -1315,7 +1315,7 @@ static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev) return rc; } -static int vfio_ap_mdev_open(struct mdev_device *mdev) +static int vfio_ap_mdev_open_device(struct mdev_device *mdev) { struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev); unsigned long events; @@ -1348,7 +1348,7 @@ static int vfio_ap_mdev_open(struct mdev_device *mdev) return ret; } -static void vfio_ap_mdev_release(struct mdev_device *mdev) +static void vfio_ap_mdev_close_device(struct mdev_device *mdev) { struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev); @@ -1427,8 +1427,8 @@ static const struct mdev_parent_ops vfio_ap_matrix_ops = { .mdev_attr_groups = vfio_ap_mdev_attr_groups, .create = vfio_ap_mdev_create, .remove = vfio_ap_mdev_remove, - .open = vfio_ap_mdev_open, - .release= vfio_ap_mdev_release, + .open_device= vfio_ap_mdev_open_device, + .close_device = vfio_ap_mdev_close_device, .ioctl = vfio_ap_mdev_ioctl, }; -- 2.32.0
linux-next: Signed-off-by missing for commit in the drm-intel tree
Hi all, Commit db47fe727e1f ("drm/i915/step: s/_revid_tbl/_revids") is missing a Signed-off-by from its committer. -- Cheers, Stephen Rothwell pgpLlySaYdecR.pgp Description: OpenPGP digital signature
[tegra-drm:drm/tegra/for-next 1/14] drivers/gpu/host1x/fence.c:168:5: warning: no previous prototype for function 'host1x_fence_create_fd'
tree: git://anongit.freedesktop.org/tegra/linux.git drm/tegra/for-next head: b19502d1a683c11f6f2c92ad63c61288b0fbe1a1 commit: ad0529424defbbe0b6a154cc100e82c1a9f91400 [1/14] gpu: host1x: Add DMA fence implementation config: arm64-randconfig-r025-20210714 (attached as .config) compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 0e49c54a8cbd3e779e5526a5888c683c01cc3c50) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm64 cross compiling tool for clang build # apt-get install binutils-aarch64-linux-gnu git remote add tegra-drm git://anongit.freedesktop.org/tegra/linux.git git fetch --no-tags tegra-drm drm/tegra/for-next git checkout ad0529424defbbe0b6a154cc100e82c1a9f91400 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/gpu/host1x/fence.c:168:5: warning: no previous prototype for >> function 'host1x_fence_create_fd' [-Wmissing-prototypes] int host1x_fence_create_fd(struct host1x_syncpt *sp, u32 threshold) ^ drivers/gpu/host1x/fence.c:168:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int host1x_fence_create_fd(struct host1x_syncpt *sp, u32 threshold) ^ static 1 warning generated. vim +/host1x_fence_create_fd +168 drivers/gpu/host1x/fence.c 167 > 168 int host1x_fence_create_fd(struct host1x_syncpt *sp, u32 threshold) 169 { 170 struct sync_file *file; 171 struct dma_fence *f; 172 int fd; 173 174 f = host1x_fence_create(sp, threshold); 175 if (IS_ERR(f)) 176 return PTR_ERR(f); 177 178 fd = get_unused_fd_flags(O_CLOEXEC); 179 if (fd < 0) { 180 dma_fence_put(f); 181 return fd; 182 } 183 184 file = sync_file_create(f); 185 dma_fence_put(f); 186 if (!file) 187 return -ENOMEM; 188 189 fd_install(fd, file->file); 190 191 return fd; 192 } 193 EXPORT_SYMBOL(host1x_fence_create_fd); 194 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
Re: [PATCH 2/2 v4] drm/panel: ws2401: Add driver for WideChips WS2401
Hi, On Wed, Jul 14, 2021 at 3:52 PM Linus Walleij wrote: > > This adds a driver for panels based on the WideChips WS2401 display > controller. This display controller is used in the Samsung LMS380KF01 > display found in the Samsung GT-I8160 (Codina) mobile phone and > possibly others. > > As is common with Samsung displays manufacturer commands are necessary > to configure the display to a working state. > > The display optionally supports internal backlight control, but can > also use an external backlight. > > This driver re-uses the DBI infrastructure to communicate with the > display. > > Cc: phone-de...@vger.kernel.org > Cc: Douglas Anderson > Reviewed-by: Noralf Trønnes > Reviewed-by: Douglas Anderson > Signed-off-by: Linus Walleij > --- > ChangeLog v3->v4: > - Add more talkative Kconfig telling which mobile phone has this. > - Make sure to turn off the internal backlight totally if requested. > - Alter the logic so that we assign the backlight handle to > panel->backlight directly and save some code. Officially this is disallowed according to comments. ...and I quote: /** * @backlight: * * Backlight device, used to turn on backlight after the call * to enable(), and to turn off backlight before the call to * disable(). * backlight is set by drm_panel_of_backlight() or * drm_panel_dp_aux_backlight() and drivers shall not assign it. */ I do not personally know the motivation of not letting drivers assign it, but with the words "shall not". Yikes! -Doug
[PATCH -next v2] drm/bochs: Fix missing pci_disable_device() on error in bochs_pci_probe()
Replace pci_enable_device() with pcim_enable_device(), pci_disable_device() will be called in release automatically. Reported-by: Hulk Robot Signed-off-by: Yang Yingliang --- v2: use pcim_enable_device() --- drivers/gpu/drm/tiny/bochs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index a2cfecfa8556..73415fa9ae0f 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -648,7 +648,7 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent if (IS_ERR(dev)) return PTR_ERR(dev); - ret = pci_enable_device(pdev); + ret = pcim_enable_device(pdev); if (ret) goto err_free_dev; -- 2.25.1
Re: [Intel-gfx] [PATCH 07/16] drm/i915/guc/slpc: Enable slpc and add related H2G events
On 7/10/2021 10:37 AM, Michal Wajdeczko wrote: On 10.07.2021 03:20, Vinay Belgaumkar wrote: Add methods for interacting with guc for enabling SLPC. Enable SLPC after guc submission has been established. GuC load will s/guc/GuC fail if SLPC cannot be successfully initialized. Add various helper methods to set/unset the parameters for SLPC. They can be set using h2g calls or directly setting bits in the shared /h2g/H2G done. data structure. Signed-off-by: Vinay Belgaumkar Signed-off-by: Sundaresan Sujaritha --- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 221 ++ .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 4 - drivers/gpu/drm/i915/gt/uc/intel_uc.c | 10 + 3 files changed, 231 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c index 94e2f19951aa..e579408d1c19 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -18,6 +18,61 @@ static inline struct intel_guc *slpc_to_guc(struct intel_guc_slpc *slpc) return container_of(slpc, struct intel_guc, slpc); } +static inline struct intel_gt *slpc_to_gt(struct intel_guc_slpc *slpc) +{ + return guc_to_gt(slpc_to_guc(slpc)); +} + +static inline struct drm_i915_private *slpc_to_i915(struct intel_guc_slpc *slpc) +{ + return (slpc_to_gt(slpc))->i915; +} + +static void slpc_mem_set_param(struct slpc_shared_data *data, + u32 id, u32 value) +{ + GEM_BUG_ON(id >= SLPC_MAX_OVERRIDE_PARAMETERS); + /* When the flag bit is set, corresponding value will be read +* and applied by slpc. fix format of multi-line comment s/slpc/SLPC Done. +*/ + data->override_params_set_bits[id >> 5] |= (1 << (id % 32)); use __set_bit instead + data->override_params_values[id] = value; +} + +static void slpc_mem_unset_param(struct slpc_shared_data *data, +u32 id) +{ + GEM_BUG_ON(id >= SLPC_MAX_OVERRIDE_PARAMETERS); + /* When the flag bit is unset, corresponding value will not be +* read by slpc. +*/ + data->override_params_set_bits[id >> 5] &= (~(1 << (id % 32))); same here Done. + data->override_params_values[id] = 0; +} + +static void slpc_mem_task_control(struct slpc_shared_data *data, +u64 val, u32 enable_id, u32 disable_id) hmm, u64 to pass simple tri-state flag ? +{ + /* Enabling a param involves setting the enable_id +* to 1 and disable_id to 0. Setting it to default +* will unset both enable and disable ids and let +* slpc choose it's default values. fix format + s/slpc/SLPC +*/ + if (val == SLPC_PARAM_TASK_DEFAULT) { + /* set default */ + slpc_mem_unset_param(data, enable_id); + slpc_mem_unset_param(data, disable_id); + } else if (val == SLPC_PARAM_TASK_ENABLED) { + /* set enable */ + slpc_mem_set_param(data, enable_id, 1); + slpc_mem_set_param(data, disable_id, 0); + } else if (val == SLPC_PARAM_TASK_DISABLED) { + /* set disable */ + slpc_mem_set_param(data, disable_id, 1); + slpc_mem_set_param(data, enable_id, 0); + } maybe instead of SLPC_PARAM_TASK_* flags (that btw were confusing me earlier) you can define 3x small helpers: static void slpc_mem_set_default(data, enable_id, disable_id); static void slpc_mem_set_enabled(data, enable_id, disable_id); static void slpc_mem_set_disabled(data, enable_id, disable_id); Agree, done. +} + static int slpc_shared_data_init(struct intel_guc_slpc *slpc) { struct intel_guc *guc = slpc_to_guc(slpc); @@ -34,6 +89,128 @@ static int slpc_shared_data_init(struct intel_guc_slpc *slpc) return err; } +/* + * Send SLPC event to guc + * + */ +static int slpc_send(struct intel_guc_slpc *slpc, + struct slpc_event_input *input, + u32 in_len) +{ + struct intel_guc *guc = slpc_to_guc(slpc); + u32 *action; + + action = (u32 *)input; + action[0] = INTEL_GUC_ACTION_SLPC_REQUEST; why not just updating input->h2g_action_id ? Removed this, using your suggestion below instead. + + return intel_guc_send(guc, action, in_len); +} + +static bool slpc_running(struct intel_guc_slpc *slpc) +{ + struct slpc_shared_data *data; + u32 slpc_global_state; + + GEM_BUG_ON(!slpc->vma); + + drm_clflush_virt_range(slpc->vaddr, sizeof(struct slpc_shared_data)); do you really need to flush all 8K of shared data? it looks that you only need single u32 sure. + data = slpc->vaddr; + + slpc_global_state = data->global_state; + + return (data->global_state == SLPC_GLOBAL_STATE_RUNNING); +} + +static int
Re: [PATCH 19/47] drm/i915/guc: Ensure request ordering via completion fences
On 6/24/2021 12:04 AM, Matthew Brost wrote: If two requests are on the same ring, they are explicitly ordered by the HW. So, a submission fence is sufficient to ensure ordering when using the new GuC submission interface. Conversely, if two requests share a timeline and are on the same physical engine but different context this doesn't ensure ordering on the new GuC submission interface. So, a completion fence needs to be used to ensure ordering. Signed-off-by: John Harrison Signed-off-by: Matthew Brost --- .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 1 - drivers/gpu/drm/i915/i915_request.c | 17 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index 0a6ccdf32316..010e46dd6b16 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -926,7 +926,6 @@ static void guc_context_sched_disable(struct intel_context *ce) * request doesn't slip through the 'context_pending_disable' fence. */ if (unlikely(atomic_add_unless(>pin_count, -2, 2))) { - spin_unlock_irqrestore(>guc_state.lock, flags); Why is this unlock() being dropped here? return; } guc_id = prep_context_pending_disable(ce); diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 9dad3df5eaf7..d92c9f25c9f4 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -444,6 +444,7 @@ void i915_request_retire_upto(struct i915_request *rq) do { tmp = list_first_entry(>requests, typeof(*tmp), link); + GEM_BUG_ON(!i915_request_completed(tmp)); This condition in the BUG_ON is not a new requirement introduced by the changes below, right? just want to make sure I'm not missing anything. } while (i915_request_retire(tmp) && tmp != rq); } @@ -1405,6 +1406,9 @@ i915_request_await_external(struct i915_request *rq, struct dma_fence *fence) return err; } +static int +i915_request_await_request(struct i915_request *to, struct i915_request *from); + int i915_request_await_execution(struct i915_request *rq, struct dma_fence *fence, @@ -1464,12 +1468,13 @@ await_request_submit(struct i915_request *to, struct i915_request *from) * the waiter to be submitted immediately to the physical engine * as it may then bypass the virtual request. */ - if (to->engine == READ_ONCE(from->engine)) + if (to->engine == READ_ONCE(from->engine)) { return i915_sw_fence_await_sw_fence_gfp(>submit, >submit, I915_FENCE_GFP); - else + } else { return __i915_request_await_execution(to, from, NULL); + } { } are not needed here. I'm guessing they're leftover from a dropped change. } static int @@ -1493,7 +1498,8 @@ i915_request_await_request(struct i915_request *to, struct i915_request *from) return ret; } - if (is_power_of_2(to->execution_mask | READ_ONCE(from->execution_mask))) + if (!intel_engine_uses_guc(to->engine) && + is_power_of_2(to->execution_mask | READ_ONCE(from->execution_mask))) ret = await_request_submit(to, from); else ret = emit_semaphore_wait(to, from, I915_FENCE_GFP); @@ -1654,6 +1660,8 @@ __i915_request_add_to_timeline(struct i915_request *rq) prev = to_request(__i915_active_fence_set(>last_request, >fence)); if (prev && !__i915_request_is_complete(prev)) { + bool uses_guc = intel_engine_uses_guc(rq->engine); + /* * The requests are supposed to be kept in order. However, * we need to be wary in case the timeline->last_request @@ -1664,7 +1672,8 @@ __i915_request_add_to_timeline(struct i915_request *rq) i915_seqno_passed(prev->fence.seqno, rq->fence.seqno)); - if (is_power_of_2(READ_ONCE(prev->engine)->mask | rq->engine->mask)) + if ((!uses_guc && is_power_of_2(READ_ONCE(prev->engine)->mask | rq->engine->mask)) || + (uses_guc && prev->context == rq->context)) Would it be worth adding an engine flag instead of checking which back-end is in use? I915_ENGINE_IS_FIFO or something. Not a blocker. Daniele i915_sw_fence_await_sw_fence(>submit, >submit, >submitq);
Re: [PATCH 26/47] drm/i915/guc: GuC virtual engines
On 6/24/2021 12:04 AM, Matthew Brost wrote: Implement GuC virtual engines. Rather simple implementation, basically just allocate an engine, setup context enter / exit function to virtual engine specific functions, set all other variables / functions to guc versions, and set the engine mask to that of all the siblings. Cc: Daniele Ceraolo Spurio Signed-off-by: Matthew Brost --- drivers/gpu/drm/i915/gem/i915_gem_context.c | 19 +- drivers/gpu/drm/i915/gem/i915_gem_context.h | 1 + drivers/gpu/drm/i915/gt/intel_context_types.h | 10 + drivers/gpu/drm/i915/gt/intel_engine.h| 45 +++- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 14 + .../drm/i915/gt/intel_execlists_submission.c | 186 +++-- .../drm/i915/gt/intel_execlists_submission.h | 11 - drivers/gpu/drm/i915/gt/selftest_execlists.c | 20 +- .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 253 +- .../gpu/drm/i915/gt/uc/intel_guc_submission.h | 2 + 10 files changed, 429 insertions(+), 132 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index 5c07e6abf16a..8a9293e0ca92 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -72,7 +72,6 @@ #include "gt/intel_context_param.h" #include "gt/intel_engine_heartbeat.h" #include "gt/intel_engine_user.h" -#include "gt/intel_execlists_submission.h" /* virtual_engine */ #include "gt/intel_gpu_commands.h" #include "gt/intel_ring.h" @@ -1568,9 +1567,6 @@ set_engines__load_balance(struct i915_user_extension __user *base, void *data) if (!HAS_EXECLISTS(i915)) return -ENODEV; - if (intel_uc_uses_guc_submission(>gt.uc)) - return -ENODEV; /* not implement yet */ - if (get_user(idx, >engine_index)) return -EFAULT; @@ -1627,7 +1623,7 @@ set_engines__load_balance(struct i915_user_extension __user *base, void *data) } } - ce = intel_execlists_create_virtual(siblings, n); + ce = intel_engine_create_virtual(siblings, n); if (IS_ERR(ce)) { err = PTR_ERR(ce); goto out_siblings; @@ -1723,13 +1719,9 @@ set_engines__bond(struct i915_user_extension __user *base, void *data) * A non-virtual engine has no siblings to choose between; and * a submit fence will always be directed to the one engine. */ - if (intel_engine_is_virtual(virtual)) { - err = intel_virtual_engine_attach_bond(virtual, - master, - bond); - if (err) - return err; - } + err = intel_engine_attach_bond(virtual, master, bond); + if (err) + return err; } return 0; @@ -2116,8 +2108,7 @@ static int clone_engines(struct i915_gem_context *dst, * the virtual engine instead. */ if (intel_engine_is_virtual(engine)) - clone->engines[n] = - intel_execlists_clone_virtual(engine); + clone->engines[n] = intel_engine_clone_virtual(engine); else clone->engines[n] = intel_context_create(engine); if (IS_ERR_OR_NULL(clone->engines[n])) { diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h index b5c908f3f4f2..ba772762f7b9 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h @@ -10,6 +10,7 @@ #include "i915_gem_context_types.h" #include "gt/intel_context.h" +#include "gt/intel_engine.h" #include "i915_drv.h" #include "i915_gem.h" diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h index e7af6a2368f8..6945963a31ba 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_types.h +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h @@ -47,6 +47,16 @@ struct intel_context_ops { void (*reset)(struct intel_context *ce); void (*destroy)(struct kref *kref); + + /* virtual engine/context interface */ + struct intel_context *(*create_virtual)(struct intel_engine_cs **engine, + unsigned int count); + struct intel_context *(*clone_virtual)(struct intel_engine_cs *engine); + struct intel_engine_cs *(*get_sibling)(struct intel_engine_cs *engine, + unsigned int sibling); + int (*attach_bond)(struct intel_engine_cs *engine, + const struct intel_engine_cs *master, + const struct intel_engine_cs
Re: [PATCH 31/47] drm/i915/guc: Reset implementation for new GuC interface
On Mon, Jul 12, 2021 at 12:58:45PM -0700, John Harrison wrote: > On 6/24/2021 00:05, Matthew Brost wrote: > > Reset implementation for new GuC interface. This is the legacy reset > > implementation which is called when the i915 owns the engine hang check. > > Future patches will offload the engine hang check to GuC but we will > > continue to maintain this legacy path as a fallback and this code path > > is also required if the GuC dies. > > > > With the new GuC interface it is not possible to reset individual > > engines - it is only possible to reset the GPU entirely. This patch > > forces an entire chip reset if any engine hangs. > There seems to be quite a lot more code being changed in the patch than is > described above. Sure, it's all in order to support resets but there is a > lot happening to request/context management, support for GuC submission > enable/disable, etc. It feels like this patch really should be split into a > couple of prep patches followed by the actual reset support. Plus see couple > of minor comments below. > Yea, this is probably the most churned on patch we have as getting resets to full work isn't easy. I'll fix the below comments but I don't know if it worth spliting. Everything in the patch is required to get resets to work and I think it is better to have in a single patch so 'git blame' can give you the whole picture. Matt > > Cc: John Harrison > > Signed-off-by: Matthew Brost > > --- > > drivers/gpu/drm/i915/gt/intel_context.c | 3 + > > drivers/gpu/drm/i915/gt/intel_context_types.h | 7 + > > drivers/gpu/drm/i915/gt/intel_engine_types.h | 6 + > > .../drm/i915/gt/intel_execlists_submission.c | 40 ++ > > drivers/gpu/drm/i915/gt/intel_gt_pm.c | 6 +- > > drivers/gpu/drm/i915/gt/intel_reset.c | 18 +- > > .../gpu/drm/i915/gt/intel_ring_submission.c | 22 + > > drivers/gpu/drm/i915/gt/mock_engine.c | 31 + > > drivers/gpu/drm/i915/gt/uc/intel_guc.c| 13 - > > drivers/gpu/drm/i915/gt/uc/intel_guc.h| 8 +- > > .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 581 ++ > > drivers/gpu/drm/i915/gt/uc/intel_uc.c | 39 +- > > drivers/gpu/drm/i915/gt/uc/intel_uc.h | 3 + > > drivers/gpu/drm/i915/i915_request.c | 41 +- > > drivers/gpu/drm/i915/i915_request.h | 2 + > > 15 files changed, 649 insertions(+), 171 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_context.c > > b/drivers/gpu/drm/i915/gt/intel_context.c > > index b24a1b7a3f88..2f01437056a8 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_context.c > > +++ b/drivers/gpu/drm/i915/gt/intel_context.c > > @@ -392,6 +392,9 @@ intel_context_init(struct intel_context *ce, struct > > intel_engine_cs *engine) > > spin_lock_init(>guc_state.lock); > > INIT_LIST_HEAD(>guc_state.fences); > > + spin_lock_init(>guc_active.lock); > > + INIT_LIST_HEAD(>guc_active.requests); > > + > > ce->guc_id = GUC_INVALID_LRC_ID; > > INIT_LIST_HEAD(>guc_id_link); > > diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h > > b/drivers/gpu/drm/i915/gt/intel_context_types.h > > index 6945963a31ba..b63c8cf7823b 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_context_types.h > > +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h > > @@ -165,6 +165,13 @@ struct intel_context { > > struct list_head fences; > > } guc_state; > > + struct { > > + /** lock: protects everything in guc_active */ > > + spinlock_t lock; > > + /** requests: active requests on this context */ > > + struct list_head requests; > > + } guc_active; > > + > > /* GuC scheduling state that does not require a lock. */ > > atomic_t guc_sched_state_no_lock; > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h > > b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > index e7cb6a06db9d..f9d264c008e8 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > @@ -426,6 +426,12 @@ struct intel_engine_cs { > > void(*release)(struct intel_engine_cs *engine); > > + /* > > +* Add / remove request from engine active tracking > > +*/ > > + void(*add_active_request)(struct i915_request *rq); > > + void(*remove_active_request)(struct i915_request *rq); > > + > > struct intel_engine_execlists execlists; > > /* > > diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c > > b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c > > index c10ea6080752..c301a2d088b1 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c > > +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c > > @@ -3118,6 +3118,42 @@ static void execlists_park(struct intel_engine_cs > > *engine) > > cancel_timer(>execlists.preempt); > > } > > +static void add_to_engine(struct i915_request *rq) > > +{ > > +
Re: [Intel-gfx] [PATCH 47/47] drm/i915/guc: Unblock GuC submission on Gen11+
On Thu, Jun 24, 2021 at 12:05:16AM -0700, Matthew Brost wrote: > From: Daniele Ceraolo Spurio > > Unblock GuC submission on Gen11+ platforms. > > Signed-off-by: Michal Wajdeczko > Signed-off-by: Daniele Ceraolo Spurio > Signed-off-by: Matthew Brost Updating debug message per feedback, with that: Reviewed-by: Matthew Brost > --- > drivers/gpu/drm/i915/gt/uc/intel_guc.h| 1 + > drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 8 > drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h | 3 +-- > drivers/gpu/drm/i915/gt/uc/intel_uc.c | 14 +- > 4 files changed, 19 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h > b/drivers/gpu/drm/i915/gt/uc/intel_guc.h > index fae01dc8e1b9..77981788204f 100644 > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h > @@ -54,6 +54,7 @@ struct intel_guc { > struct ida guc_ids; > struct list_head guc_id_list; > > + bool submission_supported; > bool submission_selected; > > struct i915_vma *ads_vma; > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c > b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c > index a427336ce916..405339202280 100644 > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c > @@ -2042,6 +2042,13 @@ void intel_guc_submission_disable(struct intel_guc > *guc) > /* Note: By the time we're here, GuC may have already been reset */ > } > > +static bool __guc_submission_supported(struct intel_guc *guc) > +{ > + /* GuC submission is unavailable for pre-Gen11 */ > + return intel_guc_is_supported(guc) && > +INTEL_GEN(guc_to_gt(guc)->i915) >= 11; > +} > + > static bool __guc_submission_selected(struct intel_guc *guc) > { > struct drm_i915_private *i915 = guc_to_gt(guc)->i915; > @@ -2054,6 +2061,7 @@ static bool __guc_submission_selected(struct intel_guc > *guc) > > void intel_guc_submission_init_early(struct intel_guc *guc) > { > + guc->submission_supported = __guc_submission_supported(guc); > guc->submission_selected = __guc_submission_selected(guc); > } > > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h > b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h > index a2a3fad72be1..be767eb6ff71 100644 > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h > @@ -37,8 +37,7 @@ int intel_guc_wait_for_pending_msg(struct intel_guc *guc, > > static inline bool intel_guc_submission_is_supported(struct intel_guc *guc) > { > - /* XXX: GuC submission is unavailable for now */ > - return false; > + return guc->submission_supported; > } > > static inline bool intel_guc_submission_is_wanted(struct intel_guc *guc) > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c > b/drivers/gpu/drm/i915/gt/uc/intel_uc.c > index 7a69c3c027e9..61be0aa81492 100644 > --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c > +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c > @@ -34,8 +34,15 @@ static void uc_expand_default_options(struct intel_uc *uc) > return; > } > > - /* Default: enable HuC authentication only */ > - i915->params.enable_guc = ENABLE_GUC_LOAD_HUC; > + /* Intermediate platforms are HuC authentication only */ > + if (IS_DG1(i915) || IS_ALDERLAKE_S(i915)) { > + drm_dbg(>drm, "Disabling GuC only due to old platform\n"); > + i915->params.enable_guc = ENABLE_GUC_LOAD_HUC; > + return; > + } > + > + /* Default: enable HuC authentication and GuC submission */ > + i915->params.enable_guc = ENABLE_GUC_LOAD_HUC | ENABLE_GUC_SUBMISSION; > } > > /* Reset GuC providing us with fresh state for both GuC and HuC. > @@ -313,9 +320,6 @@ static int __uc_init(struct intel_uc *uc) > if (i915_inject_probe_failure(uc_to_gt(uc)->i915)) > return -ENOMEM; > > - /* XXX: GuC submission is unavailable for now */ > - GEM_BUG_ON(intel_uc_uses_guc_submission(uc)); > - > ret = intel_guc_init(guc); > if (ret) > return ret; > -- > 2.28.0 > > ___ > Intel-gfx mailing list > intel-...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 42/47] drm/i915/guc: Fix for error capture after full GPU reset with GuC
On Thu, Jun 24, 2021 at 12:05:11AM -0700, Matthew Brost wrote: > From: John Harrison > > In the case of a full GPU reset (e.g. because GuC has died or because > GuC's hang detection has been disabled), the driver can't rely on GuC > reporting the guilty context. Instead, the driver needs to scan all > active contexts and find one that is currently executing, as per the > execlist mode behaviour. In GuC mode, this scan is different to > execlist mode as the active request list is handled very differently. > > Similarly, the request state dump in debugfs needs to be handled > differently when in GuC submission mode. > > Also refactured some of the request scanning code to avoid duplication > across the multiple code paths that are now replicating it. > > Signed-off-by: John Harrison > Signed-off-by: Matthew Brost Reviewed-by: Matthew Brost > --- > drivers/gpu/drm/i915/gt/intel_engine.h| 3 + > drivers/gpu/drm/i915/gt/intel_engine_cs.c | 139 -- > .../gpu/drm/i915/gt/intel_engine_heartbeat.c | 8 + > drivers/gpu/drm/i915/gt/intel_reset.c | 2 +- > drivers/gpu/drm/i915/gt/uc/intel_guc.h| 2 + > .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 67 + > .../gpu/drm/i915/gt/uc/intel_guc_submission.h | 3 + > drivers/gpu/drm/i915/i915_request.c | 41 ++ > drivers/gpu/drm/i915/i915_request.h | 11 ++ > 9 files changed, 229 insertions(+), 47 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h > b/drivers/gpu/drm/i915/gt/intel_engine.h > index 6ea5643a3aaa..9ba131175564 100644 > --- a/drivers/gpu/drm/i915/gt/intel_engine.h > +++ b/drivers/gpu/drm/i915/gt/intel_engine.h > @@ -240,6 +240,9 @@ __printf(3, 4) > void intel_engine_dump(struct intel_engine_cs *engine, > struct drm_printer *m, > const char *header, ...); > +void intel_engine_dump_active_requests(struct list_head *requests, > +struct i915_request *hung_rq, > +struct drm_printer *m); > > ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine, > ktime_t *now); > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > index 1d243b83b023..bbea7c9a367d 100644 > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > @@ -1624,6 +1624,97 @@ static void print_properties(struct intel_engine_cs > *engine, > read_ul(>defaults, p->offset)); > } > > +static void engine_dump_request(struct i915_request *rq, struct drm_printer > *m, const char *msg) > +{ > + struct intel_timeline *tl = get_timeline(rq); > + > + i915_request_show(m, rq, msg, 0); > + > + drm_printf(m, "\t\tring->start: 0x%08x\n", > +i915_ggtt_offset(rq->ring->vma)); > + drm_printf(m, "\t\tring->head: 0x%08x\n", > +rq->ring->head); > + drm_printf(m, "\t\tring->tail: 0x%08x\n", > +rq->ring->tail); > + drm_printf(m, "\t\tring->emit: 0x%08x\n", > +rq->ring->emit); > + drm_printf(m, "\t\tring->space: 0x%08x\n", > +rq->ring->space); > + > + if (tl) { > + drm_printf(m, "\t\tring->hwsp: 0x%08x\n", > +tl->hwsp_offset); > + intel_timeline_put(tl); > + } > + > + print_request_ring(m, rq); > + > + if (rq->context->lrc_reg_state) { > + drm_printf(m, "Logical Ring Context:\n"); > + hexdump(m, rq->context->lrc_reg_state, PAGE_SIZE); > + } > +} > + > +void intel_engine_dump_active_requests(struct list_head *requests, > +struct i915_request *hung_rq, > +struct drm_printer *m) > +{ > + struct i915_request *rq; > + const char *msg; > + enum i915_request_state state; > + > + list_for_each_entry(rq, requests, sched.link) { > + if (rq == hung_rq) > + continue; > + > + state = i915_test_request_state(rq); > + if (state < I915_REQUEST_QUEUED) > + continue; > + > + if (state == I915_REQUEST_ACTIVE) > + msg = "\t\tactive on engine"; > + else > + msg = "\t\tactive in queue"; > + > + engine_dump_request(rq, m, msg); > + } > +} > + > +static void engine_dump_active_requests(struct intel_engine_cs *engine, > struct drm_printer *m) > +{ > + struct i915_request *hung_rq = NULL; > + struct intel_context *ce; > + bool guc; > + > + /* > + * No need for an engine->irq_seqno_barrier() before the seqno reads. > + * The GPU is still running so requests are still executing and any > + * hardware reads will be out of date by the time they are reported. > + * But the
Re: [PATCH 35/47] drm/i915/guc: Handle context reset notification
On Mon, Jul 12, 2021 at 03:58:12PM -0700, John Harrison wrote: > On 6/24/2021 00:05, Matthew Brost wrote: > > GuC will issue a reset on detecting an engine hang and will notify > > the driver via a G2H message. The driver will service the notification > > by resetting the guilty context to a simple state or banning it > > completely. > > > > Cc: Matthew Brost > > Cc: John Harrison > > Signed-off-by: Matthew Brost > > --- > > drivers/gpu/drm/i915/gt/uc/intel_guc.h| 2 ++ > > drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 3 ++ > > .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 35 +++ > > drivers/gpu/drm/i915/i915_trace.h | 10 ++ > > 4 files changed, 50 insertions(+) > > > > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h > > b/drivers/gpu/drm/i915/gt/uc/intel_guc.h > > index 85ef6767f13b..e94b0ef733da 100644 > > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h > > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h > > @@ -262,6 +262,8 @@ int intel_guc_deregister_done_process_msg(struct > > intel_guc *guc, > > const u32 *msg, u32 len); > > int intel_guc_sched_done_process_msg(struct intel_guc *guc, > > const u32 *msg, u32 len); > > +int intel_guc_context_reset_process_msg(struct intel_guc *guc, > > + const u32 *msg, u32 len); > > void intel_guc_submission_reset_prepare(struct intel_guc *guc); > > void intel_guc_submission_reset(struct intel_guc *guc, bool stalled); > > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c > > b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c > > index 4ed074df88e5..a2020373b8e8 100644 > > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c > > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c > > @@ -945,6 +945,9 @@ static int ct_process_request(struct intel_guc_ct *ct, > > struct ct_incoming_msg *r > > case INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_DONE: > > ret = intel_guc_sched_done_process_msg(guc, payload, len); > > break; > > + case INTEL_GUC_ACTION_CONTEXT_RESET_NOTIFICATION: > > + ret = intel_guc_context_reset_process_msg(guc, payload, len); > > + break; > > default: > > ret = -EOPNOTSUPP; > > break; > > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c > > b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c > > index 16b61fe71b07..9845c5bd9832 100644 > > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c > > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c > > @@ -2192,6 +2192,41 @@ int intel_guc_sched_done_process_msg(struct > > intel_guc *guc, > > return 0; > > } > > +static void guc_context_replay(struct intel_context *ce) > > +{ > > + struct i915_sched_engine *sched_engine = ce->engine->sched_engine; > > + > > + __guc_reset_context(ce, true); > > + tasklet_hi_schedule(_engine->tasklet); > > +} > > + > > +static void guc_handle_context_reset(struct intel_guc *guc, > > +struct intel_context *ce) > > +{ > > + trace_intel_context_reset(ce); > > + guc_context_replay(ce); > > +} > > + > > +int intel_guc_context_reset_process_msg(struct intel_guc *guc, > > + const u32 *msg, u32 len) > > +{ > > + struct intel_context *ce; > > + int desc_idx = msg[0]; > Should do this dereference after checking the length? Or is it guaranteed > that the length cannot be zero? > I think for safety, it should be moved. Matt > John. > > > + > > + if (unlikely(len != 1)) { > > + drm_dbg(_to_gt(guc)->i915->drm, "Invalid length %u", len); > > + return -EPROTO; > > + } > > + > > + ce = g2h_context_lookup(guc, desc_idx); > > + if (unlikely(!ce)) > > + return -EPROTO; > > + > > + guc_handle_context_reset(guc, ce); > > + > > + return 0; > > +} > > + > > void intel_guc_log_submission_info(struct intel_guc *guc, > >struct drm_printer *p) > > { > > diff --git a/drivers/gpu/drm/i915/i915_trace.h > > b/drivers/gpu/drm/i915/i915_trace.h > > index 97c2e83984ed..c095c4d39456 100644 > > --- a/drivers/gpu/drm/i915/i915_trace.h > > +++ b/drivers/gpu/drm/i915/i915_trace.h > > @@ -929,6 +929,11 @@ DECLARE_EVENT_CLASS(intel_context, > > __entry->guc_sched_state_no_lock) > > ); > > +DEFINE_EVENT(intel_context, intel_context_reset, > > +TP_PROTO(struct intel_context *ce), > > +TP_ARGS(ce) > > +); > > + > > DEFINE_EVENT(intel_context, intel_context_register, > > TP_PROTO(struct intel_context *ce), > > TP_ARGS(ce) > > @@ -1026,6 +1031,11 @@ trace_i915_request_out(struct i915_request *rq) > > { > > } > > +static inline void > > +trace_intel_context_reset(struct intel_context *ce) > > +{ > > +} > > + > > static inline void > > trace_intel_context_register(struct intel_context *ce) > > { >
[PATCH 09/13] vfio/pci: Reorganize VFIO_DEVICE_PCI_HOT_RESET to use the device set
Like vfio_pci_try_bus_reset() this code wants to reset all of the devices in the "reset group" which is the same membership as the device set. Instead of trying to reconstruct the device set from the PCI list go directly from the device set's device list to execute the reset. The same basic structure as vfio_pci_try_bus_reset() is used. The 'vfio_devices' struct is replaced with the device set linked list and we simply sweep it multiple times under the lock. This eliminates a memory allocation and get/put traffic and another improperly locked test of pci_dev_driver(). Signed-off-by: Jason Gunthorpe --- drivers/vfio/pci/vfio_pci.c | 205 1 file changed, 88 insertions(+), 117 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index fbc20f6d2dd412..ff23168b8dc551 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -223,9 +223,11 @@ static void vfio_pci_probe_mmaps(struct vfio_pci_device *vdev) } } +struct vfio_pci_group_info; static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev); static void vfio_pci_disable(struct vfio_pci_device *vdev); -static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data); +static int vfio_hot_reset_device_set(struct vfio_pci_device *vdev, +struct vfio_pci_group_info *groups); /* * INTx masking requires the ability to disable INTx signaling via PCI_COMMAND @@ -645,37 +647,11 @@ static int vfio_pci_fill_devs(struct pci_dev *pdev, void *data) return 0; } -struct vfio_pci_group_entry { - struct vfio_group *group; - int id; -}; - struct vfio_pci_group_info { int count; - struct vfio_pci_group_entry *groups; + struct vfio_group **groups; }; -static int vfio_pci_validate_devs(struct pci_dev *pdev, void *data) -{ - struct vfio_pci_group_info *info = data; - struct iommu_group *group; - int id, i; - - group = iommu_group_get(>dev); - if (!group) - return -EPERM; - - id = iommu_group_id(group); - - for (i = 0; i < info->count; i++) - if (info->groups[i].id == id) - break; - - iommu_group_put(group); - - return (i == info->count) ? -EINVAL : 0; -} - static bool vfio_pci_dev_below_slot(struct pci_dev *pdev, struct pci_slot *slot) { for (; pdev; pdev = pdev->bus->self) @@ -753,12 +729,6 @@ int vfio_pci_register_dev_region(struct vfio_pci_device *vdev, return 0; } -struct vfio_devices { - struct vfio_pci_device **devices; - int cur_index; - int max_index; -}; - static long vfio_pci_ioctl(struct vfio_device *core_vdev, unsigned int cmd, unsigned long arg) { @@ -1127,11 +1097,10 @@ static long vfio_pci_ioctl(struct vfio_device *core_vdev, } else if (cmd == VFIO_DEVICE_PCI_HOT_RESET) { struct vfio_pci_hot_reset hdr; int32_t *group_fds; - struct vfio_pci_group_entry *groups; + struct vfio_group **groups; struct vfio_pci_group_info info; - struct vfio_devices devs = { .cur_index = 0 }; bool slot = false; - int i, group_idx, mem_idx = 0, count = 0, ret = 0; + int group_idx, count = 0, ret = 0; minsz = offsetofend(struct vfio_pci_hot_reset, count); @@ -1198,9 +1167,7 @@ static long vfio_pci_ioctl(struct vfio_device *core_vdev, break; } - groups[group_idx].group = group; - groups[group_idx].id = - vfio_external_user_iommu_id(group); + groups[group_idx] = group; } kfree(group_fds); @@ -1212,64 +1179,11 @@ static long vfio_pci_ioctl(struct vfio_device *core_vdev, info.count = hdr.count; info.groups = groups; - /* -* Test whether all the affected devices are contained -* by the set of groups provided by the user. -*/ - ret = vfio_pci_for_each_slot_or_bus(vdev->pdev, - vfio_pci_validate_devs, - , slot); - if (ret) - goto hot_reset_release; - - devs.max_index = count; - devs.devices = kcalloc(count, sizeof(struct vfio_device *), - GFP_KERNEL); - if (!devs.devices) { - ret = -ENOMEM; - goto hot_reset_release; - } - - /* -* We need to get memory_lock for each device, but devices -* can share mmap_lock, therefore we need to zap and
[PATCH 08/13] vfio/pci: Change vfio_pci_try_bus_reset() to use the dev_set
Keep track of all the vfio_devices that have been added to the device set and use this list in vfio_pci_try_bus_reset() instead of trying to work backwards from the pci_device. The dev_set->lock directly prevents devices from joining/leaving the set, which further implies the pci_device cannot change drivers or that the vfio_device be freed, eliminating the need for get/put's. Completeness of the device set can be directly measured by checking if every PCI device in the reset group is also in the device set - which proves that VFIO drivers are attached to everything. This restructuring corrects a call to pci_dev_driver() without holding the device_lock() and removes a hard wiring to _pci_driver. Signed-off-by: Jason Gunthorpe --- drivers/vfio/pci/vfio_pci.c | 110 ++-- drivers/vfio/vfio.c | 10 include/linux/vfio.h| 2 + 3 files changed, 53 insertions(+), 69 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 22774e447b5f4a..fbc20f6d2dd412 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -404,6 +404,9 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev) struct vfio_pci_ioeventfd *ioeventfd, *ioeventfd_tmp; int i, bar; + /* For needs_reset */ + lockdep_assert_held(>vdev.dev_set->lock); + /* Stop the device from further DMA */ pci_clear_master(pdev); @@ -2139,34 +2142,17 @@ static struct pci_driver vfio_pci_driver = { .err_handler= _err_handlers, }; -static int vfio_pci_get_unused_devs(struct pci_dev *pdev, void *data) +static int vfio_pci_check_all_devices_bound(struct pci_dev *pdev, void *data) { - struct vfio_devices *devs = data; - struct vfio_device *device; - struct vfio_pci_device *vdev; - - if (devs->cur_index == devs->max_index) - return -ENOSPC; + struct vfio_device_set *dev_set = data; + struct vfio_device *cur; - device = vfio_device_get_from_dev(>dev); - if (!device) - return -EINVAL; - - if (pci_dev_driver(pdev) != _pci_driver) { - vfio_device_put(device); - return -EBUSY; - } - - vdev = container_of(device, struct vfio_pci_device, vdev); - - /* Fault if the device is not unused */ - if (device->open_count) { - vfio_device_put(device); - return -EBUSY; - } + lockdep_assert_held(_set->lock); - devs->devices[devs->cur_index++] = vdev; - return 0; + list_for_each_entry(cur, _set->device_list, dev_set_list) + if (cur->dev == >dev) + return 0; + return -EBUSY; } static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data) @@ -2210,8 +2196,7 @@ static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data) *needs_reset (such as by lack of FLR support) * Then attempt to perform that bus or slot reset. Callers are required * to hold vdev->dev_set->lock, protecting the bus/slot reset group from - * concurrent opens. A vfio_device reference is acquired for each device - * to prevent unbinds during the reset operation. + * concurrent opens. * * NB: vfio-core considers a group to be viable even if some devices are * bound to drivers like pci-stub or pcieport. Here we require all devices @@ -2220,61 +2205,48 @@ static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data) */ static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev) { - struct vfio_devices devs = { .cur_index = 0 }; - int i = 0, ret = -EINVAL; - bool slot = false; - struct vfio_pci_device *tmp; - - if (!pci_probe_reset_slot(vdev->pdev->slot)) - slot = true; - else if (pci_probe_reset_bus(vdev->pdev->bus)) - return; + struct vfio_device_set *dev_set = vdev->vdev.dev_set; + struct vfio_pci_device *to_reset = NULL; + struct vfio_pci_device *cur; + int ret; - if (vfio_pci_for_each_slot_or_bus(vdev->pdev, vfio_pci_count_devs, - , slot) || !i) + if (pci_probe_reset_slot(vdev->pdev->slot) && + pci_probe_reset_bus(vdev->pdev->bus)) return; - devs.max_index = i; - devs.devices = kcalloc(i, sizeof(struct vfio_device *), GFP_KERNEL); - if (!devs.devices) - return; + lockdep_assert_held(>vdev.dev_set->lock); - if (vfio_pci_for_each_slot_or_bus(vdev->pdev, - vfio_pci_get_unused_devs, - , slot)) - goto put_devs; + /* All VFIO devices have a closed FD */ + list_for_each_entry(cur, _set->device_list, vdev.dev_set_list) + if (cur->vdev.open_count) + return; + + /* All devices
[PATCH 07/13] vfio/pci: Move to the device set infrastructure
From: Yishai Hadas PCI wants to have the usual open/close_device() logic with the slight twist that the open/close_device() must be done under a singelton lock shared by all of the vfio_devices that are in the PCI "reset group". The reset group, and thus the device set, is determined by what devices pci_reset_bus() touches, which is either the entire bus or only the slot. Rely on the core code to do everything reflck was doing and delete reflck entirely. Signed-off-by: Yishai Hadas Signed-off-by: Jason Gunthorpe --- drivers/vfio/pci/vfio_pci.c | 156 ++-- drivers/vfio/pci/vfio_pci_private.h | 7 -- 2 files changed, 31 insertions(+), 132 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index fab3715d60d4ba..22774e447b5f4a 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -530,53 +530,40 @@ static void vfio_pci_vf_token_user_add(struct vfio_pci_device *vdev, int val) vfio_device_put(_vdev->vdev); } -static void vfio_pci_release(struct vfio_device *core_vdev) +static void vfio_pci_close_device(struct vfio_device *core_vdev) { struct vfio_pci_device *vdev = container_of(core_vdev, struct vfio_pci_device, vdev); - mutex_lock(>reflck->lock); - - if (!(--vdev->refcnt)) { - vfio_pci_vf_token_user_add(vdev, -1); - vfio_spapr_pci_eeh_release(vdev->pdev); - vfio_pci_disable(vdev); + vfio_pci_vf_token_user_add(vdev, -1); + vfio_spapr_pci_eeh_release(vdev->pdev); + vfio_pci_disable(vdev); - mutex_lock(>igate); - if (vdev->err_trigger) { - eventfd_ctx_put(vdev->err_trigger); - vdev->err_trigger = NULL; - } - if (vdev->req_trigger) { - eventfd_ctx_put(vdev->req_trigger); - vdev->req_trigger = NULL; - } - mutex_unlock(>igate); + mutex_lock(>igate); + if (vdev->err_trigger) { + eventfd_ctx_put(vdev->err_trigger); + vdev->err_trigger = NULL; } - - mutex_unlock(>reflck->lock); + if (vdev->req_trigger) { + eventfd_ctx_put(vdev->req_trigger); + vdev->req_trigger = NULL; + } + mutex_unlock(>igate); } -static int vfio_pci_open(struct vfio_device *core_vdev) +static int vfio_pci_open_device(struct vfio_device *core_vdev) { struct vfio_pci_device *vdev = container_of(core_vdev, struct vfio_pci_device, vdev); int ret = 0; - mutex_lock(>reflck->lock); - - if (!vdev->refcnt) { - ret = vfio_pci_enable(vdev); - if (ret) - goto error; + ret = vfio_pci_enable(vdev); + if (ret) + return ret; - vfio_spapr_pci_eeh_open(vdev->pdev); - vfio_pci_vf_token_user_add(vdev, 1); - } - vdev->refcnt++; -error: - mutex_unlock(>reflck->lock); - return ret; + vfio_spapr_pci_eeh_open(vdev->pdev); + vfio_pci_vf_token_user_add(vdev, 1); + return 0; } static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type) @@ -1870,8 +1857,8 @@ static int vfio_pci_match(struct vfio_device *core_vdev, char *buf) static const struct vfio_device_ops vfio_pci_ops = { .name = "vfio-pci", - .open = vfio_pci_open, - .release= vfio_pci_release, + .open_device= vfio_pci_open_device, + .close_device = vfio_pci_close_device, .ioctl = vfio_pci_ioctl, .read = vfio_pci_read, .write = vfio_pci_write, @@ -1880,9 +1867,6 @@ static const struct vfio_device_ops vfio_pci_ops = { .match = vfio_pci_match, }; -static int vfio_pci_reflck_attach(struct vfio_pci_device *vdev); -static void vfio_pci_reflck_put(struct vfio_pci_reflck *reflck); - static int vfio_pci_bus_notifier(struct notifier_block *nb, unsigned long action, void *data) { @@ -2020,12 +2004,17 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) INIT_LIST_HEAD(>vma_list); init_rwsem(>memory_lock); - ret = vfio_pci_reflck_attach(vdev); + if (pci_is_root_bus(pdev->bus)) + ret = vfio_assign_device_set(>vdev, vdev); + else if (!pci_probe_reset_slot(pdev->slot)) + ret = vfio_assign_device_set(>vdev, pdev->slot); + else + ret = vfio_assign_device_set(>vdev, pdev->bus); if (ret) goto out_uninit; ret = vfio_pci_vf_init(vdev); if (ret) - goto out_reflck; + goto out_uninit; ret = vfio_pci_vga_init(vdev); if (ret) goto out_vf; @@ -2057,8 +2046,6 @@ static int
[PATCH 05/13] vfio/fsl: Move to the device set infrastructure
FSL uses the internal reflck to implement the open_device() functionality, conversion to the core code is straightforward. The decision on which set to be part of is trivially based on the is_fsl_mc_bus_dprc() and we use a 'struct device *' pointer as the set_id. It isn't entirely clear what the device set lock is actually protecting, but I think it is related to the interrupt setup. Signed-off-by: Yishai Hadas Signed-off-by: Jason Gunthorpe --- drivers/vfio/fsl-mc/vfio_fsl_mc.c | 152 -- drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c| 6 +- drivers/vfio/fsl-mc/vfio_fsl_mc_private.h | 7 - 3 files changed, 26 insertions(+), 139 deletions(-) diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c index 3d2be06e1bc146..49b93de05d5d62 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c @@ -19,81 +19,10 @@ static struct fsl_mc_driver vfio_fsl_mc_driver; -static DEFINE_MUTEX(reflck_lock); - -static void vfio_fsl_mc_reflck_get(struct vfio_fsl_mc_reflck *reflck) -{ - kref_get(>kref); -} - -static void vfio_fsl_mc_reflck_release(struct kref *kref) -{ - struct vfio_fsl_mc_reflck *reflck = container_of(kref, - struct vfio_fsl_mc_reflck, - kref); - - mutex_destroy(>lock); - kfree(reflck); - mutex_unlock(_lock); -} - -static void vfio_fsl_mc_reflck_put(struct vfio_fsl_mc_reflck *reflck) -{ - kref_put_mutex(>kref, vfio_fsl_mc_reflck_release, _lock); -} - -static struct vfio_fsl_mc_reflck *vfio_fsl_mc_reflck_alloc(void) -{ - struct vfio_fsl_mc_reflck *reflck; - - reflck = kzalloc(sizeof(*reflck), GFP_KERNEL); - if (!reflck) - return ERR_PTR(-ENOMEM); - - kref_init(>kref); - mutex_init(>lock); - - return reflck; -} - -static int vfio_fsl_mc_reflck_attach(struct vfio_fsl_mc_device *vdev) -{ - int ret = 0; - - mutex_lock(_lock); - if (is_fsl_mc_bus_dprc(vdev->mc_dev)) { - vdev->reflck = vfio_fsl_mc_reflck_alloc(); - ret = PTR_ERR_OR_ZERO(vdev->reflck); - } else { - struct device *mc_cont_dev = vdev->mc_dev->dev.parent; - struct vfio_device *device; - struct vfio_fsl_mc_device *cont_vdev; - - device = vfio_device_get_from_dev(mc_cont_dev); - if (!device) { - ret = -ENODEV; - goto unlock; - } - - cont_vdev = - container_of(device, struct vfio_fsl_mc_device, vdev); - if (!cont_vdev || !cont_vdev->reflck) { - vfio_device_put(device); - ret = -ENODEV; - goto unlock; - } - vfio_fsl_mc_reflck_get(cont_vdev->reflck); - vdev->reflck = cont_vdev->reflck; - vfio_device_put(device); - } - -unlock: - mutex_unlock(_lock); - return ret; -} - -static int vfio_fsl_mc_regions_init(struct vfio_fsl_mc_device *vdev) +static int vfio_fsl_mc_open_device(struct vfio_device *core_vdev) { + struct vfio_fsl_mc_device *vdev = + container_of(core_vdev, struct vfio_fsl_mc_device, vdev); struct fsl_mc_device *mc_dev = vdev->mc_dev; int count = mc_dev->obj_desc.region_count; int i; @@ -136,58 +65,30 @@ static void vfio_fsl_mc_regions_cleanup(struct vfio_fsl_mc_device *vdev) kfree(vdev->regions); } -static int vfio_fsl_mc_open(struct vfio_device *core_vdev) -{ - struct vfio_fsl_mc_device *vdev = - container_of(core_vdev, struct vfio_fsl_mc_device, vdev); - int ret = 0; - - mutex_lock(>reflck->lock); - if (!vdev->refcnt) { - ret = vfio_fsl_mc_regions_init(vdev); - if (ret) - goto out; - } - vdev->refcnt++; -out: - mutex_unlock(>reflck->lock); - return ret; -} - -static void vfio_fsl_mc_release(struct vfio_device *core_vdev) +static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev) { struct vfio_fsl_mc_device *vdev = container_of(core_vdev, struct vfio_fsl_mc_device, vdev); + struct fsl_mc_device *mc_dev = vdev->mc_dev; + struct device *cont_dev = fsl_mc_cont_dev(_dev->dev); + struct fsl_mc_device *mc_cont = to_fsl_mc_device(cont_dev); int ret; - mutex_lock(>reflck->lock); + vfio_fsl_mc_regions_cleanup(vdev); - if (!(--vdev->refcnt)) { - struct fsl_mc_device *mc_dev = vdev->mc_dev; - struct device *cont_dev = fsl_mc_cont_dev(_dev->dev); - struct fsl_mc_device *mc_cont = to_fsl_mc_device(cont_dev); - - vfio_fsl_mc_regions_cleanup(vdev); + /* reset the device before cleaning up the interrupts */ +
[PATCH 13/13] vfio: Remove struct vfio_device_ops open/release
Nothing uses this anymore, delete it. Signed-off-by: Yishai Hadas Signed-off-by: Jason Gunthorpe --- drivers/vfio/mdev/vfio_mdev.c | 22 -- drivers/vfio/vfio.c | 14 +- include/linux/mdev.h | 7 --- include/linux/vfio.h | 4 4 files changed, 1 insertion(+), 46 deletions(-) diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c index 3c384d2350b64a..9e39f23ca2f546 100644 --- a/drivers/vfio/mdev/vfio_mdev.c +++ b/drivers/vfio/mdev/vfio_mdev.c @@ -37,26 +37,6 @@ static void vfio_mdev_close_device(struct vfio_device *core_vdev) parent->ops->close_device(mdev); } -static int vfio_mdev_open(struct vfio_device *core_vdev) -{ - struct mdev_device *mdev = to_mdev_device(core_vdev->dev); - struct mdev_parent *parent = mdev->type->parent; - - if (unlikely(!parent->ops->open)) - return -EINVAL; - - return parent->ops->open(mdev); -} - -static void vfio_mdev_release(struct vfio_device *core_vdev) -{ - struct mdev_device *mdev = to_mdev_device(core_vdev->dev); - struct mdev_parent *parent = mdev->type->parent; - - if (likely(parent->ops->release)) - parent->ops->release(mdev); -} - static long vfio_mdev_unlocked_ioctl(struct vfio_device *core_vdev, unsigned int cmd, unsigned long arg) { @@ -122,8 +102,6 @@ static const struct vfio_device_ops vfio_mdev_dev_ops = { .name = "vfio-mdev", .open_device= vfio_mdev_open_device, .close_device = vfio_mdev_close_device, - .open = vfio_mdev_open, - .release= vfio_mdev_release, .ioctl = vfio_mdev_unlocked_ioctl, .read = vfio_mdev_read, .write = vfio_mdev_write, diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 26d340283044e7..1d68e82137a735 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -1475,19 +1475,13 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) } mutex_unlock(>dev_set->lock); - if (device->ops->open) { - ret = device->ops->open(device); - if (ret) - goto err_close_device; - } - /* * We can't use anon_inode_getfd() because we need to modify * the f_mode flags directly to allow more than just ioctls */ fdno = ret = get_unused_fd_flags(O_CLOEXEC); if (ret < 0) - goto err_release; + goto err_close_device; filep = anon_inode_getfile("[vfio-device]", _device_fops, device, O_RDWR); @@ -1514,9 +1508,6 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) err_fd: put_unused_fd(fdno); -err_release: - if (device->ops->release) - device->ops->release(device); err_close_device: mutex_lock(>dev_set->lock); if (device->open_count == 1 && device->ops->close_device) @@ -1664,9 +1655,6 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep) { struct vfio_device *device = filep->private_data; - if (device->ops->release) - device->ops->release(device); - mutex_lock(>dev_set->lock); if (!--device->open_count && device->ops->close_device) device->ops->close_device(device); diff --git a/include/linux/mdev.h b/include/linux/mdev.h index cb5b7ed1d7c30d..68427e8fadebd6 100644 --- a/include/linux/mdev.h +++ b/include/linux/mdev.h @@ -72,11 +72,6 @@ struct device *mtype_get_parent_dev(struct mdev_type *mtype); * @mdev: mdev_device device structure which is being *destroyed * Returns integer: success (0) or error (< 0) - * @open: Open mediated device. - * @mdev: mediated device. - * Returns integer: success (0) or error (< 0) - * @release: release mediated device - * @mdev: mediated device. * @read: Read emulation callback * @mdev: mediated device structure * @buf: read buffer @@ -113,8 +108,6 @@ struct mdev_parent_ops { int (*remove)(struct mdev_device *mdev); int (*open_device)(struct mdev_device *mdev); void(*close_device)(struct mdev_device *mdev); - int (*open)(struct mdev_device *mdev); - void(*release)(struct mdev_device *mdev); ssize_t (*read)(struct mdev_device *mdev, char __user *buf, size_t count, loff_t *ppos); ssize_t (*write)(struct mdev_device *mdev, const char __user *buf, diff --git a/include/linux/vfio.h b/include/linux/vfio.h index f0e6a72875e471..b53a9557884ada 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@
[PATCH 10/13] vfio/mbochs: Fix close when multiple device FDs are open
mbochs_close() iterates over global device state and frees it. Currently this is done every time a device FD is closed, but if multiple device FDs are open this could corrupt other still active FDs. Change this to use close_device() so it only runs on the last close. Signed-off-by: Jason Gunthorpe --- samples/vfio-mdev/mbochs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 199273bebcc0e2..0137494c203aa2 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -1274,7 +1274,7 @@ static long mbochs_ioctl(struct vfio_device *vdev, unsigned int cmd, return -ENOTTY; } -static void mbochs_close(struct vfio_device *vdev) +static void mbochs_close_device(struct vfio_device *vdev) { struct mdev_state *mdev_state = container_of(vdev, struct mdev_state, vdev); @@ -1392,7 +1392,7 @@ static struct attribute_group *mdev_type_groups[] = { }; static const struct vfio_device_ops mbochs_dev_ops = { - .release = mbochs_close, + .close_device = mbochs_close_device, .read = mbochs_read, .write = mbochs_write, .ioctl = mbochs_ioctl, -- 2.32.0
[PATCH 12/13] vfio/gvt: Fix open/close when multiple device FDs are open
The user can open multiple device FDs if it likes, however the open function calls vfio_register_notifier() on device global state. Calling vfio_register_notifier() twice will trigger a WARN_ON from notifier_chain_register() and the first close will wrongly delete the notifier and more. Since these really want the new open/close_device() semantics just change the function over. Signed-off-by: Jason Gunthorpe --- drivers/gpu/drm/i915/gvt/kvmgt.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 1ac98f8aba31e6..7efa386449d104 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -885,7 +885,7 @@ static int intel_vgpu_group_notifier(struct notifier_block *nb, return NOTIFY_OK; } -static int intel_vgpu_open(struct mdev_device *mdev) +static int intel_vgpu_open_device(struct mdev_device *mdev) { struct intel_vgpu *vgpu = mdev_get_drvdata(mdev); struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu); @@ -1004,7 +1004,7 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu) vgpu->handle = 0; } -static void intel_vgpu_release(struct mdev_device *mdev) +static void intel_vgpu_close_device(struct mdev_device *mdev) { struct intel_vgpu *vgpu = mdev_get_drvdata(mdev); @@ -1753,8 +1753,8 @@ static struct mdev_parent_ops intel_vgpu_ops = { .create = intel_vgpu_create, .remove = intel_vgpu_remove, - .open = intel_vgpu_open, - .release= intel_vgpu_release, + .open_device= intel_vgpu_open_device, + .close_device = intel_vgpu_close_device, .read = intel_vgpu_read, .write = intel_vgpu_write, -- 2.32.0
[PATCH 03/13] vfio: Provide better generic support for open/release vfio_device_ops
Currently the driver ops have an open/release pair that is called once each time a device FD is opened or closed. Add an additional set of open/close_device() ops which are called when the device FD is opened for the first time and closed for the last time. An analysis shows that all of the drivers require this semantic. Some are open coding it as part of their reflck implementation, and some are just buggy and miss it completely. To retain the current semantics PCI and FSL depend on, introduce the idea of a "device set" which is a grouping of vfio_device's that share the same lock around opening. The device set is established by providing a 'set_id' pointer. All vfio_device's that provide the same pointer will be joined to the same singleton memory and lock across the whole set. This effectively replaces the oddly named reflck. After conversion the set_id will be sourced from: - A struct device from a fsl_mc_device (fsl) - A struct pci_slot (pci) - A struct pci_bus (pci) - The struct vfio_device (everything) The design ensures that the above pointers are live as long as the vfio_device is registered, so they form reliable unique keys to group vfio_devices into sets. This implementation uses xarray instead of searching through the driver core structures, which simplifies the somewhat tricky locking in this area. Following patches convert all the drivers. Signed-off-by: Yishai Hadas Signed-off-by: Jason Gunthorpe --- drivers/vfio/mdev/vfio_mdev.c | 22 ++ drivers/vfio/vfio.c | 144 -- include/linux/mdev.h | 2 + include/linux/vfio.h | 19 + 4 files changed, 165 insertions(+), 22 deletions(-) diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c index a5c77ccb24f70a..3c384d2350b64a 100644 --- a/drivers/vfio/mdev/vfio_mdev.c +++ b/drivers/vfio/mdev/vfio_mdev.c @@ -17,6 +17,26 @@ #include "mdev_private.h" +static int vfio_mdev_open_device(struct vfio_device *core_vdev) +{ + struct mdev_device *mdev = to_mdev_device(core_vdev->dev); + struct mdev_parent *parent = mdev->type->parent; + + if (unlikely(!parent->ops->open_device)) + return -EINVAL; + + return parent->ops->open_device(mdev); +} + +static void vfio_mdev_close_device(struct vfio_device *core_vdev) +{ + struct mdev_device *mdev = to_mdev_device(core_vdev->dev); + struct mdev_parent *parent = mdev->type->parent; + + if (likely(parent->ops->close_device)) + parent->ops->close_device(mdev); +} + static int vfio_mdev_open(struct vfio_device *core_vdev) { struct mdev_device *mdev = to_mdev_device(core_vdev->dev); @@ -100,6 +120,8 @@ static void vfio_mdev_request(struct vfio_device *core_vdev, unsigned int count) static const struct vfio_device_ops vfio_mdev_dev_ops = { .name = "vfio-mdev", + .open_device= vfio_mdev_open_device, + .close_device = vfio_mdev_close_device, .open = vfio_mdev_open, .release= vfio_mdev_release, .ioctl = vfio_mdev_unlocked_ioctl, diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index cc375df0fd5dda..6908c2ae9b36f6 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -96,6 +96,74 @@ module_param_named(enable_unsafe_noiommu_mode, MODULE_PARM_DESC(enable_unsafe_noiommu_mode, "Enable UNSAFE, no-IOMMU mode. This mode provides no device isolation, no DMA translation, no host kernel protection, cannot be used for device assignment to virtual machines, requires RAWIO permissions, and will taint the kernel. If you do not know what this is for, step away. (default: false)"); #endif +static DEFINE_XARRAY(vfio_device_set_xa); + +int vfio_assign_device_set(struct vfio_device *device, void *set_id) +{ + struct vfio_device_set *alloc_dev_set = NULL; + struct vfio_device_set *dev_set; + + if (WARN_ON(!set_id)) + return -EINVAL; + + /* +* Atomically acquire a singleton object in the xarray for this set_id +*/ +again: + xa_lock(_device_set_xa); + if (alloc_dev_set) { + dev_set = __xa_cmpxchg(_device_set_xa, + (unsigned long)set_id, NULL, + alloc_dev_set, GFP_KERNEL); + if (xa_is_err(dev_set)) { + xa_unlock(_device_set_xa); + kfree(alloc_dev_set); + return xa_err(dev_set); + } + if (!dev_set) + dev_set = alloc_dev_set; + } else + dev_set = xa_load(_device_set_xa, (unsigned long)set_id); + if (dev_set) { + dev_set->device_count++; + xa_unlock(_device_set_xa); + device->dev_set = dev_set; + if (dev_set != alloc_dev_set) + kfree(alloc_dev_set); + return
[PATCH 01/13] vfio/samples: Remove module get/put
The patch to move the get/put to core and the patch to convert the samples to use vfio_device crossed in a way that this was missed. When both patches are together the samples do not need their own get/put. Fixes: 437e41368c01 ("vfio/mdpy: Convert to use vfio_register_group_dev()") Fixes: 681c1615f891 ("vfio/mbochs: Convert to use vfio_register_group_dev()") Signed-off-by: Jason Gunthorpe --- samples/vfio-mdev/mbochs.c | 4 samples/vfio-mdev/mdpy.c | 4 2 files changed, 8 deletions(-) diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 6c0f229db36a1a..e81b875b4d87b4 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -1274,9 +1274,6 @@ static long mbochs_ioctl(struct vfio_device *vdev, unsigned int cmd, static int mbochs_open(struct vfio_device *vdev) { - if (!try_module_get(THIS_MODULE)) - return -ENODEV; - return 0; } @@ -1300,7 +1297,6 @@ static void mbochs_close(struct vfio_device *vdev) mbochs_put_pages(mdev_state); mutex_unlock(_state->ops_lock); - module_put(THIS_MODULE); } static ssize_t diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c index 393c9df6f6a010..a7d4ed28d66411 100644 --- a/samples/vfio-mdev/mdpy.c +++ b/samples/vfio-mdev/mdpy.c @@ -611,15 +611,11 @@ static long mdpy_ioctl(struct vfio_device *vdev, unsigned int cmd, static int mdpy_open(struct vfio_device *vdev) { - if (!try_module_get(THIS_MODULE)) - return -ENODEV; - return 0; } static void mdpy_close(struct vfio_device *vdev) { - module_put(THIS_MODULE); } static ssize_t -- 2.32.0
[PATCH 06/13] vfio/platform: Use open_device() instead of open coding a refcnt scheme
Platform simply wants to run some code when the device is first opened/last closed. Use the core framework and locking for this. Aside from removing a bit of code this narrows the locking scope from a global lock. Signed-off-by: Yishai Hadas Signed-off-by: Jason Gunthorpe --- drivers/vfio/platform/vfio_platform_common.c | 79 --- drivers/vfio/platform/vfio_platform_private.h | 1 - 2 files changed, 32 insertions(+), 48 deletions(-) diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index bdde8605178cd2..6af7ce7d619c25 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -218,65 +218,52 @@ static int vfio_platform_call_reset(struct vfio_platform_device *vdev, return -EINVAL; } -static void vfio_platform_release(struct vfio_device *core_vdev) +static void vfio_platform_close_device(struct vfio_device *core_vdev) { struct vfio_platform_device *vdev = container_of(core_vdev, struct vfio_platform_device, vdev); + const char *extra_dbg = NULL; + int ret; - mutex_lock(_lock); - - if (!(--vdev->refcnt)) { - const char *extra_dbg = NULL; - int ret; - - ret = vfio_platform_call_reset(vdev, _dbg); - if (ret && vdev->reset_required) { - dev_warn(vdev->device, "reset driver is required and reset call failed in release (%d) %s\n", -ret, extra_dbg ? extra_dbg : ""); - WARN_ON(1); - } - pm_runtime_put(vdev->device); - vfio_platform_regions_cleanup(vdev); - vfio_platform_irq_cleanup(vdev); + ret = vfio_platform_call_reset(vdev, _dbg); + if (WARN_ON(ret && vdev->reset_required)) { + dev_warn( + vdev->device, + "reset driver is required and reset call failed in release (%d) %s\n", + ret, extra_dbg ? extra_dbg : ""); } - - mutex_unlock(_lock); + pm_runtime_put(vdev->device); + vfio_platform_regions_cleanup(vdev); + vfio_platform_irq_cleanup(vdev); } -static int vfio_platform_open(struct vfio_device *core_vdev) +static int vfio_platform_open_device(struct vfio_device *core_vdev) { struct vfio_platform_device *vdev = container_of(core_vdev, struct vfio_platform_device, vdev); + const char *extra_dbg = NULL; int ret; - mutex_lock(_lock); - - if (!vdev->refcnt) { - const char *extra_dbg = NULL; - - ret = vfio_platform_regions_init(vdev); - if (ret) - goto err_reg; + ret = vfio_platform_regions_init(vdev); + if (ret) + return ret; - ret = vfio_platform_irq_init(vdev); - if (ret) - goto err_irq; + ret = vfio_platform_irq_init(vdev); + if (ret) + goto err_irq; - ret = pm_runtime_get_sync(vdev->device); - if (ret < 0) - goto err_rst; + ret = pm_runtime_get_sync(vdev->device); + if (ret < 0) + goto err_rst; - ret = vfio_platform_call_reset(vdev, _dbg); - if (ret && vdev->reset_required) { - dev_warn(vdev->device, "reset driver is required and reset call failed in open (%d) %s\n", -ret, extra_dbg ? extra_dbg : ""); - goto err_rst; - } + ret = vfio_platform_call_reset(vdev, _dbg); + if (ret && vdev->reset_required) { + dev_warn( + vdev->device, + "reset driver is required and reset call failed in open (%d) %s\n", + ret, extra_dbg ? extra_dbg : ""); + goto err_rst; } - - vdev->refcnt++; - - mutex_unlock(_lock); return 0; err_rst: @@ -284,8 +271,6 @@ static int vfio_platform_open(struct vfio_device *core_vdev) vfio_platform_irq_cleanup(vdev); err_irq: vfio_platform_regions_cleanup(vdev); -err_reg: - mutex_unlock(_lock); return ret; } @@ -616,8 +601,8 @@ static int vfio_platform_mmap(struct vfio_device *core_vdev, struct vm_area_stru static const struct vfio_device_ops vfio_platform_ops = { .name = "vfio-platform", - .open = vfio_platform_open, - .release= vfio_platform_release, + .open_device= vfio_platform_open_device, + .close_device = vfio_platform_close_device, .ioctl = vfio_platform_ioctl, .read = vfio_platform_read, .write = vfio_platform_write, diff --git a/drivers/vfio/platform/vfio_platform_private.h
[PATCH 04/13] vfio/samples: Delete useless open/close
The core code no longer requires these ops to be defined, so delete these empty functions and leave the op as NULL. mtty's functions only log a pointless message, delete that entirely. Signed-off-by: Yishai Hadas Signed-off-by: Jason Gunthorpe --- samples/vfio-mdev/mbochs.c | 6 -- samples/vfio-mdev/mdpy.c | 11 --- samples/vfio-mdev/mtty.c | 13 - 3 files changed, 30 deletions(-) diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index cf264d0bf11053..199273bebcc0e2 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -1274,11 +1274,6 @@ static long mbochs_ioctl(struct vfio_device *vdev, unsigned int cmd, return -ENOTTY; } -static int mbochs_open(struct vfio_device *vdev) -{ - return 0; -} - static void mbochs_close(struct vfio_device *vdev) { struct mdev_state *mdev_state = @@ -1397,7 +1392,6 @@ static struct attribute_group *mdev_type_groups[] = { }; static const struct vfio_device_ops mbochs_dev_ops = { - .open = mbochs_open, .release = mbochs_close, .read = mbochs_read, .write = mbochs_write, diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c index 57334034cde6dd..8d1a80a0722aa9 100644 --- a/samples/vfio-mdev/mdpy.c +++ b/samples/vfio-mdev/mdpy.c @@ -614,15 +614,6 @@ static long mdpy_ioctl(struct vfio_device *vdev, unsigned int cmd, return -ENOTTY; } -static int mdpy_open(struct vfio_device *vdev) -{ - return 0; -} - -static void mdpy_close(struct vfio_device *vdev) -{ -} - static ssize_t resolution_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -717,8 +708,6 @@ static struct attribute_group *mdev_type_groups[] = { }; static const struct vfio_device_ops mdpy_dev_ops = { - .open = mdpy_open, - .release = mdpy_close, .read = mdpy_read, .write = mdpy_write, .ioctl = mdpy_ioctl, diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index 37cc9067e1601d..5983cdb16e3d1d 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -1207,17 +1207,6 @@ static long mtty_ioctl(struct vfio_device *vdev, unsigned int cmd, return -ENOTTY; } -static int mtty_open(struct vfio_device *vdev) -{ - pr_info("%s\n", __func__); - return 0; -} - -static void mtty_close(struct vfio_device *mdev) -{ - pr_info("%s\n", __func__); -} - static ssize_t sample_mtty_dev_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1325,8 +1314,6 @@ static struct attribute_group *mdev_type_groups[] = { static const struct vfio_device_ops mtty_dev_ops = { .name = "vfio-mtty", - .open = mtty_open, - .release = mtty_close, .read = mtty_read, .write = mtty_write, .ioctl = mtty_ioctl, -- 2.32.0
[PATCH 00/13] Provide core infrastructure for managing open/release
Prologue: This is the first series of three to send the "mlx5_vfio_pci" driver that has been discussed on the list for a while now. - Reorganize reflck to support splitting vfio_pci - Split vfio_pci into vfio_pci/vfio_pci_core and provide infrastructure for non-generic VFIO PCI drivers - The new driver mlx5_vfio_pci that is a full implementation of suspend/resume functionality for mlx5 devices. A preview of all the patches can be seen here: https://github.com/jgunthorpe/linux/commits/mlx5_vfio_pci === This is in support of Max's series to split vfio-pci. For that to work the reflck concept embedded in vfio-pci needs to be sharable across all of the new VFIO PCI drivers which motivated re-examining how this is implemented. Another significant issue is how the VFIO PCI core includes code like: if (pci_dev_driver(pdev) != _pci_driver) Which is not scalable if there are going to be multiple different driver types. This series takes the approach of moving the "reflck" mechanism into the core code as a "device set". Each vfio_device driver can specify how vfio_devices are grouped into the set using a key and the set comes along with a set-global mutex. The core code manages creating per-device set memory and associating it with each vfio_device. In turn this allows the core code to provide an open/close_device() operation that is called only for the first/last FD, and is called under the global device set lock. Review of all the drivers show that they are either already open coding the first/last semantic or are buggy and missing it. All drivers are migrated/fixed to the new open/close_device ops and the unused per-FD open()/release() ops are deleted. The special behavior of PCI around the bus/slot "reset group" is recast in terms of the device set which conslidates the reflck, eliminates two touches of pci_dev_driver(), and allows the reset mechanism to share across all VFIO PCI drivers. PCI is changed to acquire devices directly from the device set instead of trying to work backwards from the struct pci_device. Overall a few minor bugs are squashed and quite a bit of code is removed through consolidation. Jason Gunthorpe (11): vfio/samples: Remove module get/put vfio: Provide better generic support for open/release vfio_device_ops vfio/samples: Delete useless open/close vfio/fsl: Move to the device set infrastructure vfio/platform: Use open_device() instead of open coding a refcnt scheme vfio/pci: Change vfio_pci_try_bus_reset() to use the dev_set vfio/pci: Reorganize VFIO_DEVICE_PCI_HOT_RESET to use the device set vfio/mbochs: Fix close when multiple device FDs are open vfio/ap,ccw: Fix open/close when multiple device FDs are open vfio/gvt: Fix open/close when multiple device FDs are open vfio: Remove struct vfio_device_ops open/release Max Gurtovoy (1): vfio: Introduce a vfio_uninit_group_dev() API call Yishai Hadas (1): vfio/pci: Move to the device set infrastructure Documentation/driver-api/vfio.rst | 4 +- drivers/gpu/drm/i915/gvt/kvmgt.c | 8 +- drivers/s390/cio/vfio_ccw_ops.c | 8 +- drivers/s390/crypto/vfio_ap_ops.c | 8 +- drivers/vfio/fsl-mc/vfio_fsl_mc.c | 158 ++ drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c| 6 +- drivers/vfio/fsl-mc/vfio_fsl_mc_private.h | 7 - drivers/vfio/mdev/vfio_mdev.c | 29 +- drivers/vfio/pci/vfio_pci.c | 459 ++ drivers/vfio/pci/vfio_pci_private.h | 7 - drivers/vfio/platform/vfio_platform_common.c | 86 ++-- drivers/vfio/platform/vfio_platform_private.h | 1 - drivers/vfio/vfio.c | 149 +- include/linux/mdev.h | 9 +- include/linux/vfio.h | 26 +- samples/vfio-mdev/mbochs.c| 16 +- samples/vfio-mdev/mdpy.c | 40 +- samples/vfio-mdev/mtty.c | 40 +- 18 files changed, 439 insertions(+), 622 deletions(-) -- 2.32.0
[PATCH 02/13] vfio: Introduce a vfio_uninit_group_dev() API call
From: Max Gurtovoy This pairs with vfio_init_group_dev() and allows undoing any state that is stored in the vfio_device unrelated to registration. Add appropriately placed calls to all the drivers. The following patch will use this to add pre-registration state for the device set. Signed-off-by: Max Gurtovoy Signed-off-by: Jason Gunthorpe --- Documentation/driver-api/vfio.rst| 4 ++- drivers/vfio/fsl-mc/vfio_fsl_mc.c| 6 +++-- drivers/vfio/mdev/vfio_mdev.c| 13 +++--- drivers/vfio/pci/vfio_pci.c | 6 +++-- drivers/vfio/platform/vfio_platform_common.c | 7 +++-- drivers/vfio/vfio.c | 5 include/linux/vfio.h | 1 + samples/vfio-mdev/mbochs.c | 2 ++ samples/vfio-mdev/mdpy.c | 25 ++ samples/vfio-mdev/mtty.c | 27 10 files changed, 64 insertions(+), 32 deletions(-) diff --git a/Documentation/driver-api/vfio.rst b/Documentation/driver-api/vfio.rst index 606eed8823ceab..c663b6f978255b 100644 --- a/Documentation/driver-api/vfio.rst +++ b/Documentation/driver-api/vfio.rst @@ -255,11 +255,13 @@ vfio_unregister_group_dev() respectively:: void vfio_init_group_dev(struct vfio_device *device, struct device *dev, const struct vfio_device_ops *ops); + void vfio_uninit_group_dev(struct vfio_device *device); int vfio_register_group_dev(struct vfio_device *device); void vfio_unregister_group_dev(struct vfio_device *device); The driver should embed the vfio_device in its own structure and call -vfio_init_group_dev() to pre-configure it before going to registration. +vfio_init_group_dev() to pre-configure it before going to registration +and call vfio_uninit_group_dev() after completing the un-registration. vfio_register_group_dev() indicates to the core to begin tracking the iommu_group of the specified dev and register the dev as owned by a VFIO bus driver. Once vfio_register_group_dev() returns it is possible for userspace to diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c index 90cad109583b80..3d2be06e1bc146 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c @@ -627,7 +627,7 @@ static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) ret = vfio_fsl_mc_reflck_attach(vdev); if (ret) - goto out_kfree; + goto out_uninit; ret = vfio_fsl_mc_init_device(vdev); if (ret) @@ -657,7 +657,8 @@ static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) vfio_fsl_uninit_device(vdev); out_reflck: vfio_fsl_mc_reflck_put(vdev->reflck); -out_kfree: +out_uninit: + vfio_uninit_group_dev(>vdev); kfree(vdev); out_group_put: vfio_iommu_group_put(group, dev); @@ -674,6 +675,7 @@ static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev) dprc_remove_devices(mc_dev, NULL, 0); vfio_fsl_uninit_device(vdev); + vfio_uninit_group_dev(>vdev); vfio_fsl_mc_reflck_put(vdev->reflck); kfree(vdev); diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c index 39ef7489fe4719..a5c77ccb24f70a 100644 --- a/drivers/vfio/mdev/vfio_mdev.c +++ b/drivers/vfio/mdev/vfio_mdev.c @@ -120,12 +120,16 @@ static int vfio_mdev_probe(struct mdev_device *mdev) vfio_init_group_dev(vdev, >dev, _mdev_dev_ops); ret = vfio_register_group_dev(vdev); - if (ret) { - kfree(vdev); - return ret; - } + if (ret) + goto out_uninit; + dev_set_drvdata(>dev, vdev); return 0; + +out_uninit: + vfio_uninit_group_dev(vdev); + kfree(vdev); + return ret; } static void vfio_mdev_remove(struct mdev_device *mdev) @@ -133,6 +137,7 @@ static void vfio_mdev_remove(struct mdev_device *mdev) struct vfio_device *vdev = dev_get_drvdata(>dev); vfio_unregister_group_dev(vdev); + vfio_uninit_group_dev(vdev); kfree(vdev); } diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 318864d5283782..fab3715d60d4ba 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -2022,7 +2022,7 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ret = vfio_pci_reflck_attach(vdev); if (ret) - goto out_free; + goto out_uninit; ret = vfio_pci_vf_init(vdev); if (ret) goto out_reflck; @@ -2059,7 +2059,8 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) vfio_pci_vf_uninit(vdev); out_reflck: vfio_pci_reflck_put(vdev->reflck); -out_free: +out_uninit: + vfio_uninit_group_dev(>vdev); kfree(vdev->pm_save);
Re: [PATCH 21/47] drm/i915/guc: Ensure G2H response has space in buffer
On 7/14/2021 17:06, Matthew Brost wrote: On Tue, Jul 13, 2021 at 11:36:05AM -0700, John Harrison wrote: On 6/24/2021 00:04, Matthew Brost wrote: Ensure G2H response has space in the buffer before sending H2G CTB as the GuC can't handle any backpressure on the G2H interface. Signed-off-by: John Harrison Signed-off-by: Matthew Brost --- drivers/gpu/drm/i915/gt/uc/intel_guc.h| 13 +++- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 76 +++ drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h | 4 +- drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 4 + .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 13 ++-- 5 files changed, 87 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index b43ec56986b5..24e7a924134e 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -95,11 +95,17 @@ inline int intel_guc_send(struct intel_guc *guc, const u32 *action, u32 len) } #define INTEL_GUC_SEND_NBBIT(31) +#define INTEL_GUC_SEND_G2H_DW_SHIFT0 +#define INTEL_GUC_SEND_G2H_DW_MASK (0xff << INTEL_GUC_SEND_G2H_DW_SHIFT) +#define MAKE_SEND_FLAGS(len) \ + ({GEM_BUG_ON(!FIELD_FIT(INTEL_GUC_SEND_G2H_DW_MASK, len)); \ + (FIELD_PREP(INTEL_GUC_SEND_G2H_DW_MASK, len) | INTEL_GUC_SEND_NB);}) static -inline int intel_guc_send_nb(struct intel_guc *guc, const u32 *action, u32 len) +inline int intel_guc_send_nb(struct intel_guc *guc, const u32 *action, u32 len, +u32 g2h_len_dw) { return intel_guc_ct_send(>ct, action, len, NULL, 0, -INTEL_GUC_SEND_NB); +MAKE_SEND_FLAGS(g2h_len_dw)); } static inline int @@ -113,6 +119,7 @@ intel_guc_send_and_receive(struct intel_guc *guc, const u32 *action, u32 len, static inline int intel_guc_send_busy_loop(struct intel_guc* guc, const u32 *action, u32 len, + u32 g2h_len_dw, bool loop) { int err; @@ -121,7 +128,7 @@ static inline int intel_guc_send_busy_loop(struct intel_guc* guc, might_sleep_if(loop && (!in_atomic() && !irqs_disabled())); retry: - err = intel_guc_send_nb(guc, action, len); + err = intel_guc_send_nb(guc, action, len, g2h_len_dw); if (unlikely(err == -EBUSY && loop)) { if (likely(!in_atomic() && !irqs_disabled())) cond_resched(); diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index 7491f041859e..a60970e85635 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -73,6 +73,7 @@ static inline struct drm_device *ct_to_drm(struct intel_guc_ct *ct) #define CTB_DESC_SIZEALIGN(sizeof(struct guc_ct_buffer_desc), SZ_2K) #define CTB_H2G_BUFFER_SIZE (SZ_4K) #define CTB_G2H_BUFFER_SIZE (4 * CTB_H2G_BUFFER_SIZE) +#define G2H_ROOM_BUFFER_SIZE (PAGE_SIZE) Any particular reason why PAGE_SIZE instead of SZ_4K? I'm not seeing anything in the code that is actually related to page sizes. Seems like '(CTB_G2H_BUFFER_SIZE / 4)' would be a more correct way to express it. Unless I'm missing something about how it's used? Yes, CTB_G2H_BUFFER_SIZE / 4 is better. Matt Okay. With that changed: Reviewed-by: John Harrison John. struct ct_request { struct list_head link; @@ -129,23 +130,27 @@ static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc) static void guc_ct_buffer_reset(struct intel_guc_ct_buffer *ctb) { + u32 space; + ctb->broken = false; ctb->tail = 0; ctb->head = 0; - ctb->space = CIRC_SPACE(ctb->tail, ctb->head, ctb->size); + space = CIRC_SPACE(ctb->tail, ctb->head, ctb->size) - ctb->resv_space; + atomic_set(>space, space); guc_ct_buffer_desc_init(ctb->desc); } static void guc_ct_buffer_init(struct intel_guc_ct_buffer *ctb, struct guc_ct_buffer_desc *desc, - u32 *cmds, u32 size_in_bytes) + u32 *cmds, u32 size_in_bytes, u32 resv_space) { GEM_BUG_ON(size_in_bytes % 4); ctb->desc = desc; ctb->cmds = cmds; ctb->size = size_in_bytes / 4; + ctb->resv_space = resv_space / 4; guc_ct_buffer_reset(ctb); } @@ -226,6 +231,7 @@ int intel_guc_ct_init(struct intel_guc_ct *ct) struct guc_ct_buffer_desc *desc; u32 blob_size; u32 cmds_size; + u32 resv_space; void *blob; u32 *cmds; int err; @@ -250,19 +256,23 @@ int intel_guc_ct_init(struct intel_guc_ct *ct) desc = blob; cmds = blob + 2 * CTB_DESC_SIZE; cmds_size =
Re: [PATCH 20/47] drm/i915/guc: Disable semaphores when using GuC scheduling
On Fri, Jul 09, 2021 at 04:53:37PM -0700, John Harrison wrote: > On 6/24/2021 00:04, Matthew Brost wrote: > > Semaphores are an optimization and not required for basic GuC submission > > to work properly. Disable until we have time to do the implementation to > > enable semaphores and tune them for performance. Also long direction is > > just to delete semaphores from the i915 so another reason to not enable > > these for GuC submission. > > > > v2: Reword commit message > > > > Cc: John Harrison > > Signed-off-by: Matthew Brost > I think the commit description does not really match the patch content. The > description is valid but the 'disable' is done by simply not setting the > enable flag (done in the execlist back end and presumably not done in the > GuC back end). However, what the patch is actually doing seems to be fixing > bugs with the 'are semaphores enabled' mechanism. I.e. correcting pieces of > code that used semaphores without checking if they are enabled. And > presumably this would be broken if someone tried to disable semaphores in > execlist mode for any reason? > > So I think keeping the existing comment text is fine but something should be > added to explain the actual changes. > Yes, commit is wrong. This more or less bug fix to the existing code. Will update. Matt > John. > > > > --- > > drivers/gpu/drm/i915/gem/i915_gem_context.c | 6 -- > > 1 file changed, 4 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c > > b/drivers/gpu/drm/i915/gem/i915_gem_context.c > > index 7720b8c22c81..5c07e6abf16a 100644 > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c > > @@ -230,7 +230,8 @@ static void intel_context_set_gem(struct intel_context > > *ce, > > ce->timeline = intel_timeline_get(ctx->timeline); > > if (ctx->sched.priority >= I915_PRIORITY_NORMAL && > > - intel_engine_has_timeslices(ce->engine)) > > + intel_engine_has_timeslices(ce->engine) && > > + intel_engine_has_semaphores(ce->engine)) > > __set_bit(CONTEXT_USE_SEMAPHORES, >flags); > > intel_context_set_watchdog_us(ce, ctx->watchdog.timeout_us); > > @@ -1938,7 +1939,8 @@ static int __apply_priority(struct intel_context *ce, > > void *arg) > > if (!intel_engine_has_timeslices(ce->engine)) > > return 0; > > - if (ctx->sched.priority >= I915_PRIORITY_NORMAL) > > + if (ctx->sched.priority >= I915_PRIORITY_NORMAL && > > + intel_engine_has_semaphores(ce->engine)) > > intel_context_set_use_semaphores(ce); > > else > > intel_context_clear_use_semaphores(ce); >
Re: [PATCH 21/47] drm/i915/guc: Ensure G2H response has space in buffer
On Tue, Jul 13, 2021 at 11:36:05AM -0700, John Harrison wrote: > On 6/24/2021 00:04, Matthew Brost wrote: > > Ensure G2H response has space in the buffer before sending H2G CTB as > > the GuC can't handle any backpressure on the G2H interface. > > > > Signed-off-by: John Harrison > > Signed-off-by: Matthew Brost > > --- > > drivers/gpu/drm/i915/gt/uc/intel_guc.h| 13 +++- > > drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 76 +++ > > drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h | 4 +- > > drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 4 + > > .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 13 ++-- > > 5 files changed, 87 insertions(+), 23 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h > > b/drivers/gpu/drm/i915/gt/uc/intel_guc.h > > index b43ec56986b5..24e7a924134e 100644 > > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h > > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h > > @@ -95,11 +95,17 @@ inline int intel_guc_send(struct intel_guc *guc, const > > u32 *action, u32 len) > > } > > #define INTEL_GUC_SEND_NB BIT(31) > > +#define INTEL_GUC_SEND_G2H_DW_SHIFT0 > > +#define INTEL_GUC_SEND_G2H_DW_MASK (0xff << INTEL_GUC_SEND_G2H_DW_SHIFT) > > +#define MAKE_SEND_FLAGS(len) \ > > + ({GEM_BUG_ON(!FIELD_FIT(INTEL_GUC_SEND_G2H_DW_MASK, len)); \ > > + (FIELD_PREP(INTEL_GUC_SEND_G2H_DW_MASK, len) | INTEL_GUC_SEND_NB);}) > > static > > -inline int intel_guc_send_nb(struct intel_guc *guc, const u32 *action, u32 > > len) > > +inline int intel_guc_send_nb(struct intel_guc *guc, const u32 *action, u32 > > len, > > +u32 g2h_len_dw) > > { > > return intel_guc_ct_send(>ct, action, len, NULL, 0, > > -INTEL_GUC_SEND_NB); > > +MAKE_SEND_FLAGS(g2h_len_dw)); > > } > > static inline int > > @@ -113,6 +119,7 @@ intel_guc_send_and_receive(struct intel_guc *guc, const > > u32 *action, u32 len, > > static inline int intel_guc_send_busy_loop(struct intel_guc* guc, > >const u32 *action, > >u32 len, > > + u32 g2h_len_dw, > >bool loop) > > { > > int err; > > @@ -121,7 +128,7 @@ static inline int intel_guc_send_busy_loop(struct > > intel_guc* guc, > > might_sleep_if(loop && (!in_atomic() && !irqs_disabled())); > > retry: > > - err = intel_guc_send_nb(guc, action, len); > > + err = intel_guc_send_nb(guc, action, len, g2h_len_dw); > > if (unlikely(err == -EBUSY && loop)) { > > if (likely(!in_atomic() && !irqs_disabled())) > > cond_resched(); > > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c > > b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c > > index 7491f041859e..a60970e85635 100644 > > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c > > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c > > @@ -73,6 +73,7 @@ static inline struct drm_device *ct_to_drm(struct > > intel_guc_ct *ct) > > #define CTB_DESC_SIZE ALIGN(sizeof(struct > > guc_ct_buffer_desc), SZ_2K) > > #define CTB_H2G_BUFFER_SIZE (SZ_4K) > > #define CTB_G2H_BUFFER_SIZE (4 * CTB_H2G_BUFFER_SIZE) > > +#define G2H_ROOM_BUFFER_SIZE (PAGE_SIZE) > Any particular reason why PAGE_SIZE instead of SZ_4K? I'm not seeing > anything in the code that is actually related to page sizes. Seems like > '(CTB_G2H_BUFFER_SIZE / 4)' would be a more correct way to express it. > Unless I'm missing something about how it's used? > Yes, CTB_G2H_BUFFER_SIZE / 4 is better. Matt > John. > > > > struct ct_request { > > struct list_head link; > > @@ -129,23 +130,27 @@ static void guc_ct_buffer_desc_init(struct > > guc_ct_buffer_desc *desc) > > static void guc_ct_buffer_reset(struct intel_guc_ct_buffer *ctb) > > { > > + u32 space; > > + > > ctb->broken = false; > > ctb->tail = 0; > > ctb->head = 0; > > - ctb->space = CIRC_SPACE(ctb->tail, ctb->head, ctb->size); > > + space = CIRC_SPACE(ctb->tail, ctb->head, ctb->size) - ctb->resv_space; > > + atomic_set(>space, space); > > guc_ct_buffer_desc_init(ctb->desc); > > } > > static void guc_ct_buffer_init(struct intel_guc_ct_buffer *ctb, > >struct guc_ct_buffer_desc *desc, > > - u32 *cmds, u32 size_in_bytes) > > + u32 *cmds, u32 size_in_bytes, u32 resv_space) > > { > > GEM_BUG_ON(size_in_bytes % 4); > > ctb->desc = desc; > > ctb->cmds = cmds; > > ctb->size = size_in_bytes / 4; > > + ctb->resv_space = resv_space / 4; > > guc_ct_buffer_reset(ctb); > > } > > @@ -226,6 +231,7 @@ int intel_guc_ct_init(struct intel_guc_ct *ct) > > struct guc_ct_buffer_desc *desc; > > u32 blob_size; > > u32 cmds_size; > > + u32 resv_space; > > void *blob; > > u32 *cmds; > > int err; > > @@
Re: [PATCH 23/47] drm/i915/guc: Update GuC debugfs to support new GuC
On Tue, Jul 13, 2021 at 10:51:35AM +0200, Michal Wajdeczko wrote: > > > On 24.06.2021 09:04, Matthew Brost wrote: > > Update GuC debugfs to support the new GuC structures. > > > > Signed-off-by: John Harrison > > Signed-off-by: Matthew Brost > > --- > > drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 22 > > drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h | 3 ++ > > .../gpu/drm/i915/gt/uc/intel_guc_debugfs.c| 23 +++- > > .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 52 +++ > > .../gpu/drm/i915/gt/uc/intel_guc_submission.h | 4 ++ > > drivers/gpu/drm/i915/i915_debugfs.c | 1 + > > 6 files changed, 104 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c > > b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c > > index e0f92e28350c..4ed074df88e5 100644 > > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c > > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c > > @@ -1135,3 +1135,25 @@ void intel_guc_ct_event_handler(struct intel_guc_ct > > *ct) > > > > ct_try_receive_message(ct); > > } > > + > > +void intel_guc_log_ct_info(struct intel_guc_ct *ct, > > this is not "guc log" function, it is "guc ct" one, so: > > void intel_guc_ct_print_info(struct intel_guc_ct *ct, > Sure. > > + struct drm_printer *p) > > +{ > > + if (!ct->enabled) { > > + drm_puts(p, "CT disabled\n"); > > nit: maybe > > drm_puts(p, "CT %s\n", enableddisabled(false)); > Sure. > > + return; > > + } > > + > > + drm_printf(p, "H2G Space: %u\n", > > + atomic_read(>ctbs.send.space) * 4); > > don't you want to print size ? > or GGTT offset ? > I don't think so. > > + drm_printf(p, "Head: %u\n", > > + ct->ctbs.send.desc->head); > > + drm_printf(p, "Tail: %u\n", > > + ct->ctbs.send.desc->tail); > > + drm_printf(p, "G2H Space: %u\n", > > + atomic_read(>ctbs.recv.space) * 4); > > + drm_printf(p, "Head: %u\n", > > + ct->ctbs.recv.desc->head); > > + drm_printf(p, "Tail: %u\n", > > + ct->ctbs.recv.desc->tail); > > hmm, what about adding helper: > > static void dump_ctb(struct intel_guc_ct_buffer *ctb, *p) > { > drm_printf(p, "Size: %u\n", ctb->size); > drm_printf(p, "Space: %u\n", atomic_read(>space) * 4); > drm_printf(p, "Head: %u\n", ctb->desc->head); > drm_printf(p, "Tail: %u\n", ctb->desc->tail); > } > > and then: > > drm_printf(p, "H2G:\n"); > dump_ctb(>ctbs.send, p); > drm_printf(p, "G2H:\n"); > dump_ctb(>ctbs.recv, p); > > or > > dump_ctb(>ctbs.send, "H2G", p); > dump_ctb(>ctbs.recv, "G2H", p); > > Seems unnecessary. > > +} > > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h > > b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h > > index ab1b79ab960b..f62eb06b32fc 100644 > > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h > > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h > > @@ -16,6 +16,7 @@ > > > > struct i915_vma; > > struct intel_guc; > > +struct drm_printer; > > > > /** > > * DOC: Command Transport (CT). > > @@ -106,4 +107,6 @@ int intel_guc_ct_send(struct intel_guc_ct *ct, const > > u32 *action, u32 len, > > u32 *response_buf, u32 response_buf_size, u32 flags); > > void intel_guc_ct_event_handler(struct intel_guc_ct *ct); > > > > +void intel_guc_log_ct_info(struct intel_guc_ct *ct, struct drm_printer *p); > > + > > #endif /* _INTEL_GUC_CT_H_ */ > > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c > > b/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c > > index fe7cb7b29a1e..62b9ce0fafaa 100644 > > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c > > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c > > @@ -9,6 +9,8 @@ > > #include "intel_guc.h" > > #include "intel_guc_debugfs.h" > > #include "intel_guc_log_debugfs.h" > > +#include "gt/uc/intel_guc_ct.h" > > +#include "gt/uc/intel_guc_submission.h" > > > > static int guc_info_show(struct seq_file *m, void *data) > > { > > @@ -22,16 +24,35 @@ static int guc_info_show(struct seq_file *m, void *data) > > drm_puts(, "\n"); > > intel_guc_log_info(>log, ); > > > > - /* Add more as required ... */ > > + if (!intel_guc_submission_is_used(guc)) > > + return 0; > > + > > + intel_guc_log_ct_info(>ct, ); > > + intel_guc_log_submission_info(guc, ); > > > > return 0; > > } > > DEFINE_GT_DEBUGFS_ATTRIBUTE(guc_info); > > > > +static int guc_registered_contexts_show(struct seq_file *m, void *data) > > +{ > > + struct intel_guc *guc = m->private; > > + struct drm_printer p = drm_seq_file_printer(m); > > + > > + if (!intel_guc_submission_is_used(guc)) > > + return -ENODEV; > > + > > + intel_guc_log_context_info(guc, ); > > + > > + return 0; > > +} > > +DEFINE_GT_DEBUGFS_ATTRIBUTE(guc_registered_contexts); > > + > > void intel_guc_debugfs_register(struct intel_guc *guc, struct
Re: [RFC PATCH 12/17] dt-bindings: display: bridge: samsung,mipi-dsim: Add i.MX8MM support
On Sun, Jul 04, 2021 at 02:32:25PM +0530, Jagan Teki wrote: > Samsung MIPI DSIM bridge can also be found in i.MX8MM SoC. > > Add dt-bingings for it. > > Cc: Rob Herring > Signed-off-by: Jagan Teki > --- > .../display/bridge/samsung,mipi-dsim.yaml | 84 ++- > 1 file changed, 83 insertions(+), 1 deletion(-) > > diff --git > a/Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml > b/Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml > index b2970734ffd7..bd12d5706291 100644 > --- a/Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml > +++ b/Documentation/devicetree/bindings/display/bridge/samsung,mipi-dsim.yaml > @@ -26,6 +26,7 @@ properties: >- samsung,exynos5410-mipi-dsi >- samsung,exynos5422-mipi-dsi >- samsung,exynos5433-mipi-dsi > + - fsl,imx8mm-mipi-dsim > >reg: > maxItems: 1 > @@ -39,6 +40,10 @@ properties: >'#size-cells': > const: 0 > > + assigned-clock-parents: true > + assigned-clock-rates: true > + assigned-clocks: true You don't need these. They are always allowed if 'clocks' is present. > + >clocks: > minItems: 2 > maxItems: 5 > @@ -102,7 +107,7 @@ properties: > properties: >endpoint@0: > $ref: /schemas/graph.yaml#/properties/endpoint > -description: sub-node describing the input from MIC > +description: sub-node describing the input from MIC or LCDIF > > unevaluatedProperties: false > > @@ -128,6 +133,30 @@ required: > > allOf: >- $ref: ../dsi-controller.yaml# > + - if: > + properties: > +compatible: > + contains: > +const: fsl,imx8mm-mipi-dsim > + > +then: > + properties: > +clocks: > + minItems: 2 > + > +clock-names: > + items: > +- const: bus_clk > +- const: sclk_mipi > + > +ports: > + required: > +- port@0 > +- port@1 > + > + required: > +- ports > + >- if: >properties: > compatible: > @@ -221,6 +250,59 @@ additionalProperties: >type: object > > examples: > + - | > +#include > +#include > +#include > +#include > + > +dsi@32e1 { > + compatible = "fsl,imx8mm-mipi-dsim"; > + reg = <0x32e1 0x400>; > + clocks = < IMX8MM_CLK_DSI_CORE>, > +< IMX8MM_CLK_DSI_PHY_REF>; > + clock-names = "bus_clk", "sclk_mipi"; > + assigned-clocks = < IMX8MM_CLK_DSI_CORE>, > + < IMX8MM_VIDEO_PLL1_OUT>, > + < IMX8MM_CLK_DSI_PHY_REF>; > + assigned-clock-parents = < IMX8MM_SYS_PLL1_266M>, > + < IMX8MM_VIDEO_PLL1_BYPASS>, > + < IMX8MM_VIDEO_PLL1_OUT>; > + assigned-clock-rates = <26600>, <59400>, <2700>; > + interrupts = ; > + phys = <_phy 0>; > + phy-names = "dsim"; > + power-domains = <_blk_ctl IMX8MM_BLK_CTL_PD_DISPMIX_MIPI_DSI>; > + samsung,burst-clock-frequency = <89100>; > + samsung,esc-clock-frequency = <5400>; > + samsung,pll-clock-frequency = <2700>; > + status = "disabled"; > + > + ports { > + #address-cells = <1>; > + #size-cells = <0>; > + > + port@0 { > + reg = <0>; > + #address-cells = <1>; > + #size-cells = <0>; > + > + dsi_in_lcdif: endpoint@0 { > +reg = <0>; > +remote-endpoint = <_out_dsi>; > + }; > + }; > + > + port@1 { > + reg = <1>; > + > + dsi_out_panel: endpoint { > +remote-endpoint = <_in_dsi>; > + }; > + }; > + }; > +}; > + >- | > #include > #include > -- > 2.25.1 > >
[PATCH 2/2 v4] drm/panel: ws2401: Add driver for WideChips WS2401
This adds a driver for panels based on the WideChips WS2401 display controller. This display controller is used in the Samsung LMS380KF01 display found in the Samsung GT-I8160 (Codina) mobile phone and possibly others. As is common with Samsung displays manufacturer commands are necessary to configure the display to a working state. The display optionally supports internal backlight control, but can also use an external backlight. This driver re-uses the DBI infrastructure to communicate with the display. Cc: phone-de...@vger.kernel.org Cc: Douglas Anderson Reviewed-by: Noralf Trønnes Reviewed-by: Douglas Anderson Signed-off-by: Linus Walleij --- ChangeLog v3->v4: - Add more talkative Kconfig telling which mobile phone has this. - Make sure to turn off the internal backlight totally if requested. - Alter the logic so that we assign the backlight handle to panel->backlight directly and save some code. ChangeLog v2->v3: - Drop the ws2401_command() macro - we enhanced the mipi_dbi_command() to print errors for everyone instead. - Read out MTP properly (used wrong variables) - Register internal backlight if and only if the panel->backlight field is NULL after trying to look up external backlight. ChangeLog v1->v2: - Disable the backlight in ->unprepare() before entering sleep mode. - If we are not using internal backlight, close the L2 access after initializing. - Depromote some talkative dev_info()s to dev_dbg(). - Power up and read the MTP values before we register the display. This works fine and is probably how MTP is supposed to work. - Fix the set-up of gamma values, this was found in the GT-I8160 HD kernel tree. - Bail out properly if drm_panel_of_backlight() returns -EDEFER_PROBE. - Drop OF from dependencies since drm_panel_of_backlight() has static inline stubs in the header file. - Sort MAINTAINERS properly. - Alphabetize includes - Use format specifier %#02x so we get 0x... output in debug - Drop unnecessary braces around if () in debug macro - Drop unused include. --- MAINTAINERS | 7 + drivers/gpu/drm/panel/Kconfig | 10 + drivers/gpu/drm/panel/Makefile| 1 + .../gpu/drm/panel/panel-widechips-ws2401.c| 441 ++ 4 files changed, 459 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-widechips-ws2401.c diff --git a/MAINTAINERS b/MAINTAINERS index a61f4f3b78a9..a38ed6e5efd4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6060,6 +6060,13 @@ T: git git://people.freedesktop.org/~sroland/linux F: drivers/gpu/drm/vmwgfx/ F: include/uapi/drm/vmwgfx_drm.h +DRM DRIVER FOR WIDECHIPS WS2401 PANELS +M: Linus Walleij +S: Maintained +T: git git://anongit.freedesktop.org/drm/drm-misc +F: Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml +F: drivers/gpu/drm/panel/panel-widechips-ws2401.c + DRM DRIVERS M: David Airlie M: Daniel Vetter diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index ef87d92cdf49..0c880553ce64 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -553,6 +553,16 @@ config DRM_PANEL_VISIONOX_RM69299 Say Y here if you want to enable support for Visionox RM69299 DSI Video Mode panel. +config DRM_PANEL_WIDECHIPS_WS2401 + tristate "Widechips WS2401 DPI panel driver" + depends on SPI && GPIOLIB + depends on BACKLIGHT_CLASS_DEVICE + select DRM_MIPI_DBI + help + Say Y here if you want to enable support for the Widechips WS2401 DPI + 480x800 display controller used in panels such as Samsung LMS380KF01. + This display is used in the Samsung Galaxy Ace 2 GT-I8160 (Codina). + config DRM_PANEL_XINPENG_XPP055C272 tristate "Xinpeng XPP055C272 panel driver" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index cae4d976c069..d94c27df17aa 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -58,4 +58,5 @@ obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o obj-$(CONFIG_DRM_PANEL_VISIONOX_RM69299) += panel-visionox-rm69299.o +obj-$(CONFIG_DRM_PANEL_WIDECHIPS_WS2401) += panel-widechips-ws2401.o obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o diff --git a/drivers/gpu/drm/panel/panel-widechips-ws2401.c b/drivers/gpu/drm/panel/panel-widechips-ws2401.c new file mode 100644 index ..8bc976f54b80 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-widechips-ws2401.c @@ -0,0 +1,441 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Panel driver for the WideChips WS2401 480x800 DPI RGB panel, used in + * the Samsung Mobile Display (SMD) LMS380KF01. + * Found in the Samsung Galaxy Ace 2 GT-I8160 mobile phone. + * Linus Walleij + *
[PATCH 1/2 v4] drm/panel: Add DT bindings for Samsung LMS380KF01
This adds device tree bindings for the Samsung Mobile Displays LMS380KF01 RGB DPI display panel. Cc: devicet...@vger.kernel.org Cc: phone-de...@vger.kernel.org Cc: Noralf Trønnes Reviewed-by: Sam Ravnborg Reviewed-by: Douglas Anderson Reviewed-by: Rob Herring Signed-off-by: Linus Walleij --- ChangeLog v3->v4: - Collect a few Reviewed-by's - Mention that the node must be an SPI child. - Indent example by 4 spaces. - Resend with the driver updates. ChangeLog v2->v3: - No changes just resending with the series. ChangeLog v1->v2: - Expect SPI bindings to be pulled in for the client and state spi-cpha: true etc. - Make port a required node. - Update the example to use a proper SPI controller (spi-gpio) so we get full validation of the example. --- .../display/panel/samsung,lms380kf01.yaml | 99 +++ 1 file changed, 99 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml diff --git a/Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml b/Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml new file mode 100644 index ..251f0c7115aa --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml @@ -0,0 +1,99 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/samsung,lms380kf01.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung LMS380KF01 display panel + +description: The LMS380KF01 is a 480x800 DPI display panel from Samsung Mobile + Displays (SMD) utilizing the WideChips WS2401 display controller. It can be + used with internal or external backlight control. + The panel must obey the rules for a SPI slave device as specified in + spi/spi-controller.yaml + +maintainers: + - Linus Walleij + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: +const: samsung,lms380kf01 + + reg: true + + interrupts: +description: provides an optional ESD (electrostatic discharge) + interrupt that signals abnormalities in the display hardware. + This can also be raised for other reasons like erroneous + configuration. +maxItems: 1 + + reset-gpios: true + + vci-supply: +description: regulator that supplies the VCI analog voltage + usually around 3.0 V + + vccio-supply: +description: regulator that supplies the VCCIO voltage usually + around 1.8 V + + backlight: true + + spi-cpha: true + + spi-cpol: true + + spi-max-frequency: +maximum: 120 + + port: true + +required: + - compatible + - reg + - spi-cpha + - spi-cpol + - port + +additionalProperties: false + +examples: + - | +#include +#include + +spi { +compatible = "spi-gpio"; +sck-gpios = < 0 GPIO_ACTIVE_HIGH>; +miso-gpios = < 1 GPIO_ACTIVE_HIGH>; +mosi-gpios = < 2 GPIO_ACTIVE_HIGH>; +cs-gpios = < 3 GPIO_ACTIVE_HIGH>; +num-chipselects = <1>; +#address-cells = <1>; +#size-cells = <0>; + +panel@0 { +compatible = "samsung,lms380kf01"; +spi-max-frequency = <120>; +spi-cpha; +spi-cpol; +reg = <0>; +vci-supply = <_3v0_reg>; +vccio-supply = <_1v8_reg>; +reset-gpios = < 4 GPIO_ACTIVE_LOW>; +interrupt-parent = <>; +interrupts = <5 IRQ_TYPE_EDGE_RISING>; + +port { +panel_in: endpoint { +remote-endpoint = <_out>; +}; +}; +}; +}; + +... -- 2.31.1
Re: [Freedreno] [PATCH] drm/msm/dp: Initialize dp->aux->drm_dev before registration
On 2021-07-14 08:28, Sean Paul wrote: From: Sean Paul Avoids the following WARN: [3.009556] [ cut here ] [3.014306] WARNING: CPU: 7 PID: 109 at drivers/gpu/drm/drm_dp_helper.c:1796 drm_dp_aux_register+0xa4/0xac [3.024209] Modules linked in: [3.027351] CPU: 7 PID: 109 Comm: kworker/7:8 Not tainted 5.10.47 #69 [3.033958] Hardware name: Google Lazor (rev1 - 2) (DT) [3.039323] Workqueue: events deferred_probe_work_func [3.044596] pstate: 60c9 (nZCv daif +PAN +UAO -TCO BTYPE=--) [3.050761] pc : drm_dp_aux_register+0xa4/0xac [3.055329] lr : dp_aux_register+0x40/0x88 [3.059538] sp : ffc010ad3920 [3.062948] x29: ffc010ad3920 x28: ffa64196ac70 [3.067239] mmc1: Command Queue Engine enabled [3.068406] x27: ffa64196ac68 x26: 0001 [3.068407] x25: 0002 x24: 0060 [3.068409] x23: ffa642ab3400 x22: ffe126c10e5b [3.068410] x21: ffa641dc3188 x20: ffa641963c10 [3.068412] x19: ffa642aba910 x18: 0a00 [3.068414] x17: 00476f8e002a x16: 00b8 [3.073008] mmc1: new HS400 Enhanced strobe MMC card at address 0001 [3.078448] x15: x14: [3.078450] x13: 0030 x12: 0030 [3.078452] x11: 0101010101010101 x10: ffe12647a914 [3.078453] x9 : ffe12647a8cc x8 : [3.084452] mmcblk1: mmc1:0001 DA4032 29.1 GiB [3.089372] [3.089372] x7 : 6c6064717372fefe x6 : ffa642b11494 [3.089374] x5 : x4 : 6d006c657869 [3.089375] x3 : 6c657869 x2 : 000c [3.089376] x1 : ffe126c3ae3c x0 : ffa642aba910 [3.089381] Call trace: [3.094931] mmcblk1boot0: mmc1:0001 DA4032 partition 1 4.00 MiB [3.100291] drm_dp_aux_register+0xa4/0xac [3.100292] dp_aux_register+0x40/0x88 [3.100294] dp_display_bind+0x64/0xcc [3.100295] component_bind_all+0xdc/0x210 [3.100298] msm_drm_bind+0x1e8/0x5d4 [3.100301] try_to_bring_up_master+0x168/0x1b0 [3.105861] mmcblk1boot1: mmc1:0001 DA4032 partition 2 4.00 MiB [3.112282] __component_add+0xa0/0x158 [3.112283] component_add+0x1c/0x28 [3.112284] dp_display_probe+0x33c/0x380 [3.112286] platform_drv_probe+0x9c/0xbc [3.112287] really_probe+0x140/0x35c [3.112289] driver_probe_device+0x84/0xc0 [3.112292] __device_attach_driver+0x94/0xb0 [3.117967] mmcblk1rpmb: mmc1:0001 DA4032 partition 3 16.0 MiB, chardev (239:0) [3.123201] bus_for_each_drv+0x8c/0xd8 [3.123202] __device_attach+0xc4/0x150 [3.123204] device_initial_probe+0x1c/0x28 [3.123205] bus_probe_device+0x3c/0x9c [3.123206] deferred_probe_work_func+0x90/0xcc [3.123211] process_one_work+0x218/0x3ec [3.131976] mmcblk1: p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 [3.134123] worker_thread+0x288/0x3e8 [3.134124] kthread+0x148/0x1b0 [3.134127] ret_from_fork+0x10/0x30 [3.134128] ---[ end trace cfb9fce3f70f824d ]--- Signed-off-by: Sean Paul It looks like https://github.com/torvalds/linux/commit/6cba3fe433415b2549c909ce72601902c8254a83 is not yet present in the lazor codebase, once it gets backported we will hit the same issue, Hence Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dp/dp_display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 051c1be1de7e..987f9e330138 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -219,6 +219,7 @@ static int dp_display_bind(struct device *dev, struct device *master, goto end; } + dp->aux->drm_dev = drm; rc = dp_aux_register(dp->aux); if (rc) { DRM_ERROR("DRM DP AUX register failed\n");
Re: [PATCH v4 02/18] drm/sched: Barriers are needed for entity->last_scheduled
On 2021-07-13 12:45 p.m., Daniel Vetter wrote: On Tue, Jul 13, 2021 at 6:11 PM Andrey Grodzovsky wrote: On 2021-07-13 5:10 a.m., Daniel Vetter wrote: On Tue, Jul 13, 2021 at 9:25 AM Christian König wrote: Am 13.07.21 um 08:50 schrieb Daniel Vetter: On Tue, Jul 13, 2021 at 8:35 AM Christian König wrote: Am 12.07.21 um 19:53 schrieb Daniel Vetter: It might be good enough on x86 with just READ_ONCE, but the write side should then at least be WRITE_ONCE because x86 has total store order. It's definitely not enough on arm. Fix this proplery, which means - explain the need for the barrier in both places - point at the other side in each comment Also pull out the !sched_list case as the first check, so that the code flow is clearer. While at it sprinkle some comments around because it was very non-obvious to me what's actually going on here and why. Note that we really need full barriers here, at first I thought store-release and load-acquire on ->last_scheduled would be enough, but we actually requiring ordering between that and the queue state. v2: Put smp_rmp() in the right place and fix up comment (Andrey) Signed-off-by: Daniel Vetter Cc: "Christian König" Cc: Steven Price Cc: Daniel Vetter Cc: Andrey Grodzovsky Cc: Lee Jones Cc: Boris Brezillon --- drivers/gpu/drm/scheduler/sched_entity.c | 27 ++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index f7347c284886..89e3f6eaf519 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -439,8 +439,16 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity) dma_fence_set_error(_job->s_fence->finished, -ECANCELED); dma_fence_put(entity->last_scheduled); + entity->last_scheduled = dma_fence_get(_job->s_fence->finished); + /* + * If the queue is empty we allow drm_sched_entity_select_rq() to + * locklessly access ->last_scheduled. This only works if we set the + * pointer before we dequeue and if we a write barrier here. + */ + smp_wmb(); + Again, conceptual those barriers should be part of the spsc_queue container and not externally. That would be extremely unusual api. Let's assume that your queue is very dumb, and protected by a simple lock. That's about the maximum any user could expect. But then you still need barriers here, because linux locks (spinlock, mutex) are defined to be one-way barriers: Stuff that's inside is guaranteed to be done insinde, but stuff outside of the locked region can leak in. They're load-acquire/store-release barriers. So not good enough. You really need to have barriers here, and they really all need to be documented properly. And yes that's a shit-ton of work in drm/sched, because it's full of yolo lockless stuff. The other case you could make is that this works like a wakeup queue, or similar. The rules there are: - wake_up (i.e. pushing something into the queue) is a store-release barrier - the waked up (i.e. popping an entry) is a load acquire barrier Which is obviuosly needed because otherwise you don't have coherency for the data queued up. And again not the barriers you're locking for here. Exactly that was the idea, yes. Either way, we'd still need the comments, because it's still lockless trickery, and every single one of that needs to have a comment on both sides to explain what's going on. Essentially replace spsc_queue with an llist underneath, and that's the amount of barriers a data structure should provide. Anything else is asking your datastructure to paper over bugs in your users. This is similar to how atomic_t is by default completely unordered, and users need to add barriers as needed, with comments. My main problem is as always that kernel atomics work different than userspace atomics. I think this is all to make sure people don't just write lockless algorithms because it's a cool idea, but are forced to think this all through. Which seems to not have happened very consistently for drm/sched, so I guess needs to be fixed. Well at least initially that was all perfectly thought through. The problem is nobody is really maintaining that stuff. I'm definitely not going to hide all that by making the spsc_queue stuff provide random unjustified barriers just because that would paper over drm/sched bugs. We need to fix the actual bugs, and preferrable all of them. I've found a few, but I wasn't involved in drm/sched thus far, so best I can do is discover them as we go. I don't think that those are random unjustified barriers at all and it sounds like you didn't grip what I said here. See the spsc queue must have the following semantics: 1. When you pop a job all changes made before you push the job must be visible. This is the standard barriers that also wake-up queues have, it's just
[pull] amdgpu, amdkfd drm-fixes-5.14
Hi Dave, Daniel, Fixes for 5.14. The big change here is unifying the SMU13 code. This was new code added in 5.14 to support Yellow Carp, but we've since cleaned it up and removed a lot of duplication, so better to merge it now to facilitate any bug fixes in the future that need to go back to this kernel via stable. Only affects Yellow Carp which is new for 5.14 anyway so not much chance for regressions. The rest is just standard bug fixes. The following changes since commit 1e7b5812f4890ad84058bbb6c4a5deddfb2c5b25: Merge tag 'drm-misc-fixes-2021-07-13' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes (2021-07-13 15:15:17 +0200) are available in the Git repository at: https://gitlab.freedesktop.org/agd5f/linux.git tags/amd-drm-fixes-5.14-2021-07-14 for you to fetch changes up to 775da83005cb61d4c213c636df9337da05714ff1: drm/amdgpu: add another Renoir DID (2021-07-14 15:08:55 -0400) amd-drm-fixes-5.14-2021-07-14: amdgpu: - SR-IOV fixes - RAS fixes - eDP fixes - SMU13 code unification to facilitate fixes in the future - Add new renoir DID - Yellow Carp fixes - Beige Goby fixes - Revert a bunch of TLB fixes that caused regressions - Revert an LTTPR display regression amdkfd - Fix VRAM access regression - SVM fixes Aaron Liu (1): drm/amd/pm: Add waiting for response of mode-reset message for yellow carp Chengming Gui (1): drm/amd/pm: Fix BACO state setting for Beige_Goby Dmytro Laktyushkin (1): drm/amd/display: remove faulty assert Emily Deng (1): drm/amdgpu: Correct the irq numbers for virtual crtc Emily.Deng (1): drm/amdgpu: Restore msix after FLR Eric Huang (5): Revert "drm/amdkfd: Add memory sync before TLB flush on unmap" Revert "drm/amdgpu: Fix warning of Function parameter or member not described" Revert "drm/amdkfd: Make TLB flush conditional on mapping" Revert "drm/amdgpu: Add table_freed parameter to amdgpu_vm_bo_update" Revert "drm/amdkfd: Add heavy-weight TLB flush after unmapping" Felix Kuehling (1): drm/amdkfd: Allow CPU access for all VRAM BOs Jingwen Chen (1): drm/amdgpu: SRIOV flr_work should take write_lock Jinzhou Su (1): drm/amdgpu: add another Renoir DID Luben Tuikov (1): drm/amdgpu: Return error if no RAS Nicholas Kazlauskas (1): drm/amd/display: Fix updating infoframe for DCN3.1 eDP Philip Yang (1): drm/amdkfd: handle fault counters on invalid address Wesley Chalmers (1): Revert "drm/amd/display: Always write repeater mode regardless of LTTPR" Xiaomeng Hou (2): drm/amd/pm: drop smu_v13_0_1.c|h files for yellow carp drm/amd/display: update header file name Zhan Liu (1): drm/amdgpu/display - only update eDP's backlight level when necessary drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 22 +- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c| 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c| 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c| 18 + drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c| 49 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h| 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 11 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 2 +- drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 2 +- drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c | 4 +- drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c | 4 +- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 45 +- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 3 +- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 30 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- .../drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c | 4 +- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 8 +- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c | 2 +- .../drm/amd/include/asic_reg/mp/mp_13_0_1_offset.h | 355 -- .../amd/include/asic_reg/mp/mp_13_0_1_sh_mask.h| 531 - drivers/gpu/drm/amd/pm/inc/smu_v13_0.h | 1 + drivers/gpu/drm/amd/pm/inc/smu_v13_0_1.h | 57 --- drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 1 + drivers/gpu/drm/amd/pm/swsmu/smu13/Makefile| 2 +- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 24 + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_1.c | 311 .../gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c | 49 +- 29 files changed, 182 insertions(+), 1372 deletions(-) delete mode 100644 drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_1_offset.h delete mode 100644 drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_1_sh_mask.h delete mode 100644 drivers/gpu/drm/amd/pm/inc/smu_v13_0_1.h delete mode
[tegra-drm:drm/tegra/for-next 9/14] drivers/gpu/drm/tegra/uapi.c:278:5: warning: no previous prototype for 'tegra_drm_ioctl_gem_create'
tree: git://anongit.freedesktop.org/tegra/linux.git drm/tegra/for-next head: b19502d1a683c11f6f2c92ad63c61288b0fbe1a1 commit: cdf631031f3e574b76afed51bda0ccc9d71d4a4e [9/14] drm/tegra: Implement new UAPI config: arm-defconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git remote add tegra-drm git://anongit.freedesktop.org/tegra/linux.git git fetch --no-tags tegra-drm drm/tegra/for-next git checkout cdf631031f3e574b76afed51bda0ccc9d71d4a4e # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/gpu/drm/tegra/uapi.c:278:5: warning: no previous prototype for >> 'tegra_drm_ioctl_gem_create' [-Wmissing-prototypes] 278 | int tegra_drm_ioctl_gem_create(struct drm_device *drm, void *data, | ^~ >> drivers/gpu/drm/tegra/uapi.c:295:5: warning: no previous prototype for >> 'tegra_drm_ioctl_gem_mmap' [-Wmissing-prototypes] 295 | int tegra_drm_ioctl_gem_mmap(struct drm_device *drm, void *data, | ^~~~ vim +/tegra_drm_ioctl_gem_create +278 drivers/gpu/drm/tegra/uapi.c 277 > 278 int tegra_drm_ioctl_gem_create(struct drm_device *drm, void *data, 279 struct drm_file *file) 280 { 281 struct drm_tegra_gem_create *args = data; 282 struct tegra_bo *bo; 283 284 if (args->flags) 285 return -EINVAL; 286 287 bo = tegra_bo_create_with_handle(file, drm, args->size, args->flags, 288 >handle); 289 if (IS_ERR(bo)) 290 return PTR_ERR(bo); 291 292 return 0; 293 } 294 > 295 int tegra_drm_ioctl_gem_mmap(struct drm_device *drm, void *data, --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
Re: [PATCH] drm/msm/dp: Remove unused variable
Quoting Souptick Joarder (2021-07-08 19:48:34) > Kernel test roobot throws below warning -> > > drivers/gpu/drm/msm/dp/dp_display.c:1017:21: > warning: variable 'drm' set but not used [-Wunused-but-set-variable] > > Removed unused variable drm. > > Reported-by: kernel test robot > Signed-off-by: Souptick Joarder > --- Reviewed-by: Stephen Boyd
Re: [PATCH 2/2] drm/i915/gem: Migrate to system at dma-buf attach time (v5)
On Tue, Jul 13, 2021 at 10:23 AM Daniel Vetter wrote: > > On Tue, Jul 13, 2021 at 04:06:13PM +0100, Matthew Auld wrote: > > On Tue, 13 Jul 2021 at 15:44, Daniel Vetter wrote: > > > > > > On Mon, Jul 12, 2021 at 06:12:34PM -0500, Jason Ekstrand wrote: > > > > From: Thomas Hellström > > > > > > > > Until we support p2p dma or as a complement to that, migrate data > > > > to system memory at dma-buf attach time if possible. > > > > > > > > v2: > > > > - Rebase on dynamic exporter. Update the igt_dmabuf_import_same_driver > > > > selftest to migrate if we are LMEM capable. > > > > v3: > > > > - Migrate also in the pin() callback. > > > > v4: > > > > - Migrate in attach > > > > v5: (jason) > > > > - Lock around the migration > > > > > > > > Signed-off-by: Thomas Hellström > > > > Signed-off-by: Michael J. Ruhl > > > > Reported-by: kernel test robot > > > > Signed-off-by: Jason Ekstrand > > > > Reviewed-by: Jason Ekstrand > > > > --- > > > > drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c| 25 ++- > > > > .../drm/i915/gem/selftests/i915_gem_dmabuf.c | 4 ++- > > > > 2 files changed, 27 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c > > > > b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c > > > > index 9a655f69a0671..3163f00554476 100644 > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c > > > > @@ -170,8 +170,31 @@ static int i915_gem_dmabuf_attach(struct dma_buf > > > > *dmabuf, > > > > struct dma_buf_attachment *attach) > > > > { > > > > struct drm_i915_gem_object *obj = dma_buf_to_obj(dmabuf); > > > > + struct i915_gem_ww_ctx ww; > > > > + int err; > > > > + > > > > + for_i915_gem_ww(, err, true) { > > > > + err = i915_gem_object_lock(obj, ); > > > > + if (err) > > > > + continue; > > > > + > > > > + if (!i915_gem_object_can_migrate(obj, INTEL_REGION_SMEM)) > > > > { > > > > + err = -EOPNOTSUPP; > > > > + continue; > > > > + } > > > > + > > > > + err = i915_gem_object_migrate(obj, , > > > > INTEL_REGION_SMEM); > > > > + if (err) > > > > + continue; > > > > > > > > - return i915_gem_object_pin_pages_unlocked(obj); > > > > + err = i915_gem_object_wait_migration(obj, 0); > > > > + if (err) > > > > + continue; > > > > + > > > > + err = i915_gem_object_pin_pages(obj); > > > > + } > > > > + > > > > + return err; > > > > } > > > > > > > > static void i915_gem_dmabuf_detach(struct dma_buf *dmabuf, > > > > diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c > > > > b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c > > > > index 3dc0f8b3cdab0..4f7e77b1c0152 100644 > > > > --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c > > > > +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c > > > > @@ -106,7 +106,9 @@ static int igt_dmabuf_import_same_driver(void *arg) > > > > int err; > > > > > > > > force_different_devices = true; > > > > - obj = i915_gem_object_create_shmem(i915, PAGE_SIZE); > > > > + obj = i915_gem_object_create_lmem(i915, PAGE_SIZE, 0); > > > > > > I'm wondering (and couldn't answer) whether this creates an lmem+smem > > > buffer, since if we create an lmem-only buffer then the migration above > > > should fail. > > > > It's lmem-only, but it's also a kernel internal object, so the > > migration path will still happily migrate it if asked. On the other > > hand if it's a userspace object then we always have to respect the > > placements. > > > > I think for now the only usecase for that is in the selftests. > > Yeah I've read the kerneldoc, it's all nicely documented but feels a bit > dangerous. What I proposed on irc: > - i915_gem_object_migrate does the placement check, i.e. as strict as > can_migrate. > - A new __i915_gem_object_migrate is for selftest that do special stuff. I just sent out a patch which does this except we don't actually need the __ version because there are no self-tests that want to do a dangerous migrate. We could add such a helper later if we needed. > - In the import selftest we check that lmem-only fails (because we can't > pin it into smem) for a non-dynamic importer, but lmem+smem works and > gets migrated. I think we maybe want multiple things here? The test we have right now is useful because, by creating an internal LMEM buffer we ensure that the migration actually happens. If we create LMEM+SMEM, then it's possible it'll start off in SMEM and the migration would be a no-op. Not sure how likely that is in reality in a self-test environment, though. --Jason > - Once we have dynamic dma-buf for p2p pci, then we'll have another > selftest which checks that things work for lmem only if and only if
Re: [PATCH 2/2] drm/panel: Add Innolux EJ030NA 3.0" 320x480 panel
Hi Sam, Le sam., juil. 10 2021 at 08:18:44 +0200, Sam Ravnborg a écrit : Hi Paul, Christophe, On Fri, Jun 25, 2021 at 01:10:45PM +0100, Paul Cercueil wrote: From: Christophe Branchereau Add support for the Innolux/Chimei EJ030NA 3.0" 320x480 TFT panel. This panel can be found in the LDKs, RS97 V2.1 and RG300 (non IPS) handheld gaming consoles. While being 320x480, it is actually a horizontal 4:3 panel with non-square pixels in delta arrangement. Signed-off-by: Christophe Branchereau Signed-off-by: Paul Cercueil The drivers looks good. Reviewed-by: Sam Ravnborg Pushed to drm-misc-next. Thanks for the review! Cheers, -Paul
[PATCH] drm/i915: Check object_can_migrate from object_migrate
We don't roll them together entirely because there are still a couple cases where we want a separate can_migrate check. For instance, the display code checks that you can migrate a buffer to LMEM before it accepts it in fb_create. The dma-buf import code also uses it to do an early check and return a different error code if someone tries to attach a LMEM-only dma-buf to another driver. However, no one actually wants to call object_migrate when can_migrate has failed. The stated intention is for self-tests but none of those actually take advantage of this unsafe migration. Signed-off-by: Jason Ekstrand Cc: Daniel Vetter Cc: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c| 8 +++- drivers/gpu/drm/i915/gem/i915_gem_object.c| 13 ++--- .../gpu/drm/i915/gem/selftests/i915_gem_migrate.c | 15 --- 3 files changed, 5 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index 3163f00554476..5d438b95826b9 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -173,16 +173,14 @@ static int i915_gem_dmabuf_attach(struct dma_buf *dmabuf, struct i915_gem_ww_ctx ww; int err; + if (!i915_gem_object_can_migrate(obj, INTEL_REGION_SMEM)) + return -EOPNOTSUPP; + for_i915_gem_ww(, err, true) { err = i915_gem_object_lock(obj, ); if (err) continue; - if (!i915_gem_object_can_migrate(obj, INTEL_REGION_SMEM)) { - err = -EOPNOTSUPP; - continue; - } - err = i915_gem_object_migrate(obj, , INTEL_REGION_SMEM); if (err) continue; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index 9da7b288b7ede..f2244ae09a613 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -584,12 +584,6 @@ bool i915_gem_object_can_migrate(struct drm_i915_gem_object *obj, * completed yet, and to accomplish that, i915_gem_object_wait_migration() * must be called. * - * This function is a bit more permissive than i915_gem_object_can_migrate() - * to allow for migrating objects where the caller knows exactly what is - * happening. For example within selftests. More specifically this - * function allows migrating I915_BO_ALLOC_USER objects to regions - * that are not in the list of allowable regions. - * * Note: the @ww parameter is not used yet, but included to make sure * callers put some effort into obtaining a valid ww ctx if one is * available. @@ -616,11 +610,8 @@ int i915_gem_object_migrate(struct drm_i915_gem_object *obj, if (obj->mm.region == mr) return 0; - if (!i915_gem_object_evictable(obj)) - return -EBUSY; - - if (!obj->ops->migrate) - return -EOPNOTSUPP; + if (!i915_gem_object_can_migrate(obj, id)) + return -EINVAL; return obj->ops->migrate(obj, mr); } diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c index 0b7144d2991ca..28a700f08b49a 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c @@ -61,11 +61,6 @@ static int igt_create_migrate(struct intel_gt *gt, enum intel_region_id src, if (err) continue; - if (!i915_gem_object_can_migrate(obj, dst)) { - err = -EINVAL; - continue; - } - err = i915_gem_object_migrate(obj, , dst); if (err) continue; @@ -114,11 +109,6 @@ static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, return err; if (i915_gem_object_is_lmem(obj)) { - if (!i915_gem_object_can_migrate(obj, INTEL_REGION_SMEM)) { - pr_err("object can't migrate to smem.\n"); - return -EINVAL; - } - err = i915_gem_object_migrate(obj, ww, INTEL_REGION_SMEM); if (err) { pr_err("Object failed migration to smem\n"); @@ -137,11 +127,6 @@ static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, } } else { - if (!i915_gem_object_can_migrate(obj, INTEL_REGION_LMEM)) { - pr_err("object can't migrate to lmem.\n"); - return -EINVAL; - } - err = i915_gem_object_migrate(obj, ww, INTEL_REGION_LMEM); if (err) { pr_err("Object failed migration to lmem\n"); -- 2.31.1
Re: [PATCH 1/2] dt-bindings: display/panel: Add Innolux EJ030NA
Hi Rob, Le mer., juil. 14 2021 at 14:30:13 -0600, Rob Herring a écrit : On Sat, Jul 10, 2021 at 11:21:56AM +0100, Paul Cercueil wrote: [...] > > I am not sure; the doc states that this (additionalProperties: > > false) "can't > > be used in case where another schema is referenced", which is the > > case here, > > as we include "panel-common.yaml". > > This DT schema already list all relevant properties like: > > backlight: true > > So "additionalProperties: false" tells that no other properties are > allowed other than the listed properties. > > To my best understanding unevaluatedProperties: false is less strict and > should be used if one does not list all possilbe properties. Right. There's some value of listing which common properties you are using as well. > This could be the case for a panel haging below a SPI controller as in > this case. So in other words giving this some extra thought I think > unevaluatedProperties: false is OK here. A panel below a SPI controller would have all its SPI-specific properties covered by spi-controller.yaml, I believe? So maybe "additionalProperties: false" would work? No. Because spi-controller.yaml is evaluated on the SPI host node and this one is evaluated on the SPI slave. There's some work to address this, but it means every SPI slave will have to reference a SPI device schema. The bigger issue here is SPI controller specific device properties. So for this case, we'll have to use unevaluatedProperties. Thank you for the clarification. Cheers, -Paul In any case, if I use "additionalProperties: false", "make dt_binding_check" complains that my example's "spi-max-frequency" property is not covered. So maybe you are right. > So my r-b is ok if you keep it as it. > > PS. Where do you guys hang out with the downfall of freenode - somewhere > on oftc? We moved to #opendingux on Libera. Cheers, -Paul
Help needed for EVoC/GSoC/Outreachy
Hi! As some of you might already be aware, after helping out X.org project the previous years with regards to student outreach, Trevor decided to retire from this position in hopes that someone else will be able to step up and take on these responsibilities. As such, we're trying to find people who would be willing to volunteer their time to help out with getting us involved once again in student outreach programs. In the past, X.org has been active in the GSoC program, occasionally Outreachy, and our own EVoC program. As of 2021 though, GSoC decided to shorten the amount of time allocated for a student to work on their project. This unfortunately posed some problems for X.org/freedesktop.org as a lot of the potential work that would have been good for us to have students working on wouldn't really fit within the new GSoC timeframe. While it's certainly possible that there will be projects that come up in the future which do fit into this new timeline, we think it'd be a good idea to step up our involvement again with Outreachy where the program is a good bit more flexible then GSoC. We've also had pretty good experience working with the Outreachy candidates we've had in the past. The other main topic of discussion is around the fact that our own program, EVoC, hasn't really had anyone available to volunteer to help run it for a while now. For those who aren't aware, EVoC is a program similar to Google Summer of Code that X.org started running with much more relaxed requirements then GSoC/Outreachy in order to help fill the gaps for any exceptional cases with students who would otherwise be left out by the requirements for GSoC/Outreachy. Typically though, EVoC is usually considered the last resort after a student has tried getting into GSoC/Outreachy. So, the two biggest things that we need are: * Admin volunteer(s) * Mentors, mentors, mentors! We really need these the most. So, what responsibilities would being an admin for this entail? * Fielding questions from potential GSoC/EVoC/Outreachy participants. Most of these students are just looking for simple details of how these programs work and are looking for project ideas. Responding to these inquiries is mostly just a matter of pointing students to various pages on our wiki or replying with form/stock replies. Most of the students at this phase expect to be handed a project and a mentor, and therefore end up learning that they will need to come up with their own project and mentor. * For the small handful of students that make it to the next phase and figure out a project idea, they then need to find a mentor. Usually the admin will help out by taking a look at who proposed the project idea, and/or looking through commit messages and mailing list history to try to find someone who would be a good fit and willing to mentor the student. Sometimes this happens quickly, and sometimes it requires poking a lot of people - and occasionally, there might not always be a mentor to be found. * If we have a student, project, and mentor then the next step is having the student write up a proposal. Many students start out with over-simplified proposals, so a lot of this work is just gently nudging students and getting them to refine their work items into a week-by-week synopsis. There's usually a good bit of back and forth with the student's proposal, and occasionally the mentor may be involved with this step. * The admin then works with the student to come up with a timeline for their work, taking into account any vacation time the student may have, along with coordinating the frequency/type of meetings that will happen between the student and the mentor. If the mentor is unable to attend all of these meetings, it's usually up to the admin to check in with the student to see how they are progressing and potentially provide them tips if they get stuck. As for being a mentor, it's pretty much as simple as it sounds: you work with students who have projects to help familiarize them with the project at hand, help them out wherever needed, check in on their progress, and guide them along the way towards reaching their project goal along with grading their work. Please help spread the word on this, and contact anyone you know who might be involved with this! We'll be happy to provide more information on how you can get started. Remember, folks like myself wouldn't be in this community without projects like GSoC :). -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
Re: [PATCH 1/2] dt-bindings: display/panel: Add Innolux EJ030NA
On Fri, 25 Jun 2021 13:10:44 +0100, Paul Cercueil wrote: > Add binding for the Innolux EJ030NA panel, which is a 320x480 3.0" 4:3 > 24-bit TFT LCD panel with non-square pixels and a delta-RGB 8-bit > interface. > > Signed-off-by: Paul Cercueil > --- > .../display/panel/innolux,ej030na.yaml| 62 +++ > 1 file changed, 62 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/panel/innolux,ej030na.yaml > Reviewed-by: Rob Herring
Re: [PATCH 1/2] dt-bindings: display/panel: Add Innolux EJ030NA
On Sat, Jul 10, 2021 at 11:21:56AM +0100, Paul Cercueil wrote: > > [...] > > > > I am not sure; the doc states that this (additionalProperties: > > > false) "can't > > > be used in case where another schema is referenced", which is the > > > case here, > > > as we include "panel-common.yaml". > > > > This DT schema already list all relevant properties like: > > > > backlight: true > > > > So "additionalProperties: false" tells that no other properties are > > allowed other than the listed properties. > > > > To my best understanding unevaluatedProperties: false is less strict and > > should be used if one does not list all possilbe properties. Right. There's some value of listing which common properties you are using as well. > > This could be the case for a panel haging below a SPI controller as in > > this case. So in other words giving this some extra thought I think > > unevaluatedProperties: false is OK here. > > A panel below a SPI controller would have all its SPI-specific properties > covered by spi-controller.yaml, I believe? So maybe "additionalProperties: > false" would work? No. Because spi-controller.yaml is evaluated on the SPI host node and this one is evaluated on the SPI slave. There's some work to address this, but it means every SPI slave will have to reference a SPI device schema. The bigger issue here is SPI controller specific device properties. So for this case, we'll have to use unevaluatedProperties. > > In any case, if I use "additionalProperties: false", "make dt_binding_check" > complains that my example's "spi-max-frequency" property is not covered. So > maybe you are right. > > > So my r-b is ok if you keep it as it. > > > > PS. Where do you guys hang out with the downfall of freenode - somewhere > > on oftc? > > We moved to #opendingux on Libera. > > Cheers, > -Paul > > >
[tegra-drm:drm/tegra/for-next 1/14] drivers/gpu/host1x/fence.c:168:5: warning: no previous prototype for 'host1x_fence_create_fd'
tree: git://anongit.freedesktop.org/tegra/linux.git drm/tegra/for-next head: b19502d1a683c11f6f2c92ad63c61288b0fbe1a1 commit: ad0529424defbbe0b6a154cc100e82c1a9f91400 [1/14] gpu: host1x: Add DMA fence implementation config: arm-defconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git remote add tegra-drm git://anongit.freedesktop.org/tegra/linux.git git fetch --no-tags tegra-drm drm/tegra/for-next git checkout ad0529424defbbe0b6a154cc100e82c1a9f91400 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/gpu/host1x/fence.c:168:5: warning: no previous prototype for >> 'host1x_fence_create_fd' [-Wmissing-prototypes] 168 | int host1x_fence_create_fd(struct host1x_syncpt *sp, u32 threshold) | ^~ vim +/host1x_fence_create_fd +168 drivers/gpu/host1x/fence.c 167 > 168 int host1x_fence_create_fd(struct host1x_syncpt *sp, u32 threshold) 169 { 170 struct sync_file *file; 171 struct dma_fence *f; 172 int fd; 173 174 f = host1x_fence_create(sp, threshold); 175 if (IS_ERR(f)) 176 return PTR_ERR(f); 177 178 fd = get_unused_fd_flags(O_CLOEXEC); 179 if (fd < 0) { 180 dma_fence_put(f); 181 return fd; 182 } 183 184 file = sync_file_create(f); 185 dma_fence_put(f); 186 if (!file) 187 return -ENOMEM; 188 189 fd_install(fd, file->file); 190 191 return fd; 192 } 193 EXPORT_SYMBOL(host1x_fence_create_fd); 194 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
[PATCH 5/5] Revert "drm/i915: Skip over MI_NOOP when parsing"
This reverts a6c5e2aea704 ("drm/i915: Skip over MI_NOOP when parsing"). It complicates the batch parsing code a bit and increases indentation for no reason other than fast-skipping a command that userspace uses only rarely. Sure, there may be IGT tests that fill batches with NOOPs but that's not a case we should optimize for in the kernel. We should optimize for code clarity instead. Signed-off-by: Jason Ekstrand Reviewed-by: Jon Bloomfield Acked-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_cmd_parser.c | 67 +- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 00ec618d01590..322f4d5955a4f 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -1470,42 +1470,43 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, * space. Parsing should be faster in some cases this way. */ batch_end = cmd + batch_length / sizeof(*batch_end); - while (*cmd != MI_BATCH_BUFFER_END) { - u32 length = 1; - - if (*cmd != MI_NOOP) { /* MI_NOOP == 0 */ - desc = find_cmd(engine, *cmd, desc, _desc); - if (!desc) { - DRM_DEBUG("CMD: Unrecognized command: 0x%08X\n", *cmd); - ret = -EINVAL; - break; - } + do { + u32 length; - if (desc->flags & CMD_DESC_FIXED) - length = desc->length.fixed; - else - length = (*cmd & desc->length.mask) + LENGTH_BIAS; + if (*cmd == MI_BATCH_BUFFER_END) + break; - if ((batch_end - cmd) < length) { - DRM_DEBUG("CMD: Command length exceeds batch length: 0x%08X length=%u batchlen=%td\n", - *cmd, - length, - batch_end - cmd); - ret = -EINVAL; - break; - } + desc = find_cmd(engine, *cmd, desc, _desc); + if (!desc) { + DRM_DEBUG("CMD: Unrecognized command: 0x%08X\n", *cmd); + ret = -EINVAL; + break; + } - if (!check_cmd(engine, desc, cmd, length)) { - ret = -EACCES; - break; - } + if (desc->flags & CMD_DESC_FIXED) + length = desc->length.fixed; + else + length = (*cmd & desc->length.mask) + LENGTH_BIAS; - if (cmd_desc_is(desc, MI_BATCH_BUFFER_START)) { - ret = check_bbstart(cmd, offset, length, batch_length, - batch_addr, shadow_addr, - jump_whitelist); - break; - } + if ((batch_end - cmd) < length) { + DRM_DEBUG("CMD: Command length exceeds batch length: 0x%08X length=%u batchlen=%td\n", + *cmd, + length, + batch_end - cmd); + ret = -EINVAL; + break; + } + + if (!check_cmd(engine, desc, cmd, length)) { + ret = -EACCES; + break; + } + + if (cmd_desc_is(desc, MI_BATCH_BUFFER_START)) { + ret = check_bbstart(cmd, offset, length, batch_length, + batch_addr, shadow_addr, + jump_whitelist); + break; } if (!IS_ERR_OR_NULL(jump_whitelist)) @@ -1518,7 +1519,7 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, ret = -EINVAL; break; } - } + } while (1); if (trampoline) { /* -- 2.31.1
[PATCH 3/5] drm/i915: Remove allow_alloc from i915_gem_object_get_sg*
This reverts the rest of 0edbb9ba1bfe ("drm/i915: Move cmd parser pinning to execbuffer"). Now that the only user of i915_gem_object_get_sg without allow_alloc has been removed, we can drop the parameter. This portion of the revert was broken into its own patch to aid review. Signed-off-by: Jason Ekstrand Cc: Maarten Lankhorst Reviewed-by: Jon Bloomfield Acked-by: Daniel Vetter --- drivers/gpu/drm/i915/gem/i915_gem_object.h | 10 +- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 20 drivers/gpu/drm/i915/gem/i915_gem_ttm.c| 2 +- drivers/gpu/drm/i915/gt/intel_ggtt.c | 2 +- 4 files changed, 11 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 8be4fadeee487..f3ede43282dc6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -342,22 +342,22 @@ struct scatterlist * __i915_gem_object_get_sg(struct drm_i915_gem_object *obj, struct i915_gem_object_page_iter *iter, unsigned int n, -unsigned int *offset, bool allow_alloc, bool dma); +unsigned int *offset, bool dma); static inline struct scatterlist * i915_gem_object_get_sg(struct drm_i915_gem_object *obj, unsigned int n, - unsigned int *offset, bool allow_alloc) + unsigned int *offset) { - return __i915_gem_object_get_sg(obj, >mm.get_page, n, offset, allow_alloc, false); + return __i915_gem_object_get_sg(obj, >mm.get_page, n, offset, false); } static inline struct scatterlist * i915_gem_object_get_sg_dma(struct drm_i915_gem_object *obj, unsigned int n, - unsigned int *offset, bool allow_alloc) + unsigned int *offset) { - return __i915_gem_object_get_sg(obj, >mm.get_dma_page, n, offset, allow_alloc, true); + return __i915_gem_object_get_sg(obj, >mm.get_dma_page, n, offset, true); } struct page * diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index 0c9d28423d459..8eb1c3a6fc9cd 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -494,7 +494,7 @@ __i915_gem_object_get_sg(struct drm_i915_gem_object *obj, struct i915_gem_object_page_iter *iter, unsigned int n, unsigned int *offset, -bool allow_alloc, bool dma) +bool dma) { struct scatterlist *sg; unsigned int idx, count; @@ -516,9 +516,6 @@ __i915_gem_object_get_sg(struct drm_i915_gem_object *obj, if (n < READ_ONCE(iter->sg_idx)) goto lookup; - if (!allow_alloc) - goto manual_lookup; - mutex_lock(>lock); /* We prefer to reuse the last sg so that repeated lookup of this @@ -568,16 +565,7 @@ __i915_gem_object_get_sg(struct drm_i915_gem_object *obj, if (unlikely(n < idx)) /* insertion completed by another thread */ goto lookup; - goto manual_walk; - -manual_lookup: - idx = 0; - sg = obj->mm.pages->sgl; - count = __sg_page_count(sg); - -manual_walk: - /* -* In case we failed to insert the entry into the radixtree, we need + /* In case we failed to insert the entry into the radixtree, we need * to look beyond the current sg. */ while (idx + count <= n) { @@ -624,7 +612,7 @@ i915_gem_object_get_page(struct drm_i915_gem_object *obj, unsigned int n) GEM_BUG_ON(!i915_gem_object_has_struct_page(obj)); - sg = i915_gem_object_get_sg(obj, n, , true); + sg = i915_gem_object_get_sg(obj, n, ); return nth_page(sg_page(sg), offset); } @@ -650,7 +638,7 @@ i915_gem_object_get_dma_address_len(struct drm_i915_gem_object *obj, struct scatterlist *sg; unsigned int offset; - sg = i915_gem_object_get_sg_dma(obj, n, , true); + sg = i915_gem_object_get_sg_dma(obj, n, ); if (len) *len = sg_dma_len(sg) - (offset << PAGE_SHIFT); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 6589411396d3f..f253b11e9e367 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -589,7 +589,7 @@ static unsigned long i915_ttm_io_mem_pfn(struct ttm_buffer_object *bo, GEM_WARN_ON(bo->ttm); - sg = __i915_gem_object_get_sg(obj, >ttm.get_io_page, page_offset, , true, true); + sg = __i915_gem_object_get_sg(obj, >ttm.get_io_page, page_offset, , true); return ((base + sg_dma_address(sg)) >> PAGE_SHIFT) + ofs; } diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c
[PATCH 4/5] drm/i915: Drop error handling from dma_fence_work
Asynchronous command parsing was the only thing which ever returned a non-zero error. With that gone, we can drop the error handling from dma_fence_work. Signed-off-by: Jason Ekstrand Reviewed-by: Jon Bloomfield Acked-by: Daniel Vetter --- drivers/gpu/drm/i915/gem/i915_gem_clflush.c | 4 +--- drivers/gpu/drm/i915/i915_sw_fence_work.c | 5 + drivers/gpu/drm/i915/i915_sw_fence_work.h | 2 +- drivers/gpu/drm/i915/i915_vma.c | 3 +-- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_clflush.c b/drivers/gpu/drm/i915/gem/i915_gem_clflush.c index daf9284ef1f54..f0435c6feb68b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_clflush.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_clflush.c @@ -24,13 +24,11 @@ static void __do_clflush(struct drm_i915_gem_object *obj) i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU); } -static int clflush_work(struct dma_fence_work *base) +static void clflush_work(struct dma_fence_work *base) { struct clflush *clflush = container_of(base, typeof(*clflush), base); __do_clflush(clflush->obj); - - return 0; } static void clflush_release(struct dma_fence_work *base) diff --git a/drivers/gpu/drm/i915/i915_sw_fence_work.c b/drivers/gpu/drm/i915/i915_sw_fence_work.c index a3a81bb8f2c36..5b33ef23d54c9 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence_work.c +++ b/drivers/gpu/drm/i915/i915_sw_fence_work.c @@ -16,11 +16,8 @@ static void fence_complete(struct dma_fence_work *f) static void fence_work(struct work_struct *work) { struct dma_fence_work *f = container_of(work, typeof(*f), work); - int err; - err = f->ops->work(f); - if (err) - dma_fence_set_error(>dma, err); + f->ops->work(f); fence_complete(f); dma_fence_put(>dma); diff --git a/drivers/gpu/drm/i915/i915_sw_fence_work.h b/drivers/gpu/drm/i915/i915_sw_fence_work.h index 2c409f11c5c59..d56806918d131 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence_work.h +++ b/drivers/gpu/drm/i915/i915_sw_fence_work.h @@ -17,7 +17,7 @@ struct dma_fence_work; struct dma_fence_work_ops { const char *name; - int (*work)(struct dma_fence_work *f); + void (*work)(struct dma_fence_work *f); void (*release)(struct dma_fence_work *f); }; diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 0f227f28b2802..5b9dce0f443b0 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -300,14 +300,13 @@ struct i915_vma_work { unsigned int flags; }; -static int __vma_bind(struct dma_fence_work *work) +static void __vma_bind(struct dma_fence_work *work) { struct i915_vma_work *vw = container_of(work, typeof(*vw), base); struct i915_vma *vma = vw->vma; vma->ops->bind_vma(vw->vm, >stash, vma, vw->cache_level, vw->flags); - return 0; } static void __vma_release(struct dma_fence_work *work) -- 2.31.1
[PATCH 2/5] Revert "drm/i915: Propagate errors on awaiting already signaled fences"
This reverts commit 9e31c1fe45d555a948ff66f1f0e3fe1f83ca63f7. Ever since that commit, we've been having issues where a hang in one client can propagate to another. In particular, a hang in an app can propagate to the X server which causes the whole desktop to lock up. Error propagation along fences sound like a good idea, but as your bug shows, surprising consequences, since propagating errors across security boundaries is not a good thing. What we do have is track the hangs on the ctx, and report information to userspace using RESET_STATS. That's how arb_robustness works. Also, if my understanding is still correct, the EIO from execbuf is when your context is banned (because not recoverable or too many hangs). And in all these cases it's up to userspace to figure out what is all impacted and should be reported to the application, that's not on the kernel to guess and automatically propagate. What's more, we're also building more features on top of ctx error reporting with RESET_STATS ioctl: Encrypted buffers use the same, and the userspace fence wait also relies on that mechanism. So it is the path going forward for reporting gpu hangs and resets to userspace. So all together that's why I think we should just bury this idea again as not quite the direction we want to go to, hence why I think the revert is the right option here. For backporters: Please note that you _must_ have a backport of https://lore.kernel.org/dri-devel/20210602164149.391653-2-ja...@jlekstrand.net/ for otherwise backporting just this patch opens up a security bug. v2: Augment commit message. Also restore Jason's sob that I accidentally lost. v3: Add a note for backporters Signed-off-by: Jason Ekstrand Reported-by: Marcin Slusarz Cc: # v5.6+ Cc: Jason Ekstrand Cc: Marcin Slusarz Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/3080 Fixes: 9e31c1fe45d5 ("drm/i915: Propagate errors on awaiting already signaled fences") Acked-by: Daniel Vetter Reviewed-by: Jon Bloomfield --- drivers/gpu/drm/i915/i915_request.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 86b4c9f2613d5..09ebea9a0090a 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -1399,10 +1399,8 @@ i915_request_await_execution(struct i915_request *rq, do { fence = *child++; - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, >flags)) { - i915_sw_fence_set_error_once(>submit, fence->error); + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, >flags)) continue; - } if (fence->context == rq->fence.context) continue; @@ -1499,10 +1497,8 @@ i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence) do { fence = *child++; - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, >flags)) { - i915_sw_fence_set_error_once(>submit, fence->error); + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, >flags)) continue; - } /* * Requests on the same timeline are explicitly ordered, along -- 2.31.1
[PATCH 1/5] drm/i915: Revert "drm/i915/gem: Asynchronous cmdparser"
This reverts 686c7c35abc2 ("drm/i915/gem: Asynchronous cmdparser"). The justification for this commit in the git history was a vague comment about getting it out from under the struct_mutex. While this may improve perf for some workloads on Gen7 platforms where we rely on the command parser for features such as indirect rendering, no numbers were provided to prove such an improvement. It claims to closed two gitlab/bugzilla issues but with no explanation whatsoever as to why or what bug it's fixing. Meanwhile, by moving command parsing off to an async callback, it leaves us with a problem of what to do on error. When things were synchronous, EXECBUFFER2 would fail with an error code if parsing failed. When moving it to async, we needed another way to handle that error and the solution employed was to set an error on the dma_fence and then trust that said error gets propagated to the client eventually. Moving back to synchronous will help us untangle the fence error propagation mess. This also reverts most of 0edbb9ba1bfe ("drm/i915: Move cmd parser pinning to execbuffer") which is a refactor of some of our allocation paths for asynchronous parsing. Now that everything is synchronous, we don't need it. v2 (Daniel Vetter): - Add stabel Cc and Fixes tag Signed-off-by: Jason Ekstrand Cc: # v5.6+ Fixes: 9e31c1fe45d5 ("drm/i915: Propagate errors on awaiting already signaled fences") Cc: Maarten Lankhorst Reviewed-by: Jon Bloomfield Acked-by: Daniel Vetter --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 227 +- .../i915/gem/selftests/i915_gem_execbuffer.c | 4 + drivers/gpu/drm/i915/i915_cmd_parser.c| 132 +- drivers/gpu/drm/i915/i915_drv.h | 7 +- 4 files changed, 91 insertions(+), 279 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 5ea8b4e23e428..1ed7475de454d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -25,10 +25,8 @@ #include "i915_gem_clflush.h" #include "i915_gem_context.h" #include "i915_gem_ioctls.h" -#include "i915_sw_fence_work.h" #include "i915_trace.h" #include "i915_user_extensions.h" -#include "i915_memcpy.h" struct eb_vma { struct i915_vma *vma; @@ -1471,6 +1469,10 @@ static u32 *reloc_gpu(struct i915_execbuffer *eb, int err; struct intel_engine_cs *engine = eb->engine; + /* If we need to copy for the cmdparser, we will stall anyway */ + if (eb_use_cmdparser(eb)) + return ERR_PTR(-EWOULDBLOCK); + if (!reloc_can_use_engine(engine)) { engine = engine->gt->engine_class[COPY_ENGINE_CLASS][0]; if (!engine) @@ -2385,217 +2387,6 @@ shadow_batch_pin(struct i915_execbuffer *eb, return vma; } -struct eb_parse_work { - struct dma_fence_work base; - struct intel_engine_cs *engine; - struct i915_vma *batch; - struct i915_vma *shadow; - struct i915_vma *trampoline; - unsigned long batch_offset; - unsigned long batch_length; - unsigned long *jump_whitelist; - const void *batch_map; - void *shadow_map; -}; - -static int __eb_parse(struct dma_fence_work *work) -{ - struct eb_parse_work *pw = container_of(work, typeof(*pw), base); - int ret; - bool cookie; - - cookie = dma_fence_begin_signalling(); - ret = intel_engine_cmd_parser(pw->engine, - pw->batch, - pw->batch_offset, - pw->batch_length, - pw->shadow, - pw->jump_whitelist, - pw->shadow_map, - pw->batch_map); - dma_fence_end_signalling(cookie); - - return ret; -} - -static void __eb_parse_release(struct dma_fence_work *work) -{ - struct eb_parse_work *pw = container_of(work, typeof(*pw), base); - - if (!IS_ERR_OR_NULL(pw->jump_whitelist)) - kfree(pw->jump_whitelist); - - if (pw->batch_map) - i915_gem_object_unpin_map(pw->batch->obj); - else - i915_gem_object_unpin_pages(pw->batch->obj); - - i915_gem_object_unpin_map(pw->shadow->obj); - - if (pw->trampoline) - i915_active_release(>trampoline->active); - i915_active_release(>shadow->active); - i915_active_release(>batch->active); -} - -static const struct dma_fence_work_ops eb_parse_ops = { - .name = "eb_parse", - .work = __eb_parse, - .release = __eb_parse_release, -}; - -static inline int -__parser_mark_active(struct i915_vma *vma, -struct intel_timeline *tl, -struct dma_fence *fence) -{ - struct
[PATCH 0/5] drm/i915: Get rid of fence error propagation (v4)
Fence error propagation is sketchy at best. Instead of explicitly handling fences which might have errors set in the code which is aware of errors, we just kick them down the line and hope that userspace knows what to do when a wait eventually fails. This is sketchy at best because most userspace isn't prepared to handle errors in those places. To make things worse, it allows errors to propagate across processes in unpredictable ways. This is causing hangs in one client to kill X11. Unfortunately, there's no quick path from here to there thanks to the fact that we're now running the command parser asynchronously and relying on fence errors for when it fails. This series first gets rid of asynchronous command parsing and then cleans up from there. There was never any real use-case for asynchronous parsing and the platforms that rely heavily on the command parser are old enough (Gen7) that, when we changed the way the command parser works, it wasn't really a change anyone was asking for anyway. I think we probably want this whole mess back-ported. I'm happy to take suggestions on the strategy there because the history there is a bit annoying and I'm not 100% sure where the Linux release cuts land. In any case, I'm happy to make a version of this series per-release if needed for Greg to back-port. v2 (Daniel Vetter): - Re-order to put the reverts first - Add ACKs from Daniel - Add better CC and Fixes tags v3 (Jason Ekstrand): - Rebase on drm-tip v4 (Jason Ekstrand): - Rebase on drm-tip Test-with: 20210714173141.1381686-1-ja...@jlekstrand.net Jason Ekstrand (5): drm/i915: Revert "drm/i915/gem: Asynchronous cmdparser" Revert "drm/i915: Propagate errors on awaiting already signaled fences" drm/i915: Remove allow_alloc from i915_gem_object_get_sg* drm/i915: Drop error handling from dma_fence_work Revert "drm/i915: Skip over MI_NOOP when parsing" drivers/gpu/drm/i915/gem/i915_gem_clflush.c | 4 +- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 227 +- drivers/gpu/drm/i915/gem/i915_gem_object.h| 10 +- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 20 +- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +- .../i915/gem/selftests/i915_gem_execbuffer.c | 4 + drivers/gpu/drm/i915/gt/intel_ggtt.c | 2 +- drivers/gpu/drm/i915/i915_cmd_parser.c| 199 --- drivers/gpu/drm/i915/i915_drv.h | 7 +- drivers/gpu/drm/i915/i915_request.c | 8 +- drivers/gpu/drm/i915/i915_sw_fence_work.c | 5 +- drivers/gpu/drm/i915/i915_sw_fence_work.h | 2 +- drivers/gpu/drm/i915/i915_vma.c | 3 +- 13 files changed, 142 insertions(+), 351 deletions(-) -- 2.31.1
Re: [PATCH] drm/panel-simple: Power the panel when probing DP AUX backlight
Reviewed-by: Lyude Paul On Wed, 2021-07-14 at 09:33 -0700, Douglas Anderson wrote: > When I tried booting up a device that needed the DP AUX backlight, I > found an error in the logs: > panel-simple-dp-aux: probe of aux-ti_sn65dsi86.aux.0 failed with error - > 110 > > The aux transfers were failing because the panel wasn't powered. Just > like when reading the EDID we need to power the panel when trying to > talk to it. Add the needed pm_runtime calls. > > After I do this I can successfully probe the panel and adjust the > backlight on my board. > > Fixes: bfd451403d70 ("drm/panel-simple: Support DP AUX backlight") > Signed-off-by: Douglas Anderson > --- > > drivers/gpu/drm/panel/panel-simple.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/gpu/drm/panel/panel-simple.c > b/drivers/gpu/drm/panel/panel-simple.c > index e0a05f366ce6..9b286bdf 100644 > --- a/drivers/gpu/drm/panel/panel-simple.c > +++ b/drivers/gpu/drm/panel/panel-simple.c > @@ -827,7 +827,10 @@ static int panel_simple_probe(struct device *dev, const > struct panel_desc *desc, > goto disable_pm_runtime; > > if (!panel->base.backlight && panel->aux) { > + pm_runtime_get_sync(dev); > err = drm_panel_dp_aux_backlight(>base, panel->aux); > + pm_runtime_mark_last_busy(dev); > + pm_runtime_put_autosuspend(dev); > if (err) > goto disable_pm_runtime; > } -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
Re: [PATCH] drm/dp: For drm_panel_dp_aux_backlight(), init backlight as disabled
Reviewed-by: Lyude Paul On Wed, 2021-07-14 at 10:17 -0700, Douglas Anderson wrote: > Even after the DP AUX backlight on my board worked OK after applying > the patch ("drm/panel-simple: Power the panel when probing DP AUX > backlight") [1], I still noticed some strange timeouts being reported > by ti_sn_aux_transfer(). Digging, I realized the problem was this: > * Even though `enabled` in `struct dp_aux_backlight` was false, the > base backlight structure (`base` in that structure) thought that the > backlight was powered on. > * If userspace wrote to sysfs in this state then we'd try to enable > the backlight. > * Unfortunatley, enabling the backlight didn't work because the panel > itself wasn't powered. > > We can only use the backlight if the panel is on and the panel is not > officially on when we probe (it's temporarily just on enough for us to > talk to it). > > The important thing we want here is to get `BL_CORE_FBBLANK` set since > userspace can't mess with that. This will keep us disabled until > drm_panel enables us, which means that the panel is enabled > first. Ideally we'd just set this in our `props` before calling > devm_backlight_device_register() but the comments in the header file > are pretty explicit that we're not supposed to much with the `state` > ourselves. Because of this, there may be a small window where the > backlight device is registered and someone could try to tweak with the > backlight. This isn't likely to happen and even if it did, I don't > believe this causes any huge problem. > > [1] > https://lore.kernel.org/lkml/20210714093334.1.Idb41f87e5abae4aee0705db7458b0097fc50e7ab@changeid/ > > Signed-off-by: Douglas Anderson > --- > > drivers/gpu/drm/drm_dp_helper.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/gpu/drm/drm_dp_helper.c > b/drivers/gpu/drm/drm_dp_helper.c > index e8eec20ab364..b5f75ca05774 100644 > --- a/drivers/gpu/drm/drm_dp_helper.c > +++ b/drivers/gpu/drm/drm_dp_helper.c > @@ -3568,6 +3568,8 @@ int drm_panel_dp_aux_backlight(struct drm_panel > *panel, struct drm_dp_aux *aux) > if (IS_ERR(bl->base)) > return PTR_ERR(bl->base); > > + backlight_disable(bl->base); > + > panel->backlight = bl->base; > > return 0; -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
Re: [PATCH] drm/dp: For drm_panel_dp_aux_backlight(), init backlight as disabled
Reviewed-by: Lyude Paul On Wed, 2021-07-14 at 10:17 -0700, Douglas Anderson wrote: > Even after the DP AUX backlight on my board worked OK after applying > the patch ("drm/panel-simple: Power the panel when probing DP AUX > backlight") [1], I still noticed some strange timeouts being reported > by ti_sn_aux_transfer(). Digging, I realized the problem was this: > * Even though `enabled` in `struct dp_aux_backlight` was false, the > base backlight structure (`base` in that structure) thought that the > backlight was powered on. > * If userspace wrote to sysfs in this state then we'd try to enable > the backlight. > * Unfortunatley, enabling the backlight didn't work because the panel > itself wasn't powered. > > We can only use the backlight if the panel is on and the panel is not > officially on when we probe (it's temporarily just on enough for us to > talk to it). > > The important thing we want here is to get `BL_CORE_FBBLANK` set since > userspace can't mess with that. This will keep us disabled until > drm_panel enables us, which means that the panel is enabled > first. Ideally we'd just set this in our `props` before calling > devm_backlight_device_register() but the comments in the header file > are pretty explicit that we're not supposed to much with the `state` > ourselves. Because of this, there may be a small window where the > backlight device is registered and someone could try to tweak with the > backlight. This isn't likely to happen and even if it did, I don't > believe this causes any huge problem. > > [1] > https://lore.kernel.org/lkml/20210714093334.1.Idb41f87e5abae4aee0705db7458b0097fc50e7ab@changeid/ > > Signed-off-by: Douglas Anderson > --- > > drivers/gpu/drm/drm_dp_helper.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/gpu/drm/drm_dp_helper.c > b/drivers/gpu/drm/drm_dp_helper.c > index e8eec20ab364..b5f75ca05774 100644 > --- a/drivers/gpu/drm/drm_dp_helper.c > +++ b/drivers/gpu/drm/drm_dp_helper.c > @@ -3568,6 +3568,8 @@ int drm_panel_dp_aux_backlight(struct drm_panel > *panel, struct drm_dp_aux *aux) > if (IS_ERR(bl->base)) > return PTR_ERR(bl->base); > > + backlight_disable(bl->base); > + > panel->backlight = bl->base; > > return 0; -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
[Bug 209457] AMDGPU resume fail with RX 580 GPU
https://bugzilla.kernel.org/show_bug.cgi?id=209457 --- Comment #38 from Alex Deucher (alexdeuc...@gmail.com) --- (In reply to Leandro Jacques from comment #37) > (In reply to Alex Deucher from comment #32) > As you asked about the firmware version details, I upgraded my > linux-firmware package to see if the problem would come back and it came > back. So, this time, I could attatch the kernel log for the amdgpu driver > and the amdgpu firmware versions details as of the crash event to narrow > down the issue. By now, I'll return to the older version to make my system > stable again. You have a Picasso system. The original bug was about an RX 580. I don't think this is the same issue. Sounds like you are seeing this issue: https://lists.freedesktop.org/archives/amd-gfx/2021-July/066452.html -- 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 v5 17/17] drm/amd/display: Add handling for new "Broadcast RGB" property
Am 30.06.21 um 17:10 schrieb Werner Sembach: This commit implements the "Broadcast RGB" drm property for the AMD GPU driver. Signed-off-by: Werner Sembach --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +++--- .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c| 4 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 02a5809d4993..80d5a11fb0c5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5247,7 +5247,8 @@ get_aspect_ratio(const struct drm_display_mode *mode_in) } static enum dc_color_space -get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing) +get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing, + enum drm_mode_color_range preferred_color_range) { enum dc_color_space color_space = COLOR_SPACE_SRGB; @@ -5278,7 +5279,10 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing) } break; case PIXEL_ENCODING_RGB: - color_space = COLOR_SPACE_SRGB; + if (preferred_color_range == DRM_MODE_COLOR_RANGE_LIMITED_16_235) + color_space = COLOR_SPACE_SRGB_LIMITED; + else + color_space = COLOR_SPACE_SRGB; break; After some testing I found out, that what I did here, was useless. amdgpu actually never sets the quantization_range range in the hdmi_avi_infoframe and from that I guess any quantization range, besides the default one, is not implemented in multiple places Until limited RGB is properly implemented in amdgpu there kind of is no purpose of generalizing the Broadcast RGB switch. default: @@ -5424,7 +5428,10 @@ static void fill_stream_properties_from_drm_display_mode( timing_out->aspect_ratio = get_aspect_ratio(mode_in); - stream->output_color_space = get_output_color_space(timing_out); + stream->output_color_space = get_output_color_space(timing_out, + connector_state ? + connector_state->preferred_color_range : + DRM_MODE_COLOR_RANGE_UNSET); stream->out_transfer_func->type = TF_TYPE_PREDEFINED; stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB; @@ -7775,6 +7782,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, drm_connector_attach_active_bpc_property(>base, 8, 16); drm_connector_attach_preferred_color_format_property(>base); drm_connector_attach_active_color_format_property(>base); + drm_connector_attach_preferred_color_range_property(>base); drm_connector_attach_active_color_range_property(>base); } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 2563788ba95a..80e1389fd0ec 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -421,6 +421,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, if (connector->active_color_format_property) drm_connector_attach_active_color_format_property(>base); + connector->preferred_color_range_property = master->base.preferred_color_range_property; + if (connector->preferred_color_range_property) + drm_connector_attach_preferred_color_range_property(>base); + connector->active_color_range_property = master->base.active_color_range_property; if (connector->active_color_range_property) drm_connector_attach_active_color_range_property(>base);
Re: [PATCH v4 03/17] drm/uAPI: Add "active bpc" as feedback channel for "max bpc" drm property
Am 01.07.21 um 13:30 schrieb Werner Sembach: Am 01.07.21 um 09:42 schrieb Pekka Paalanen: On Wed, 30 Jun 2021 11:42:10 +0200 Werner Sembach wrote: Am 30.06.21 um 10:21 schrieb Pekka Paalanen: On Tue, 29 Jun 2021 13:02:05 +0200 Werner Sembach wrote: Am 28.06.21 um 19:03 schrieb Werner Sembach: Am 18.06.21 um 11:11 schrieb Werner Sembach: Add a new general drm property "active bpc" which can be used by graphic drivers to report the applied bit depth per pixel back to userspace. While "max bpc" can be used to change the color depth, there was no way to check which one actually got used. While in theory the driver chooses the best/highest color depth within the max bpc setting a user might not be fully aware what his hardware is or isn't capable off. This is meant as a quick way to double check the setup. In the future, automatic color calibration for screens might also depend on this information being available. Signed-off-by: Werner Sembach --- drivers/gpu/drm/drm_connector.c | 51 + include/drm/drm_connector.h | 8 ++ 2 files changed, 59 insertions(+) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index da39e7ff6965..943f6b61053b 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1197,6 +1197,14 @@ static const struct drm_prop_enum_list dp_colorspaces[] = { * drm_connector_attach_max_bpc_property() to create and attach the * property to the connector during initialization. * + * active bpc: + * This read-only range property tells userspace the pixel color bit depth + * actually used by the hardware display engine on "the cable" on a + * connector. The chosen value depends on hardware capabilities, both + * display engine and connected monitor, and the "max bpc" property. + * Drivers shall use drm_connector_attach_active_bpc_property() to install + * this property. + * Regarding "on the cable" and dithering: As far as I can tell, what the dithering option does, is setting a hardware register here: - https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/i915/display/intel_display.c#L4534 - https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/i915/display/intel_display.c#L4571 So dithering seems to be calculated by fixed purpose hardware/firmware outside of the driver? The Intel driver does not seem to set a target bpc/bpp for this hardware so I guess it defaults to 6 or 8 bpc? Never mind it does. This switch-case does affect the dithering output: https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/i915/display/intel_display.c#L4537 Hi, I obviously do not know the intel driver or hardware at all, but to me that just looks like translating from bits per pixel to bits per channel in RGB mapping? No, if i understand the documentation correctly: Writing bit depth here with dithering enabled sets the dithering target bpc. As found in this documentation p.548: https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-lkf-vol02c-commandreference-registers-part2.pdf So max bpc and active bpc are affecting/affected by the bpc after dithering. By definition, if the cable carries N bpc, then dithering does not change that. The cable still carries N bpc, but due to spatial or temporal dithering, the *observed* color resolution may or may not be higher than the cable bpc. Yes, and max bpc and active bpc tell the cable bpc ist not the *observed* bpc. Of course, if the cable bpc is 8, and dithering targets 6 bpc, then 2 LSB on the cable are always zero, right? I would assume that in this case only 6 bpc are actually send? Isn't the whole thing of dithering that you can't send, for example, 8 bpc? Maybe one would want to do that if the monitor has a 6 bit panel and it simply ignored the 2 LSB, and the cable cannot go down to 6 bpc. Is there dithering actually doing this? aka is my assumption above wrong? AMD code that confused me before, is hinting that you might be right: https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c#L826 there is a set_clamp depth and a separate DCP_SPATIAL_DITHER_DEPTH_30BPP So, what does "max bpc" mean right now? It seems like dither on/off is insufficient information, one would also need to control the dithering target bpc. I suppose the driver has a policy on how it chooses the target bpc, but what is that policy? Is the dither target bpc the cable bpc or the sink bpc? Needless to say, I'm quite confused. ... We need someone who knows what dithering on intel and amd gpu actually means. But I don't want this to become a blocker for this patchset, because if there is no dithering, which seems to be the norm, the active bpc property is already really usefull as it is. So add a note to the docs that the value might be invalid when dithering is active for now? Hi, not necessarily invalid. It all depends on how
Re: [PATCH v4 12/17] drm/uAPI: Add "preferred color format" drm property as setting for userspace
Am 06.07.21 um 09:09 schrieb Pekka Paalanen: On Mon, 5 Jul 2021 17:49:42 +0200 Werner Sembach wrote: Am 01.07.21 um 15:24 schrieb Pekka Paalanen: On Thu, 1 Jul 2021 14:50:13 +0200 Werner Sembach wrote: Am 01.07.21 um 10:07 schrieb Pekka Paalanen: On Wed, 30 Jun 2021 11:20:18 +0200 Werner Sembach wrote: Am 30.06.21 um 10:41 schrieb Pekka Paalanen: On Tue, 29 Jun 2021 13:39:18 +0200 Werner Sembach wrote: Am 29.06.21 um 13:17 schrieb Pekka Paalanen: On Tue, 29 Jun 2021 08:12:54 + Simon Ser wrote: On Tuesday, June 22nd, 2021 at 09:15, Pekka Paalanen wrote: yes, I think this makes sense, even if it is a property that one can't tell for sure what it does before hand. Using a pair of properties, preference and active, to ask for something and then check what actually worked is good for reducing the combinatorial explosion caused by needing to "atomic TEST_ONLY commit" test different KMS configurations. Userspace has a better chance of finding a configuration that is possible. OTOH, this has the problem than in UI one cannot tell the user in advance which options are truly possible. Given that KMS properties are rarely completely independent, and in this case known to depend on several other KMS properties, I think it is good enough to know after the fact. If a driver does not use what userspace prefers, there is no way to understand why, or what else to change to make it happen. That problem exists anyway, because TEST_ONLY commits do not give useful feedback but only a yes/no. By submitting incremental atomic reqs with TEST_ONLY (i.e. only changing one property at a time), user-space can discover which property makes the atomic commit fail. That works if the properties are independent of each other. Color range, color format, bpc and more may all be interconnected, allowing only certain combinations to work. If all these properties have "auto" setting too, then it would be possible to probe each property individually, but that still does not tell which combinations are valid. If you probe towards a certain configuration by setting the properties one by one, then depending on the order you pick the properties, you may come to a different conclusion on which property breaks the configuration. My mind crossed another point that must be considered: When plugin in a Monitor a list of possible Resolutions+Framerate combinations is created for xrandr and other userspace (I guess by atomic checks? but I don't know). Hi, I would not think so, but I hope to be corrected if I'm wrong. My belief is that the driver collects a list of modes from EDID, some standard modes, and maybe some other hardcoded modes, and then validates each entry against all the known limitations like vertical and horizontal frequency limits, discarding modes that do not fit. Not all limitations are known during that phase, which is why KMS property "link-status" exists. When userspace actually programs a mode (not a TEST_ONLY commit), the link training may fail. The kernel prunes the mode from the list and sets the link status property to signal failure, and sends a hotplug uevent. Userspace needs to re-check the mode list and try again. That is a generic escape hatch for when TEST_ONLY commit succeeds, but in reality the hardware cannot do it, you just cannot know until you actually try for real. It causes end user visible flicker if it happens on an already running connector, but since it usually happens when turning a connector on to begin with, there is no flicker to be seen, just a small delay in finding a mode that works. During this drm properties are already considered, which is no problem atm because as far as i can tell there is currently no drm property that would make a certain Resolutions+Framerate combination unreachable that would be possible with everything on default. I would not expect KMS properties to be considered at all. It would reject modes that are actually possible if the some KMS properties were changed. So at least going forward, current KMS property values cannot factor in. At least the debugfs variable "force_yuv420_output" did change the available modes here: https://elixir.bootlin.com/linux/v5.13/source/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c#L5165 before my patch https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=68eb3ae3c63708f823aeeb63bb15197c727bd9bf Hi, debugfs is not proper UAPI, so we can just ignore it. Display servers cannot be expected to poke in debugfs. Debugfs is not even supposed to exist in production systems, but I'm sure people use it for hacking stuff. But that's all it is for: developer testing and hacking. e.g. Ubuntu has it active by default, but only read (and writable) by root. Hi, that's normal, yes. Root can do damage anyway, and it's useful for debugging. KMS clients OTOH often do not run as root. Forcing a color format via a DRM property in this
[Bug 209457] AMDGPU resume fail with RX 580 GPU
https://bugzilla.kernel.org/show_bug.cgi?id=209457 --- Comment #37 from Leandro Jacques (ls...@yahoo.com) --- (In reply to Alex Deucher from comment #32) As you asked about the firmware version details, I upgraded my linux-firmware package to see if the problem would come back and it came back. So, this time, I could attatch the kernel log for the amdgpu driver and the amdgpu firmware versions details as of the crash event to narrow down the issue. By now, I'll return to the older version to make my system stable again. -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
[PATCH v3 5/5] i915: map gvt pr_debug categories to bits in parameters/debug_gvt
The gvt component of this driver has ~120 pr_debugs, in 9 "classes". Following the interface model of drm.debug, add a parameter to map bits to these classes. If CONFIG_DRM_USE_DYNAMIC_DEBUG=y (and CONFIG_DYNAMIC_DEBUG_CORE), add -DDYNAMIC_DEBUG_MODULE into Makefile. TBD: maybe add a separate CONFIG_I915_USE_DYNAMIC_DEBUG to more fully optionalize this. In i915_params.c, add callback to map bits to queries. TBD: the callback code should probably be moved to lib/dynamic_debug, and given a declarative interface, with implied bit-numbering, something like: MOD_PARM_BITMAP_DESC(__gvt_debug, "gvt: cmd: ", "command processing" "gvt: core: ", "core help", "gvt: dpy: ", "display help", "gvt: el: ", "help", "gvt: irq: ", "help", "gvt: mm: ", "help", "gvt: mmio: ", "help", "gvt: render: ", "help", "gvt: sched: " "help"); Signed-off-by: Jim Cromie --- drivers/gpu/drm/i915/gvt/Makefile | 4 ++ drivers/gpu/drm/i915/i915_params.c | 76 ++ 2 files changed, 80 insertions(+) diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile index ea8324abc784..846ba73b8de6 100644 --- a/drivers/gpu/drm/i915/gvt/Makefile +++ b/drivers/gpu/drm/i915/gvt/Makefile @@ -7,3 +7,7 @@ GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \ ccflags-y += -I $(srctree)/$(src) -I $(srctree)/$(src)/$(GVT_DIR)/ i915-y += $(addprefix $(GVT_DIR)/, $(GVT_SOURCE)) + +#ifdef CONFIG_DRM_USE_DYNAMIC_DEBUG +ccflags-y += -DDYNAMIC_DEBUG_MODULE +#endif diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index e07f4cfea63a..e0d13aff5274 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -265,3 +265,79 @@ void i915_params_free(struct i915_params *params) I915_PARAMS_FOR_EACH(FREE); #undef FREE } + +/* POC for callback -> dynamic_debug_exec_queries */ +unsigned long __gvt_debug; +EXPORT_SYMBOL(__gvt_debug); + +static char *format_prefix_classes[] = { + "gvt: cmd: ", + "gvt: core: ", + "gvt: dpy: ", + "gvt: el: ", + "gvt: irq: ", + "gvt: mm: ", + "gvt: mmio: ", + "gvt: render: ", + "gvt: sched: " +}; +#define NUM_CLASSESARRAY_SIZE(format_prefix_classes) +#define OUR_QUERY_SIZE 128 /* we need about 20 */ + +#include + +static int param_set_dyndbg(const char *instr, const struct kernel_param *kp) +{ + unsigned int val; + unsigned long changes, result; + int rc, chgct = 0, totct = 0, bitpos; + char query[OUR_QUERY_SIZE]; + + rc = kstrtouint(instr, 0, ); + if (rc) { + pr_err("set_dyndbg: failed\n"); + return -EINVAL; + } + result = val; + pr_info("set_dyndbg: result:0x%lx from %s\n", result, instr); + + changes = result ^ __gvt_debug; + + for_each_set_bit(bitpos, , NUM_CLASSES) { + + sprintf(query, "format '^%s' %cp", format_prefix_classes[bitpos], + test_bit(bitpos, ) ? '+' : '-'); + + chgct = dynamic_debug_exec_queries(query, "i915"); + + pr_info("%d changes on: %s\n", chgct, query); + totct += chgct; + } + pr_info("total changes: %d\n", totct); + __gvt_debug = result; + return 0; +} +static int param_get_dyndbg(char *buffer, const struct kernel_param *kp) +{ + return scnprintf(buffer, PAGE_SIZE, "%u\n", +*((unsigned int *)kp->arg)); +} +static const struct kernel_param_ops param_ops_dyndbg = { + .set = param_set_dyndbg, + .get = param_get_dyndbg, +}; + +#define info_ln(hexi, prefix) "\n\t0x" __stringify(hexi) "\t" prefix + +MODULE_PARM_DESC(debug_gvt, " gvt debug categories:" +info_ln(1, "gvt: cmd:") +info_ln(2, "gvt: core:") +info_ln(4, "gvt: dpy:") +info_ln(8, "gvt: el:") +info_ln(10, "gvt: irq:") +info_ln(20, "gvt: mm:") +info_ln(40, "gvt: mmio:") +info_ln(80, "gvt: render:") +info_ln(100, "gvt: sched:")); + +module_param_cb(debug_gvt, _ops_dyndbg, &__gvt_debug, 0644); -- 2.31.1
[PATCH v3 4/5] drm/print: move conditional deref into macro defn
commit 7911902129a8 ("drm/print: Handle potentially NULL drm_devices in drm_dbg_*") added a maybe(deref) to 6 macro invocations of drm_dev_dbg(). Commit 01ff672190bd("drm: RFC add choice to use dynamic debug in drm-debug") then renamed that fn to _drm_dev_dbg(), and redefined drm_dev_dbg() as a macro. That new macro can do the maybe(deref), so the ~9 callers dont have to. no functional changes. small word-count reduction. Signed-off-by: Jim Cromie --- include/drm/drm_print.h | 27 +-- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 499fa0b35200..573b513e7836 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -326,8 +326,8 @@ enum drm_debug_category { */ #define __drm_dbg(cls, fmt, ...) \ ___drm_dbg(cls, fmt, ##__VA_ARGS__) -#define drm_dev_dbg(dev, cls, fmt, ...)\ - _drm_dev_dbg(dev, cls, fmt, ##__VA_ARGS__) +#define drm_dev_dbg(drm, cls, fmt, ...)\ + _drm_dev_dbg((drm) ? (drm)->dev : NULL, cls, fmt, ##__VA_ARGS__) #define cDRM_UT_CORE DRM_UT_CORE #define cDRM_UT_DRIVER DRM_UT_DRIVER @@ -488,25 +488,25 @@ void _drm_dev_dbg(const struct device *dev, enum drm_debug_category category, #define drm_dbg_core(drm, fmt, ...)\ - drm_dev_dbg((drm) ? (drm)->dev : NULL, cDRM_UT_CORE, fmt, ##__VA_ARGS__) + drm_dev_dbg(drm, cDRM_UT_CORE, fmt, ##__VA_ARGS__) #define drm_dbg(drm, fmt, ...) \ - drm_dev_dbg((drm) ? (drm)->dev : NULL, cDRM_UT_DRIVER, fmt, ##__VA_ARGS__) + drm_dev_dbg(drm, cDRM_UT_DRIVER, fmt, ##__VA_ARGS__) #define drm_dbg_kms(drm, fmt, ...) \ - drm_dev_dbg((drm) ? (drm)->dev : NULL, cDRM_UT_KMS, fmt, ##__VA_ARGS__) + drm_dev_dbg(drm, cDRM_UT_KMS, fmt, ##__VA_ARGS__) #define drm_dbg_prime(drm, fmt, ...) \ - drm_dev_dbg((drm) ? (drm)->dev : NULL, cDRM_UT_PRIME, fmt, ##__VA_ARGS__) + drm_dev_dbg(drm, cDRM_UT_PRIME, fmt, ##__VA_ARGS__) #define drm_dbg_atomic(drm, fmt, ...) \ - drm_dev_dbg((drm) ? (drm)->dev : NULL, cDRM_UT_ATOMIC, fmt, ##__VA_ARGS__) + drm_dev_dbg(drm, cDRM_UT_ATOMIC, fmt, ##__VA_ARGS__) #define drm_dbg_vbl(drm, fmt, ...) \ - drm_dev_dbg((drm) ? (drm)->dev : NULL, cDRM_UT_VBL, fmt, ##__VA_ARGS__) + drm_dev_dbg(drm, cDRM_UT_VBL, fmt, ##__VA_ARGS__) #define drm_dbg_state(drm, fmt, ...) \ - drm_dev_dbg((drm) ? (drm)->dev : NULL, cDRM_UT_STATE, fmt, ##__VA_ARGS__) + drm_dev_dbg(drm, cDRM_UT_STATE, fmt, ##__VA_ARGS__) #define drm_dbg_lease(drm, fmt, ...) \ - drm_dev_dbg((drm) ? (drm)->dev : NULL, cDRM_UT_LEASE, fmt, ##__VA_ARGS__) + drm_dev_dbg(drm, cDRM_UT_LEASE, fmt, ##__VA_ARGS__) #define drm_dbg_dp(drm, fmt, ...) \ - drm_dev_dbg((drm) ? (drm)->dev : NULL, cDRM_UT_DP, fmt, ##__VA_ARGS__) + drm_dev_dbg(drm, cDRM_UT_DP, fmt, ##__VA_ARGS__) #define drm_dbg_drmres(drm, fmt, ...) \ - drm_dev_dbg((drm) ? (drm)->dev : NULL, cDRM_UT_DRMRES, fmt, ##__VA_ARGS__) + drm_dev_dbg(drm, cDRM_UT_DRMRES, fmt, ##__VA_ARGS__) /* @@ -578,8 +578,7 @@ void __drm_err(const char *format, ...); const struct drm_device *drm_ = (drm); \ \ if (drm_debug_enabled(DRM_UT) && __ratelimit(_)) \ - drm_dev_dbg((drm_) ? (drm_)->dev : NULL,\ - cDRM_UT, fmt, ##__VA_ARGS__); \ + drm_dev_dbg(drm_, cDRM_UT, fmt, ##__VA_ARGS__); \ }) #define drm_dbg_kms_ratelimited(drm, fmt, ...) \ -- 2.31.1
[PATCH v3 3/5] drm/print: RFC add choice to use dynamic debug in drm-debug
drm's debug system uses distinct categories of debug messages, encoded in an enum (DRM_UT_), which are mapped to bits in drm.debug. drm_debug_enabled() does a lot of unlikely bit-mask checks on drm.debug; we can use dynamic debug instead, and get all that static_key/jump_label goodness. Dynamic debug has no concept of category, but we can map the DRM_UT_* to a set of distinct prefixes; "drm:core:", "drm:kms:" etc, and prepend them to the given formats. Then we can use: `echo module drm format ^drm:core: +p > control` to enable every such "prefixed" pr_debug with one query. This new prefix changes pr_debug's output, so is user visible, but it seems unlikely to cause trouble for log watchers; they're not relying on the absence of class prefix strings. This conversion yields ~2100 new callsites on my i7/i915 laptop: dyndbg: 195 debug prints in module drm_kms_helper dyndbg: 298 debug prints in module drm dyndbg: 1630 debug prints in module i915 CONFIG_DRM_USE_DYNAMIC_DEBUG enables this, and is available if CONFIG_DYNAMIC_DEBUG or CONFIG_DYNAMIC_DEBUG_CORE is chosen, and if CONFIG_JUMP_LABEL is enabled; this because its required to get the promised optimizations. The indirection/switchover is layered into the macro scheme: 0. A new callback on drm.debug which calls dynamic_debug_exec_queries to map those bits to specific query/commands dynamic_debug_exec_queries("format ^drm:kms: +p", "drm*"); here for POC, this should be in dynamic_debug.c with a MODULE_PARAM_DEBUG_BITMAP(__drm_debug, { "prefix-1", "desc-1" }+) 1. A "converted" or "classy" DRM_UT_* map based on: DRM_UT_* ( symbol => bit-mask ) named it: cDRM_UT_* ( symbol => format-class-prefix-string ) So cDRM_UT_* is either: legacy: cDRM_UT_* <-- DRM_UT_* ( !CONFIG_DRM_USE_DYNAMIC_DEBUG ) enabled: #define cDRM_UT_KMS"drm:kms: " #define cDRM_UT_PRIME "drm:prime: " #define cDRM_UT_ATOMIC "drm:atomic: " DRM_UT_* are unchanged, since theyre used in drm_debug_enabled() and elsewhere. 2. drm_dev_dbg & drm_debug are renamed (prefixed with '_') old names are now macros, calling either: legacy: -> to renamed fn enabled: -> dev_dbg & pr_debug, with cDRM-prefix # format. these names are used in a fat layer of macros (3) which supply the category; those macros are used throughout drm code, yielding the ~2100 new prdbgs reported above. 3. names in (2) are invoked by DRM_DEBUG_, drm_dbg_. all these macros get "converted" to use cDRM_UT_* to get right token type for both !/!! DRM_USE_DYNAMIC_DEBUG 4. simplification of __DRM_DEFINE_DBG_RATELIMITED macro remove DRM_UT_ ## KMS as extra indirection pass both DRM_UT & cDRM_UT, for drm_debug_enabled & drm_dev_dbg Signed-off-by: Jim Cromie --- drivers/gpu/drm/Kconfig | 13 + drivers/gpu/drm/drm_print.c | 75 -- include/drm/drm_print.h | 102 ++-- 3 files changed, 158 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 7ff89690a976..e4524ccba040 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -57,6 +57,19 @@ config DRM_DEBUG_MM If in doubt, say "N". +config DRM_USE_DYNAMIC_DEBUG + bool "use dynamic debug to implement drm.debug" + default n + depends on DRM + depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE + depends on JUMP_LABEL + help + The drm debug category facility does a lot of unlikely bit-field + tests at runtime; while cheap individually, the cost accumulates. + This option uses dynamic debug facility (if configured and + using jump_label) to avoid those runtime checks, patching + the kernel when those debugs are desired. + config DRM_DEBUG_SELFTEST tristate "kselftests for DRM" depends on DRM diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c index 111b932cf2a9..e2acdfc7088b 100644 --- a/drivers/gpu/drm/drm_print.c +++ b/drivers/gpu/drm/drm_print.c @@ -52,8 +52,75 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug cat "\t\tBit 5 (0x20) will enable VBL messages (vblank code)\n" "\t\tBit 7 (0x80) will enable LEASE messages (leasing code)\n" "\t\tBit 8 (0x100) will enable DP messages (displayport code)"); + +#ifndef CONFIG_DRM_USE_DYNAMIC_DEBUG module_param_named(debug, __drm_debug, int, 0600); +#else +static char *format_class_prefixes[] = { + cDRM_UT_CORE, + cDRM_UT_DRIVER, + cDRM_UT_KMS, + cDRM_UT_PRIME, + cDRM_UT_ATOMIC, + cDRM_UT_VBL, + cDRM_UT_STATE, + cDRM_UT_LEASE, + cDRM_UT_DP, + cDRM_UT_DRMRES +}; + +#define OUR_QUERY_SIZE 64 /* > strlen "format '^%s' %cp" + longest prefix */ + +static int param_set_dyndbg(const char *instr, const struct kernel_param *kp) +{ + unsigned int val; + unsigned long changes, result; + int rc,
[PATCH v3 2/5] drm_print.h: rewrap __DRM_DEFINE_DBG_RATELIMITED macro
whitespace only, to minimize the diff of a later commit. no functional changes Signed-off-by: Jim Cromie --- include/drm/drm_print.h | 20 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 15a089a87c22..ff5ac0e88321 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -524,19 +524,23 @@ void __drm_err(const char *format, ...); #define DRM_DEBUG_DP(fmt, ...) \ __drm_dbg(DRM_UT_DP, fmt, ## __VA_ARGS__) -#define __DRM_DEFINE_DBG_RATELIMITED(category, drm, fmt, ...) \ -({ \ - static DEFINE_RATELIMIT_STATE(rs_, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST);\ - const struct drm_device *drm_ = (drm); \ - \ - if (drm_debug_enabled(DRM_UT_ ## category) && __ratelimit(_)) \ - drm_dev_printk(drm_ ? drm_->dev : NULL, KERN_DEBUG, fmt, ## __VA_ARGS__); \ +#define __DRM_DEFINE_DBG_RATELIMITED(category, drm, fmt, ...) \ +({ \ + static DEFINE_RATELIMIT_STATE(rs_, \ + DEFAULT_RATELIMIT_INTERVAL, \ + DEFAULT_RATELIMIT_BURST); \ + const struct drm_device *drm_ = (drm); \ + \ + if (drm_debug_enabled(DRM_UT_ ## category) && __ratelimit(_))\ + drm_dev_printk(drm_ ? drm_->dev : NULL, \ + KERN_DEBUG, fmt, ## __VA_ARGS__);\ }) #define drm_dbg_kms_ratelimited(drm, fmt, ...) \ __DRM_DEFINE_DBG_RATELIMITED(KMS, drm, fmt, ## __VA_ARGS__) -#define DRM_DEBUG_KMS_RATELIMITED(fmt, ...) drm_dbg_kms_ratelimited(NULL, fmt, ## __VA_ARGS__) +#define DRM_DEBUG_KMS_RATELIMITED(fmt, ...) \ + drm_dbg_kms_ratelimited(NULL, fmt, ## __VA_ARGS__) /* * struct drm_device based WARNs -- 2.31.1
[PATCH v3 1/5] drm/print: fixup spelling in a comment
s/prink/printk/ - no functional changes Signed-off-by: Jim Cromie --- include/drm/drm_print.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 9b66be54dd16..15a089a87c22 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -327,7 +327,7 @@ static inline bool drm_debug_enabled(enum drm_debug_category category) /* * struct device based logging * - * Prefer drm_device based logging over device or prink based logging. + * Prefer drm_device based logging over device or printk based logging. */ __printf(3, 4) -- 2.31.1
[PATCH v3 0/5] drm: use dyndbg in drm_print
hi dri-devel, Im pretty new in this particular playground. Im using this to send, is it too spammy ? too --to ? git send-email --dry-run \ --to-cmd='scripts/get_maintainer.pl --no-rolestats v3-000*.patch' \ --to=jba...@akamai.com v3-000*.patch drm_debug_enabled() is called a lot (by drm_dev_dbg) to do unlikely bit-tests to selectively enable debug printing; this is a good job for dynamic-debug, IFF it is built with JUMP_LABEL. This patchset enables the use of dynamic-debug to avoid those drm_debug_enabled() overheads, if CONFIG_DRM_USE_DYNAMIC_DEBUG=y. v3: fixes missed SOB, && on BOL, commit-log tweaks reordered patches, 1 is comment, 2 is whitespace. dropped RFC, to see what happens. v2: https://lore.kernel.org/lkml/20210711055003.528167-1-jim.cro...@gmail.com/ v1: https://lore.kernel.org/lkml/20201204035318.332419-1-jim.cro...@gmail.com/ Doing so creates many new pr_debug callsites, otherwise i915 has ~120 prdbgs, and drm has just 1; bash-5.1# modprobe i915 dyndbg: 8 debug prints in module video dyndbg: 305 debug prints in module drm dyndbg: 207 debug prints in module drm_kms_helper dyndbg: 2 debug prints in module ttm dyndbg: 1720 debug prints in module i915 On amdgpu, enabling it adds ~3200 prdbgs, currently at 56 bytes each. So CONFIG_DRM_USE_DYNAMIC_DEBUG=y affects resource requirements. Im running this patchset bare-metal on an i915 laptop & an amdgpu desktop (both as loadable modules). I booted the amdgpu box with: BOOT_IMAGE=(hd2,gpt2)/vmlinuz-5.13.0-dd7-13692-g8def25788f56 \ root=UUID=mumble ro \ rootflags=subvol=root00 rhgb \ dynamic_debug.verbose=3 main.dyndbg=+p \ amdgpu.debug=1 amdgpu.test=1 \ "amdgpu.dyndbg=format ^[ +p" That last line enables ~1700 prdbg callsites with a format like '[DML' etc at boot, and amdgpu.test=1 triggers 3 minutes of tests, causing ~76k prdbgs in 409 seconds, before I turned them off with: echo module amdgpu -p > /proc/dynamic_debug/control This is on top of master @ v5.14-rc1 Should I rebase onto something else ? Jim Cromie (5): drm/print: fixup spelling in a comment drm_print.h: rewrap __DRM_DEFINE_DBG_RATELIMITED macro drm/print: RFC add choice to use dynamic debug in drm-debug drm/print: move conditional deref into macro defn i915: map gvt pr_debug categories to bits in parameters/debug_gvt Note: 3/5, 5/5 have bits that are here for POC, but belong in dynamic_debug.c. drivers/gpu/drm/Kconfig| 13 drivers/gpu/drm/drm_print.c| 75 +- drivers/gpu/drm/i915/gvt/Makefile | 4 + drivers/gpu/drm/i915/i915_params.c | 76 +++ include/drm/drm_print.h| 117 - 5 files changed, 247 insertions(+), 38 deletions(-) -- 2.31.1
Re: [v2 1/3] dt-bindings: msm/dsi: Add sc7280 7nm dsi phy
On Tue, 22 Jun 2021 18:12:26 +0530, Rajeev Nandan wrote: > The SC7280 SoC uses the 7nm (V4.1) DSI PHY driver. > > Signed-off-by: Rajeev Nandan > --- > > Changes in v2: > - New > This patch depends on [1] (dt-bindings: msm: dsi: add missing 7nm bindings) > > [1] > https://lore.kernel.org/linux-arm-msm/20210617144349.28448-2-jonat...@marek.ca/ > > Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml | 1 + > 1 file changed, 1 insertion(+) > Acked-by: Rob Herring
[PATCH] drm/dp: For drm_panel_dp_aux_backlight(), init backlight as disabled
Even after the DP AUX backlight on my board worked OK after applying the patch ("drm/panel-simple: Power the panel when probing DP AUX backlight") [1], I still noticed some strange timeouts being reported by ti_sn_aux_transfer(). Digging, I realized the problem was this: * Even though `enabled` in `struct dp_aux_backlight` was false, the base backlight structure (`base` in that structure) thought that the backlight was powered on. * If userspace wrote to sysfs in this state then we'd try to enable the backlight. * Unfortunatley, enabling the backlight didn't work because the panel itself wasn't powered. We can only use the backlight if the panel is on and the panel is not officially on when we probe (it's temporarily just on enough for us to talk to it). The important thing we want here is to get `BL_CORE_FBBLANK` set since userspace can't mess with that. This will keep us disabled until drm_panel enables us, which means that the panel is enabled first. Ideally we'd just set this in our `props` before calling devm_backlight_device_register() but the comments in the header file are pretty explicit that we're not supposed to much with the `state` ourselves. Because of this, there may be a small window where the backlight device is registered and someone could try to tweak with the backlight. This isn't likely to happen and even if it did, I don't believe this causes any huge problem. [1] https://lore.kernel.org/lkml/20210714093334.1.Idb41f87e5abae4aee0705db7458b0097fc50e7ab@changeid/ Signed-off-by: Douglas Anderson --- drivers/gpu/drm/drm_dp_helper.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index e8eec20ab364..b5f75ca05774 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -3568,6 +3568,8 @@ int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux) if (IS_ERR(bl->base)) return PTR_ERR(bl->base); + backlight_disable(bl->base); + panel->backlight = bl->base; return 0; -- 2.32.0.93.g670b81a890-goog
[PATCH -next] drm: nouveau: fix disp.c build when NOUVEAU_BACKLIGHT is not enabled
Fix build errors and warnings when # CONFIG_DRM_NOUVEAU_BACKLIGHT is not set ../drivers/gpu/drm/nouveau/dispnv50/disp.c: In function ‘nv50_sor_atomic_disable’: ../drivers/gpu/drm/nouveau/dispnv50/disp.c:1665:52: error: ‘struct nouveau_connector’ has no member named ‘backlight’ struct nouveau_backlight *backlight = nv_connector->backlight; ^~ ../drivers/gpu/drm/nouveau/dispnv50/disp.c:1670:28: error: dereferencing pointer to incomplete type ‘struct nouveau_backlight’ if (backlight && backlight->uses_dpcd) { and then fix subsequent build warnings after the above are fixed: ../drivers/gpu/drm/nouveau/dispnv50/disp.c: In function ‘nv50_sor_atomic_disable’: ../drivers/gpu/drm/nouveau/dispnv50/disp.c:1669:6: warning: unused variable ‘ret’ [-Wunused-variable] int ret; ^~~ ../drivers/gpu/drm/nouveau/dispnv50/disp.c:1662:22: warning: unused variable ‘drm’ [-Wunused-variable] struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); ^~~ Fixes: 6eca310e8924 ("drm/nouveau/kms/nv50-: Add basic DPCD backlight support for nouveau") Signed-off-by: Randy Dunlap Cc: Ben Skeggs Cc: dri-devel@lists.freedesktop.org Cc: nouv...@lists.freedesktop.org Cc: Lyude Paul --- drivers/gpu/drm/nouveau/dispnv50/disp.c |8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) --- linux-next-20210714.orig/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ linux-next-20210714/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1659,23 +1659,27 @@ static void nv50_sor_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); struct nouveau_crtc *nv_crtc = nouveau_crtc(nv_encoder->crtc); struct nouveau_connector *nv_connector = nv50_outp_get_old_connector(state, nv_encoder); +#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT + struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); struct nouveau_backlight *backlight = nv_connector->backlight; +#endif struct drm_dp_aux *aux = _connector->aux; int ret; u8 pwr; +#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT if (backlight && backlight->uses_dpcd) { ret = drm_edp_backlight_disable(aux, >edp_info); if (ret < 0) NV_ERROR(drm, "Failed to disable backlight on [CONNECTOR:%d:%s]: %d\n", nv_connector->base.base.id, nv_connector->base.name, ret); } +#endif if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { - int ret = drm_dp_dpcd_readb(aux, DP_SET_POWER, ); + ret = drm_dp_dpcd_readb(aux, DP_SET_POWER, ); if (ret == 0) { pwr &= ~DP_SET_POWER_MASK;
[PATCH] drm/amd/powerplay: remove redundant assignment to usTMax
From: Colin Ian King Struct element usTMax is being assigned a hard coded value that is never read and it is being re-assigned a new value immediately afterwards. The assignment is redundant and can be removed. Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c index f2a55c1413f5..20e528c166f9 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c @@ -977,8 +977,6 @@ static int init_thermal_controller( = le16_to_cpu(tonga_fan_table->usPWMMed); hwmgr->thermal_controller.advanceFanControlParameters.usPWMHigh = le16_to_cpu(tonga_fan_table->usPWMHigh); - hwmgr->thermal_controller.advanceFanControlParameters.usTMax - = 10900; /* hard coded */ hwmgr->thermal_controller.advanceFanControlParameters.usTMax = le16_to_cpu(tonga_fan_table->usTMax); hwmgr->thermal_controller.advanceFanControlParameters.ucFanControlMode -- 2.31.1
Re: [PATCH AUTOSEL 4.4 08/31] drm/virtio: Fixes a potential NULL pointer dereference on probe failure
On Mon, Jul 12, 2021 at 11:59:37PM +0200, Pavel Machek wrote: Hi! From: Xie Yongji [ Upstream commit 17f46f488a5d82c5568e6e786cd760bba1c2ee09 ] The dev->dev_private might not be allocated if virtio_gpu_pci_quirk() or virtio_gpu_init() failed. In this case, we should avoid the cleanup in virtio_gpu_release(). The check is in wrong place at least in 4.4: +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -257,6 +257,9 @@ int virtio_gpu_driver_unload(struct drm_device *dev) flush_work(>config_changed_work); vgdev->vdev->config->del_vqs(vgdev->vdev); + if (!vgdev) + return; + Pointer is dereferenced before being tested. Heh, yes, thanks for catching that. I'll drop it for now and rework it next week. -- Thanks, Sasha
Re: [PATCH AUTOSEL 5.13 001/189] drm/etnaviv: fix NULL check before some freeing functions is not needed
On Wed, Jul 07, 2021 at 01:50:21PM +0200, Christian König wrote: Am 07.07.21 um 12:52 schrieb Lucas Stach: Am Dienstag, dem 06.07.2021 um 07:11 -0400 schrieb Sasha Levin: From: Tian Tao [ Upstream commit 7d614ab2f20503ed8766363d41f8607337571adf ] fixed the below warning: drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c:84:2-8: WARNING: NULL check before some freeing functions is not needed. While the subject contains "fix" this only removes a duplicated NULL check, so the code is correct before and after this change. Is this really stable material? Doesn't this just add commit noise to the stable kernels? Yeah, agree. I also had a case where a NULL check was removed in amdgpu and then a bit later back ported to stable. Maybe just use something like "remove superfluous NULL check". Sorry for missing that, I'll drop it. Thanks! -- Thanks, Sasha
Re: [PATCH v2 3/4] dt-bindings: arm: fsl: add SKOV imx6q and imx6dl based boards
On Wed, 14 Jul 2021 06:53:48 +0200, Oleksij Rempel wrote: > Add SKOV imx6q/dl LT2, LT6 and mi1010ait-1cp1 boards. > > Signed-off-by: Oleksij Rempel > --- > Documentation/devicetree/bindings/arm/fsl.yaml | 5 + > 1 file changed, 5 insertions(+) > Please add Acked-by/Reviewed-by tags when posting new versions. However, there's no need to repost patches *only* to add the tags. The upstream maintainer will do that for acks received on the version they apply. If a tag was not added on purpose, please state why and what changed.
Re: [PATCH v2 2/4] dt-bindings: vendor-prefixes: Add an entry for SKOV A/S
On Wed, 14 Jul 2021 06:53:47 +0200, Oleksij Rempel wrote: > Add "skov" entry for the SKOV A/S: https://www.skov.com/en/ > > Signed-off-by: Oleksij Rempel > --- > Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ > 1 file changed, 2 insertions(+) > Please add Acked-by/Reviewed-by tags when posting new versions. However, there's no need to repost patches *only* to add the tags. The upstream maintainer will do that for acks received on the version they apply. If a tag was not added on purpose, please state why and what changed.
Re: [PATCH v2 1/4] dt-bindings: display: simple: add some Logic Technologies and Multi-Inno panels
On Wed, 14 Jul 2021 06:53:46 +0200, Oleksij Rempel wrote: > Add Logictechno and Multi-Inno panels: > - Logic Technologies LTTD800x480 L2RT 7" 800x480 TFT Resistive Touch Module > - Logic Technologies LTTD800480070-L6WH-RT 7” 800x480 TFT Resistive Touch > Module > - Multi-Inno Technology Co.,Ltd MI1010AIT-1CP 10.1" 1280x800 LVDS IPS Cap > Touch Mod. > > Signed-off-by: Oleksij Rempel > --- > .../devicetree/bindings/display/panel/panel-simple.yaml | 6 ++ > 1 file changed, 6 insertions(+) > Please add Acked-by/Reviewed-by tags when posting new versions. However, there's no need to repost patches *only* to add the tags. The upstream maintainer will do that for acks received on the version they apply. If a tag was not added on purpose, please state why and what changed.
[PATCH] drm/panel-simple: Power the panel when probing DP AUX backlight
When I tried booting up a device that needed the DP AUX backlight, I found an error in the logs: panel-simple-dp-aux: probe of aux-ti_sn65dsi86.aux.0 failed with error -110 The aux transfers were failing because the panel wasn't powered. Just like when reading the EDID we need to power the panel when trying to talk to it. Add the needed pm_runtime calls. After I do this I can successfully probe the panel and adjust the backlight on my board. Fixes: bfd451403d70 ("drm/panel-simple: Support DP AUX backlight") Signed-off-by: Douglas Anderson --- drivers/gpu/drm/panel/panel-simple.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index e0a05f366ce6..9b286bdf 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -827,7 +827,10 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc, goto disable_pm_runtime; if (!panel->base.backlight && panel->aux) { + pm_runtime_get_sync(dev); err = drm_panel_dp_aux_backlight(>base, panel->aux); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); if (err) goto disable_pm_runtime; } -- 2.32.0.93.g670b81a890-goog
Re: [PATCH v4 3/4] drm/shmem-helpers: Allocate wc pages on x86
On Wed, Jul 14, 2021 at 02:58:26PM +0200, Christian König wrote: > Am 14.07.21 um 14:48 schrieb Daniel Vetter: > > On Wed, Jul 14, 2021 at 01:54:50PM +0200, Christian König wrote: > > > Am 13.07.21 um 22:51 schrieb Daniel Vetter: > > > > intel-gfx-ci realized that something is not quite coherent anymore on > > > > some platforms for our i915+vgem tests, when I tried to switch vgem > > > > over to shmem helpers. > > > > > > > > After lots of head-scratching I realized that I've removed calls to > > > > drm_clflush. And we need those. To make this a bit cleaner use the > > > > same page allocation tooling as ttm, which does internally clflush > > > > (and more, as neeeded on any platform instead of just the intel x86 > > > > cpus i915 can be combined with). > > > > > > > > Unfortunately this doesn't exist on arm, or as a generic feature. For > > > > that I think only the dma-api can get at wc memory reliably, so maybe > > > > we'd need some kind of GFP_WC flag to do this properly. > > > The problem is that this stuff is extremely architecture specific. So > > > GFP_WC > > > and GFP_UNCACHED are really what we should aim for in the long term. > > > > > > And as far as I know we have at least the following possibilities how it > > > is > > > implemented: > > > > > > * A fixed amount of registers which tells the CPU the caching behavior > > > for a > > > memory region, e.g. MTRR. > > > * Some bits of the memory pointers used, e.g. you see the same memory at > > > different locations with different caching attributes. > > > * Some bits in the CPUs page table. > > > * Some bits in a separate page table. > > > > > > On top of that there is the PCIe specification which defines non-cache > > > snooping access as an extension. > > Yeah dma-buf is extremely ill-defined even on x86 if you combine these > > all. We just play a game of whack-a-mole with the cacheline dirt until > > it's gone. > > > > That's the other piece here, how do you even make sure that the page is > > properly flushed and ready for wc access: > > - easy case is x86 with clflush available pretty much everywhere (since > >10+ years at least) > > - next are cpus which have some cache flush instructions, but it's highly > >cpu model specific > > - next up is the same, but you absolutely have to make sure there's no > >other mapping around anymore or the coherency fabric just dies > > - and I'm pretty sure there's worse stuff where you defacto can only > >allocate wc memory that's set aside at boot-up and that's all you ever > >get. > > Well long story short you don't make sure that the page is flushed at all. > > What you do is to allocate the page as WC in the first place, if you fail to > do this you can't use it. Oh sure, but even when you allocate as wc you need to make sure the page you have is actually wc coherent from the start. I'm chasing some fun trying to convert vgem over to shmem helpers right now (i.e. this patch series), and if you don't start out with flushed pages some of the vgem + i915 igts just fail on the less coherent igpu platforms we have. And if you look into what set_pages_wc actually does, then you spot the clflush somewhere deep down (aside from all the other things it does). On some ARM platforms that's just not possible, and you have to do a carveout that you never even map as wb (so needs to be excluded from the kernel map too and treated as highmem). There's some really bonkers stuff here. > The whole idea TTM try to sell until a while ago that you can actually > change that on the fly only works on x86 and even there only very very > limited. Yeah that's clear, this is why we're locking down the i915 gem uapi a lot for dgpu. All the tricks are out the window. -Daniel > > Cheers, > Christian. > > > > > Cheers, Daniel > > > > > Mixing that with the CPU caching behavior gets you some really nice ways > > > to > > > break a driver. In general x86 seems to be rather graceful, but arm and > > > PowerPC are easily pissed if you mess that up. > > > > > > > Signed-off-by: Daniel Vetter > > > > Cc: Christian König > > > > Cc: "Thomas Hellström" > > > > Cc: Maarten Lankhorst > > > > Cc: Maxime Ripard > > > > Cc: Thomas Zimmermann > > > > Cc: David Airlie > > > > Cc: Daniel Vetter > > > Acked-by: Christian könig > > > > > > Regards, > > > Christian. > > > > > > > --- > > > >drivers/gpu/drm/drm_gem_shmem_helper.c | 14 ++ > > > >1 file changed, 14 insertions(+) > > > > > > > > diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c > > > > b/drivers/gpu/drm/drm_gem_shmem_helper.c > > > > index 296ab1b7c07f..657d2490aaa5 100644 > > > > --- a/drivers/gpu/drm/drm_gem_shmem_helper.c > > > > +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c > > > > @@ -10,6 +10,10 @@ > > > >#include > > > >#include > > > > +#ifdef CONFIG_X86 > > > > +#include > > > > +#endif > > > > + > > > >#include > > > >#include > > > >#include > > > > @@ -162,6 +166,11 @@
Re: [PATCH 1/2] drm: add crtc background color property
On 2021-07-14 3:35 a.m., Pekka Paalanen wrote: > On Tue, 13 Jul 2021 09:54:35 -0400 > Harry Wentland wrote: > >> On 2021-07-13 3:52 a.m., Pekka Paalanen wrote: >>> On Mon, 12 Jul 2021 12:15:59 -0400 >>> Harry Wentland wrote: >>> On 2021-07-12 4:03 a.m., Pekka Paalanen wrote: > On Fri, 9 Jul 2021 18:23:26 +0200 > Raphael Gallais-Pou wrote: > >> On 7/9/21 10:04 AM, Pekka Paalanen wrote: >>> On Wed, 7 Jul 2021 08:48:47 + >>> Raphael GALLAIS-POU - foss wrote: >>> Some display controllers can be programmed to present non-black colors for pixels not covered by any plane (or pixels covered by the transparent regions of higher planes). Compositors that want a UI with a solid color background can potentially save memory bandwidth by setting the CRTC background property and using smaller planes to display the rest of the content. To avoid confusion between different ways of encoding RGB data, we define a standard 64-bit format that should be used for this property's value. Helper functions and macros are provided to generate and dissect values in this standard format with varying component precision values. Signed-off-by: Raphael Gallais-Pou Signed-off-by: Matt Roper --- drivers/gpu/drm/drm_atomic_state_helper.c | 1 + drivers/gpu/drm/drm_atomic_uapi.c | 4 +++ drivers/gpu/drm/drm_blend.c | 34 +-- drivers/gpu/drm/drm_mode_config.c | 6 include/drm/drm_blend.h | 1 + include/drm/drm_crtc.h| 12 include/drm/drm_mode_config.h | 5 include/uapi/drm/drm_mode.h | 28 +++ 8 files changed, 89 insertions(+), 2 deletions(-) >>> >>> ... >>> >>> The question about full vs. limited range seems unnecessary to me, as >>> the background color will be used as-is in the blending stage, so >>> userspace can just program the correct value that fits the pipeline it >>> is setting up. >>> >>> One more question is, as HDR exists, could we need background colors >>> with component values greater than 1.0? >> >> AR4H color format should cover that case, isn't it ? > > Yes, but with the inconvenience I mentioned. > > This is a genuine question though, would anyone actually need > background color values > 1.0. I don't know of any case yet where it > would be required. It would imply that plane blending happens in a > color space where >1.0 values are meaningful. I'm not even sure if any > hardware supporting that exists. > > Maybe it would be best to assume that only [0.0, 1.0] pixel value range > is useful, and mention in the commit message that if someone really > needs values outside of that, they should create another background > color property. Then, you can pick a simple unsigned integer pixel > format, too. (I didn't see any 16 bit-per-channel formats like that in > drm_fourcc.h though.) > I don't think we should artificially limit this to [0.0, 1.0]. As you mentioned above when talking about full vs limited, the userspace understands what's the correct value that fits the pipeline. If that pipeline is FP16 with > 1.0 values then it would make sense that the background color can be > 1.0. >>> >>> Ok. The standard FP32 format then for ease of use and guaranteed enough >>> range and precision for far into the future? >>> >> >> I don't have a strong preference for FP16 vs FP32. My understanding is >> that FP16 is enough to represent linearly encoded data in a way that >> looks smooth to humans. >> >> scRGB uses FP16 with linear encoding in a range of [-0.5, 7.4999]. >> >>> Or do you want to keep it in 64 bits total, so the UABI can pack >>> everything into a u64 instead of needing to create a blob? >>> >>> I don't mind as long as it's clearly documented what it is and how it >>> works, and it carries enough precision. >>> >>> But FP16 with its 10 bits of precision might be too little for integer >>> 12-16 bpc pipelines and sinks? > > The 10 bits worries me still. > > If you have a pipeline that works in [0.0, 1.0] range only, then FP16 > limits precision to 10 bits (in the upper half of the range?). > >>> >>> If the values can go beyond [0.0, 1.0] range, then does the blending >>> hardware and the degamma/ctm/gamma coming afterwards cope with them, or >>> do they get clamped anyway? >>> >> >> That probably depends on the HW and how it's configured. AMD HW can handle >> values above and below [0.0, 1.0]. > > Right, so how would userspace know what will happen? > > Or do we need to specify that while values
Re: [PATCH v3 1/1] drm/ttm: Fix COW check
Am 2021-07-14 um 6:51 a.m. schrieb Christian König: > Am 14.07.21 um 12:44 schrieb Daniel Vetter: >> On Mon, Jul 12, 2021 at 06:06:36PM -0400, Felix Kuehling wrote: >>> KFD Thunk maps invisible VRAM BOs with PROT_NONE, MAP_PRIVATE. >>> is_cow_mapping returns true for these mappings. Add a check for >>> vm_flags & VM_WRITE to avoid mmap failures on private read-only or >>> PROT_NONE mappings. >>> >>> v2: protect against mprotect making a mapping writable after the fact >>> v3: update driver-specific vm_operations_structs >>> >>> Fixes: f91142c62161 ("drm/ttm: nuke VM_MIXEDMAP on BO mappings v3") >>> Signed-off-by: Felix Kuehling >>> Signed-off-by: Alex Deucher >> So looking at vmf_insert_pfn_prot() and the comment there we can't have >> VM_PFNMAP and is_cow_mapping ever be true, or things break. On platforms >> without pte_special at least. > > Key idea is that we never end up in vmf_insert_pfn_prot() because the > vma is mapped with PROT_NONE. Ah, thanks for that pointer. I wasn't aware of that BUG_ON. I thought it was more of an abstract "copy-on-write faults may be bad on these mappings." > >> >> So I'm not sure this is a great idea, and definitely not for all drivers > > Yeah, I'm absolutely not happy with this either but it seemed to be > the least painful thing to do. > >> ... >> >> Can we clear VM_MAYWRITE instead to force this to be a non-cow mapping >> instead? > > Well we have considered forcefully setting VM_SHARED, which won't work > easily for a couple of reasons. > > But clearing VM_MAYWRITE in amdgpu/amdkfd may actually work as well. > > Felix can you test this? Sounds like it should work and be straight forward (I thought that about setting VM_SHARED, too ...). I'll give it a try. Thanks, Felix > > Thanks, > Christian. > >> -Daniel >> >>> --- >>> drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 3 ++- >>> drivers/gpu/drm/nouveau/nouveau_gem.c | 3 ++- >>> drivers/gpu/drm/radeon/radeon_gem.c | 3 ++- >>> drivers/gpu/drm/ttm/ttm_bo_vm.c | 14 +- >>> drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c | 1 + >>> include/drm/ttm/ttm_bo_api.h | 4 >>> 6 files changed, 24 insertions(+), 4 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c >>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c >>> index b3404c43a911..1aa750a6a5d2 100644 >>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c >>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c >>> @@ -79,7 +79,8 @@ static const struct vm_operations_struct >>> amdgpu_gem_vm_ops = { >>> .fault = amdgpu_gem_fault, >>> .open = ttm_bo_vm_open, >>> .close = ttm_bo_vm_close, >>> - .access = ttm_bo_vm_access >>> + .access = ttm_bo_vm_access, >>> + .mprotect = ttm_bo_vm_mprotect >>> }; >>> static void amdgpu_gem_object_free(struct drm_gem_object *gobj) >>> diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c >>> b/drivers/gpu/drm/nouveau/nouveau_gem.c >>> index 5b27845075a1..164ea564bb7a 100644 >>> --- a/drivers/gpu/drm/nouveau/nouveau_gem.c >>> +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c >>> @@ -70,7 +70,8 @@ static const struct vm_operations_struct >>> nouveau_ttm_vm_ops = { >>> .fault = nouveau_ttm_fault, >>> .open = ttm_bo_vm_open, >>> .close = ttm_bo_vm_close, >>> - .access = ttm_bo_vm_access >>> + .access = ttm_bo_vm_access, >>> + .mprotect = ttm_bo_vm_mprotect >>> }; >>> void >>> diff --git a/drivers/gpu/drm/radeon/radeon_gem.c >>> b/drivers/gpu/drm/radeon/radeon_gem.c >>> index 458f92a70887..c19ad07eb7b5 100644 >>> --- a/drivers/gpu/drm/radeon/radeon_gem.c >>> +++ b/drivers/gpu/drm/radeon/radeon_gem.c >>> @@ -77,7 +77,8 @@ static const struct vm_operations_struct >>> radeon_gem_vm_ops = { >>> .fault = radeon_gem_fault, >>> .open = ttm_bo_vm_open, >>> .close = ttm_bo_vm_close, >>> - .access = ttm_bo_vm_access >>> + .access = ttm_bo_vm_access, >>> + .mprotect = ttm_bo_vm_mprotect >>> }; >>> static void radeon_gem_object_free(struct drm_gem_object *gobj) >>> diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c >>> b/drivers/gpu/drm/ttm/ttm_bo_vm.c >>> index f56be5bc0861..fb325bad5db6 100644 >>> --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c >>> +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c >>> @@ -542,17 +542,29 @@ int ttm_bo_vm_access(struct vm_area_struct >>> *vma, unsigned long addr, >>> } >>> EXPORT_SYMBOL(ttm_bo_vm_access); >>> +int ttm_bo_vm_mprotect(struct vm_area_struct *vma, unsigned long >>> start, >>> + unsigned long end, unsigned long newflags) >>> +{ >>> + /* Enforce no COW since would have really strange behavior with >>> it. */ >>> + if (is_cow_mapping(newflags) && (newflags & VM_WRITE)) >>> + return -EINVAL; >>> + >>> + return 0; >>> +} >>> +EXPORT_SYMBOL(ttm_bo_vm_mprotect); >>> + >>> static const struct vm_operations_struct ttm_bo_vm_ops = { >>> .fault = ttm_bo_vm_fault, >>> .open = ttm_bo_vm_open, >>> .close = ttm_bo_vm_close, >>> .access =
[PATCH] drm/msm/dp: Initialize dp->aux->drm_dev before registration
From: Sean Paul Avoids the following WARN: [3.009556] [ cut here ] [3.014306] WARNING: CPU: 7 PID: 109 at drivers/gpu/drm/drm_dp_helper.c:1796 drm_dp_aux_register+0xa4/0xac [3.024209] Modules linked in: [3.027351] CPU: 7 PID: 109 Comm: kworker/7:8 Not tainted 5.10.47 #69 [3.033958] Hardware name: Google Lazor (rev1 - 2) (DT) [3.039323] Workqueue: events deferred_probe_work_func [3.044596] pstate: 60c9 (nZCv daif +PAN +UAO -TCO BTYPE=--) [3.050761] pc : drm_dp_aux_register+0xa4/0xac [3.055329] lr : dp_aux_register+0x40/0x88 [3.059538] sp : ffc010ad3920 [3.062948] x29: ffc010ad3920 x28: ffa64196ac70 [3.067239] mmc1: Command Queue Engine enabled [3.068406] x27: ffa64196ac68 x26: 0001 [3.068407] x25: 0002 x24: 0060 [3.068409] x23: ffa642ab3400 x22: ffe126c10e5b [3.068410] x21: ffa641dc3188 x20: ffa641963c10 [3.068412] x19: ffa642aba910 x18: 0a00 [3.068414] x17: 00476f8e002a x16: 00b8 [3.073008] mmc1: new HS400 Enhanced strobe MMC card at address 0001 [3.078448] x15: x14: [3.078450] x13: 0030 x12: 0030 [3.078452] x11: 0101010101010101 x10: ffe12647a914 [3.078453] x9 : ffe12647a8cc x8 : [3.084452] mmcblk1: mmc1:0001 DA4032 29.1 GiB [3.089372] [3.089372] x7 : 6c6064717372fefe x6 : ffa642b11494 [3.089374] x5 : x4 : 6d006c657869 [3.089375] x3 : 6c657869 x2 : 000c [3.089376] x1 : ffe126c3ae3c x0 : ffa642aba910 [3.089381] Call trace: [3.094931] mmcblk1boot0: mmc1:0001 DA4032 partition 1 4.00 MiB [3.100291] drm_dp_aux_register+0xa4/0xac [3.100292] dp_aux_register+0x40/0x88 [3.100294] dp_display_bind+0x64/0xcc [3.100295] component_bind_all+0xdc/0x210 [3.100298] msm_drm_bind+0x1e8/0x5d4 [3.100301] try_to_bring_up_master+0x168/0x1b0 [3.105861] mmcblk1boot1: mmc1:0001 DA4032 partition 2 4.00 MiB [3.112282] __component_add+0xa0/0x158 [3.112283] component_add+0x1c/0x28 [3.112284] dp_display_probe+0x33c/0x380 [3.112286] platform_drv_probe+0x9c/0xbc [3.112287] really_probe+0x140/0x35c [3.112289] driver_probe_device+0x84/0xc0 [3.112292] __device_attach_driver+0x94/0xb0 [3.117967] mmcblk1rpmb: mmc1:0001 DA4032 partition 3 16.0 MiB, chardev (239:0) [3.123201] bus_for_each_drv+0x8c/0xd8 [3.123202] __device_attach+0xc4/0x150 [3.123204] device_initial_probe+0x1c/0x28 [3.123205] bus_probe_device+0x3c/0x9c [3.123206] deferred_probe_work_func+0x90/0xcc [3.123211] process_one_work+0x218/0x3ec [3.131976] mmcblk1: p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 [3.134123] worker_thread+0x288/0x3e8 [3.134124] kthread+0x148/0x1b0 [3.134127] ret_from_fork+0x10/0x30 [3.134128] ---[ end trace cfb9fce3f70f824d ]--- Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/dp/dp_display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 051c1be1de7e..987f9e330138 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -219,6 +219,7 @@ static int dp_display_bind(struct device *dev, struct device *master, goto end; } + dp->aux->drm_dev = drm; rc = dp_aux_register(dp->aux); if (rc) { DRM_ERROR("DRM DP AUX register failed\n"); -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH resend 0/5] video: fbdev: ssd1307fb: Optimizations and improvements
Hi Geert, On Wed, Jul 14, 2021 at 04:57:59PM +0200, Geert Uytterhoeven wrote: > Hi all, > > This patch series optimizes console operations on ssd1307fb, after the > customary fixes and cleanups. What is required to to have a drm driver that could do the same? Note: I will take a look at the patches a bit later. Sam
Re: [PATCH v2] drm/of: free the iterator object on failure
Hi Steven, Thank you for the patch. On Wed, Jul 14, 2021 at 03:33:00PM +0100, Steven Price wrote: > When bailing out due to the sanity check the iterator value needs to be > freed because the early return prevents for_each_child_of_node() from > doing the dereference itself. > > Fixes: 6529007522de ("drm: of: Add drm_of_lvds_get_dual_link_pixel_order") > Signed-off-by: Steven Price Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/drm_of.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > v2: Fixes now refers to the original commit as suggested by Laurent, rather > than 4ee48cc5586b ("drm: of: Fix double-free bug") which only fixed part of > the problem. Note that 4ee48cc5586b is a dependency for this patch to > cleanly apply. > > diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c > index 197c57477344..997b8827fed2 100644 > --- a/drivers/gpu/drm/drm_of.c > +++ b/drivers/gpu/drm/drm_of.c > @@ -331,8 +331,10 @@ static int drm_of_lvds_get_remote_pixels_type( >* configurations by passing the endpoints explicitly to >* drm_of_lvds_get_dual_link_pixel_order(). >*/ > - if (!current_pt || pixels_type != current_pt) > + if (!current_pt || pixels_type != current_pt) { > + of_node_put(endpoint); > return -EINVAL; > + } > } > > return pixels_type; -- Regards, Laurent Pinchart
Re: [PATCH v8 00/14] drm/tegra: Introduce a modern UABI
On 7/14/21 5:50 PM, Dmitry Osipenko wrote: 14.07.2021 11:30, Thierry Reding пишет: On Sat, Jul 10, 2021 at 12:16:28AM +0300, Dmitry Osipenko wrote: Hello Thierry, 09.07.2021 22:31, Thierry Reding пишет: From: Thierry Reding Hi all, Mikko has been away for a few weeks, so I've been testing and revising the new UABI patches in the meantime. There are very minor changes to the naming of some of the UABI fields, but other than that it's mostly unchanged from v7. Why you haven't addressed any of the previous review comments? There were some obvious problems in v7 and v8 still has them. One notable change is that mappings can now be read-only, write-only, read-write or none of them (rather than just read-only or read-write), since those combinations are all supported by the IOMMUs and it might be useful to make some mappings write-only. For a full list of changes in v8, see the changelog in patch 6. I've also updated the libdrm_tegra library to work against this version of the UABI. A branch can be found here: https://gitlab.freedesktop.org/tagr/drm/-/commits/drm-tegra-uabi-v8 That contains helper APIs for the concepts introduced in this series and shows how they can be used in various tests that can be run for sanity checking. In addition, Mikko has made updates to the following projects, though they may need to be updated for the minor changes in v8: * vaapi-tegra-driver - https://github.com/cyndis/vaapi-tegra-driver Experimental support for MPEG2 and H264 decoding on T210, T186 and T194. * xf86-video-opentegra - https://github.com/grate-driver/xf86-video-opentegra X11 userspace acceleration driver for Tegra20, Tegra30, and Tegra114. * grate - https://github.com/grate-driver/grate 3D rendering testbed for Tegra20, Tegra30, and Tegra114 I plan on putting this into linux-next soon after v5.14-rc1 so that this can get some soak time. It should be a bit too early to push it into kernel. The UAPI is not ready because it's missing essential features. We can't call this a 'modern UABI' until it's fully implemented. The design decisions are still questionable because this UAPI is built around the proprietary firmware (and based on UAPI of downstream driver) which doesn't fit well into DRM world. I haven't got all the answers to my previous questions, should I repeat them? I don't know what you means by "built around the proprietary firmware". Yes, this ends up using proprietary firmware for some of the hardware engines that host1x drives, but that's completely orthogonal to the UABI. No matter what UABI we'd be introducing, we'd be using that same firmware. And yes, this is based on the UABI of the downstream drivers. The design is guided by what we've learned over the last decade working with this hardware in use-cases that customers need. It'd be dumb not to use that knowledge to our advantage. This is the only way to ensure we can deliver an upstream driver that's on par with our downstream drivers and therefore make it possible to eventually adopt the upstream driver. And frankly, you did get answers to previous questions, though perhaps not all, but I'm out of patience. We've been going in circles and at some point we have to make a decision so we can make progress. By firmware I was referring to the supervisor OS and inter-VM integration, sorry for not making it clear. My rough understanding is that it's all software defined and technically it's possible to avoid going though the trouble of supporting the firmware convention defined by downstream, and thus, making driver less optimal than it could be. It's still not clear to me how much that firmware is relevant to upstream in practice. As mentioned in discussion elsewhere, there is no 'firmware convention'. The view I've formed so far is that the model of ephemeral syncpoint allocations and value resets, which I believe you are talking about here, is fundamentally opposed to the design intent of the hardware, and would result in a less efficient system regardless of inter-VM integration convention. I made several attempts over the years to get something usable merged upstream so that we can finally make use of this hardware and get it supported upstream and each time I made the mistake of trying to make it perfect and accomodate all wishlist items. The result is that I wasted a lot of time and have nothing to show for it. It's a problem that you try to do everything on your own and not collaborating as much as you could. Writing code isn't a problem, the problem is that there is no clear understanding of what needs to be done, IMO. I have a vision of whats need to be done from a perspective of older SoCs, but I never could start implementing it for upstream because it requires yours feedback and preliminary agreement since you're the only maintainer of the driver who could merge patches I don't want to waste my time too. I've also been very hard Mikko with his work on this and I think we've stretched
Re: [PATCH] drm/ttm: add a check against null pointer dereference
Am 14.07.21 um 16:54 schrieb Zheyu Ma: When calling ttm_range_man_fini(), 'man' may be uninitialized, which may cause a null pointer dereference bug. Fix this by checking if it is a null pointer. It would be better if the driver doesn't try to fini a manager which was never initialized, but for now that should work. This log reveals it: [7.902580 ] BUG: kernel NULL pointer dereference, address: 0058 [7.905721 ] RIP: 0010:ttm_range_man_fini+0x40/0x160 [7.911826 ] Call Trace: [7.911826 ] radeon_ttm_fini+0x167/0x210 [7.911826 ] radeon_bo_fini+0x15/0x40 [7.913767 ] rs400_fini+0x55/0x80 [7.914358 ] radeon_device_fini+0x3c/0x140 [7.914358 ] radeon_driver_unload_kms+0x5c/0xe0 [7.914358 ] radeon_driver_load_kms+0x13a/0x200 [7.914358 ] ? radeon_driver_unload_kms+0xe0/0xe0 [7.914358 ] drm_dev_register+0x1db/0x290 [7.914358 ] radeon_pci_probe+0x16a/0x230 [7.914358 ] local_pci_probe+0x4a/0xb0 Signed-off-by: Zheyu Ma Reviewed-by: Christian König Going to push it later. Thanks, Christian. --- drivers/gpu/drm/ttm/ttm_range_manager.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/ttm/ttm_range_manager.c b/drivers/gpu/drm/ttm/ttm_range_manager.c index 03395386e8a7..f4b08a8705b3 100644 --- a/drivers/gpu/drm/ttm/ttm_range_manager.c +++ b/drivers/gpu/drm/ttm/ttm_range_manager.c @@ -181,6 +181,9 @@ int ttm_range_man_fini(struct ttm_device *bdev, struct drm_mm *mm = >mm; int ret; + if (!man) + return 0; + ttm_resource_manager_set_used(man, false); ret = ttm_resource_manager_evict_all(bdev, man);
Re: nouveau: failed to initialise sync
On Wed, Jul 14, 2021 at 03:02:21PM +0200, Christian König wrote: > Am 14.07.21 um 14:56 schrieb Kirill A. Shutemov: > > On Tue, Jul 06, 2021 at 08:58:37AM +0200, Christian König wrote: > > > Hi guys, > > > > > > yes nouveau was using the same functionality for internal BOs without > > > noticing it. This is fixes by the following commit: > > > > > > commit d098775ed44021293b1962dea61efb19297b8d02 > > > Author: Christian König > > > Date: Wed Jun 9 19:25:56 2021 +0200 > > > > > > drm/nouveau: init the base GEM fields for internal BOs > > > > > > TTMs buffer objects are based on GEM objects for quite a while > > > and rely on initializing those fields before initializing the TTM BO. > > > > > > Nouveau now doesn't init the GEM object for internally allocated BOs, > > > so make sure that we at least initialize some necessary fields. > > > > > > Could be that the patch needs to be send to stable as well. > > The regression is present in v5.14-rc1. Any idea when it will hit > > upstream? I don't see it being applied to drm=next. > > Well that question needs to answer Dave or somebody else from the drm-misc > maintainer team. > > This fix together with some others are already in drm-misc-next-fixes > waiting to be pushed upstream, but it looks like that hasn't happened yet. > > Even Linus already pinged me where the fix for qxl got stuck. Yeah there was some missed patches. drm-misc-fixes is now in drm-fixes, and drm-misc-next-fixes is included in drm-misc-fixes, for which Thomas will do a pull request on Thu so it will land in -rc2. It should also now be in linux-next. But yes somehow bugfixes got a bit lost during the merge window. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
[PATCH resend 2/5] video: fbdev: ssd1307fb: Simplify ssd1307fb_update_display()
Simplify the nested loops to handle conversion from linear frame buffer to ssd1307 page layout: 1. Move last page handling one level up, as the value of "m" is the same inside a page, 2. array->data[] is filled linearly, so there is no need to recalculate array_idx over and over again; a simple increment is sufficient. Signed-off-by: Geert Uytterhoeven --- drivers/video/fbdev/ssd1307fb.c | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index e6b6263e3bef847f..6d7bd025bca1a175 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -158,6 +158,7 @@ static int ssd1307fb_update_display(struct ssd1307fb_par *par) u8 *vmem = par->info->screen_buffer; unsigned int line_length = par->info->fix.line_length; unsigned int pages = DIV_ROUND_UP(par->height, 8); + u32 array_idx = 0; int ret, i, j, k; array = ssd1307fb_alloc_array(par->width * pages, SSD1307FB_DATA); @@ -194,19 +195,21 @@ static int ssd1307fb_update_display(struct ssd1307fb_par *par) */ for (i = 0; i < pages; i++) { + int m = 8; + + /* Last page may be partial */ + if (i + 1 == pages && par->height % 8) + m = par->height % 8; for (j = 0; j < par->width; j++) { - int m = 8; - u32 array_idx = i * par->width + j; - array->data[array_idx] = 0; - /* Last page may be partial */ - if (i + 1 == pages && par->height % 8) - m = par->height % 8; + u8 data = 0; + for (k = 0; k < m; k++) { u8 byte = vmem[(8 * i + k) * line_length + j / 8]; u8 bit = (byte >> (j % 8)) & 1; - array->data[array_idx] |= bit << k; + data |= bit << k; } + array->data[array_idx++] = data; } } -- 2.25.1
[PATCH resend 5/5] video: fbdev: ssd1307fb: Cache address ranges
Cache the column and page ranges, to avoid doing unneeded I2C transfers when the values haven't changed. Signed-off-by: Geert Uytterhoeven --- drivers/video/fbdev/ssd1307fb.c | 52 +++-- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 8e3d4be74723b9bf..23b43ce479898813 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -82,6 +82,11 @@ struct ssd1307fb_par { struct regulator *vbat_reg; u32 vcomh; u32 width; + /* Cached address ranges */ + u8 col_start; + u8 col_end; + u8 page_start; + u8 page_end; }; struct ssd1307fb_array { @@ -160,28 +165,43 @@ static int ssd1307fb_set_address_range(struct ssd1307fb_par *par, u8 col_start, int ret; /* Set column range */ - ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COL_RANGE); - if (ret < 0) - return ret; + if (col_start != par->col_start || col_end != par->col_end) { + ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COL_RANGE); + if (ret < 0) + return ret; - ret = ssd1307fb_write_cmd(par->client, col_start); - if (ret < 0) - return ret; + ret = ssd1307fb_write_cmd(par->client, col_start); + if (ret < 0) + return ret; - ret = ssd1307fb_write_cmd(par->client, col_end); - if (ret < 0) - return ret; + ret = ssd1307fb_write_cmd(par->client, col_end); + if (ret < 0) + return ret; + + par->col_start = col_start; + par->col_end = col_end; + } /* Set page range */ - ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PAGE_RANGE); - if (ret < 0) - return ret; + if (page_start != par->page_start || page_end != par->page_end) { + ret = ssd1307fb_write_cmd(par->client, + SSD1307FB_SET_PAGE_RANGE); + if (ret < 0) + return ret; - ret = ssd1307fb_write_cmd(par->client, page_start); - if (ret < 0) - return ret; + ret = ssd1307fb_write_cmd(par->client, page_start); + if (ret < 0) + return ret; + + ret = ssd1307fb_write_cmd(par->client, page_end); + if (ret < 0) + return ret; - return ssd1307fb_write_cmd(par->client, page_end); + par->page_start = page_start; + par->page_end = page_end; + } + + return 0; } static int ssd1307fb_update_rect(struct ssd1307fb_par *par, unsigned int x, -- 2.25.1
[PATCH resend 0/5] video: fbdev: ssd1307fb: Optimizations and improvements
Hi all, This patch series optimizes console operations on ssd1307fb, after the customary fixes and cleanups. Currently, each screen update triggers an I2C transfer of all screen data, up to 1 KiB of data for a 128x64 display, which takes at least 20 ms in Fast mode. While many displays are smaller, and thus require less data to be transferred, 20 ms is still an optimistic value, as the actual data transfer may be much slower, especially on bitbanged I2C drivers. After this series, the amount of data transfer is reduced, as fillrect, copyarea, and imageblit only update the rectangle that changed. This has been tested on an Adafruit FeatherWing OLED with an SSD1306 controller and a 128x32 OLED, connected to an OrangeCrab ECP5 FPGA board running a 64 MHz VexRiscv RISC-V softcore, where it reduced the CPU usage for blinking the cursor from more than 70% to ca. 10%. Thanks for your comments! Geert Uytterhoeven (5): video: fbdev: ssd1307fb: Propagate errors via ssd1307fb_update_display() video: fbdev: ssd1307fb: Simplify ssd1307fb_update_display() video: fbdev: ssd1307fb: Extract ssd1307fb_set_address_range() video: fbdev: ssd1307fb: Optimize screen updates video: fbdev: ssd1307fb: Cache address ranges drivers/video/fbdev/ssd1307fb.c | 143 +--- 1 file changed, 96 insertions(+), 47 deletions(-) -- 2.25.1 Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
[PATCH resend 4/5] video: fbdev: ssd1307fb: Optimize screen updates
Currently, each screen update triggers an I2C transfer of all screen data, up to 1 KiB of data for a 128x64 display, which takes at least 20 ms in Fast mode. Reduce the amount of transferred data by only updating the rectangle that changed. Remove the call to ssd1307fb_set_address_range() during initialization, as ssd1307fb_update_rect() now takes care of that. Note that for now the optimized operation is only used for fillrect, copyarea, and imageblit, which are used by fbcon. Signed-off-by: Geert Uytterhoeven --- drivers/video/fbdev/ssd1307fb.c | 43 - 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index cfa27ea0feab4f01..8e3d4be74723b9bf 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -184,16 +184,18 @@ static int ssd1307fb_set_address_range(struct ssd1307fb_par *par, u8 col_start, return ssd1307fb_write_cmd(par->client, page_end); } -static int ssd1307fb_update_display(struct ssd1307fb_par *par) +static int ssd1307fb_update_rect(struct ssd1307fb_par *par, unsigned int x, +unsigned int y, unsigned int width, +unsigned int height) { struct ssd1307fb_array *array; u8 *vmem = par->info->screen_buffer; unsigned int line_length = par->info->fix.line_length; - unsigned int pages = DIV_ROUND_UP(par->height, 8); + unsigned int pages = DIV_ROUND_UP(height + y % 8, 8); u32 array_idx = 0; int ret, i, j, k; - array = ssd1307fb_alloc_array(par->width * pages, SSD1307FB_DATA); + array = ssd1307fb_alloc_array(width * pages, SSD1307FB_DATA); if (!array) return -ENOMEM; @@ -226,13 +228,18 @@ static int ssd1307fb_update_display(struct ssd1307fb_par *par) * (5) A4 B4 C4 D4 E4 F4 G4 H4 */ - for (i = 0; i < pages; i++) { + ret = ssd1307fb_set_address_range(par, par->col_offset + x, width, + par->page_offset + y / 8, pages); + if (ret < 0) + goto out_free; + + for (i = y / 8; i < y / 8 + pages; i++) { int m = 8; /* Last page may be partial */ - if (i + 1 == pages && par->height % 8) + if (8 * (i + 1) > par->height) m = par->height % 8; - for (j = 0; j < par->width; j++) { + for (j = x; j < x + width; j++) { u8 data = 0; for (k = 0; k < m; k++) { @@ -245,11 +252,17 @@ static int ssd1307fb_update_display(struct ssd1307fb_par *par) } } - ret = ssd1307fb_write_array(par->client, array, par->width * pages); + ret = ssd1307fb_write_array(par->client, array, width * pages); + +out_free: kfree(array); return ret; } +static int ssd1307fb_update_display(struct ssd1307fb_par *par) +{ + return ssd1307fb_update_rect(par, 0, 0, par->width, par->height); +} static ssize_t ssd1307fb_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos) @@ -299,21 +312,24 @@ static void ssd1307fb_fillrect(struct fb_info *info, const struct fb_fillrect *r { struct ssd1307fb_par *par = info->par; sys_fillrect(info, rect); - ssd1307fb_update_display(par); + ssd1307fb_update_rect(par, rect->dx, rect->dy, rect->width, + rect->height); } static void ssd1307fb_copyarea(struct fb_info *info, const struct fb_copyarea *area) { struct ssd1307fb_par *par = info->par; sys_copyarea(info, area); - ssd1307fb_update_display(par); + ssd1307fb_update_rect(par, area->dx, area->dy, area->width, + area->height); } static void ssd1307fb_imageblit(struct fb_info *info, const struct fb_image *image) { struct ssd1307fb_par *par = info->par; sys_imageblit(info, image); - ssd1307fb_update_display(par); + ssd1307fb_update_rect(par, image->dx, image->dy, image->width, + image->height); } static const struct fb_ops ssd1307fb_ops = { @@ -493,13 +509,6 @@ static int ssd1307fb_init(struct ssd1307fb_par *par) if (ret < 0) return ret; - /* Set column and page range */ - ret = ssd1307fb_set_address_range(par, par->col_offset, par->width, - par->page_offset, - DIV_ROUND_UP(par->height, 8)); - if (ret < 0) - return ret; - /* Clear the screen */ ret = ssd1307fb_update_display(par); if (ret < 0) -- 2.25.1
[PATCH resend 3/5] video: fbdev: ssd1307fb: Extract ssd1307fb_set_address_range()
Extract the code to set the column and page ranges into a helper function. Signed-off-by: Geert Uytterhoeven --- drivers/video/fbdev/ssd1307fb.c | 61 +++-- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 6d7bd025bca1a175..cfa27ea0feab4f01 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -152,6 +152,38 @@ static inline int ssd1307fb_write_cmd(struct i2c_client *client, u8 cmd) return ret; } +static int ssd1307fb_set_address_range(struct ssd1307fb_par *par, u8 col_start, + u8 cols, u8 page_start, u8 pages) +{ + u8 col_end = col_start + cols - 1; + u8 page_end = page_start + pages - 1; + int ret; + + /* Set column range */ + ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COL_RANGE); + if (ret < 0) + return ret; + + ret = ssd1307fb_write_cmd(par->client, col_start); + if (ret < 0) + return ret; + + ret = ssd1307fb_write_cmd(par->client, col_end); + if (ret < 0) + return ret; + + /* Set page range */ + ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PAGE_RANGE); + if (ret < 0) + return ret; + + ret = ssd1307fb_write_cmd(par->client, page_start); + if (ret < 0) + return ret; + + return ssd1307fb_write_cmd(par->client, page_end); +} + static int ssd1307fb_update_display(struct ssd1307fb_par *par) { struct ssd1307fb_array *array; @@ -461,31 +493,10 @@ static int ssd1307fb_init(struct ssd1307fb_par *par) if (ret < 0) return ret; - /* Set column range */ - ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COL_RANGE); - if (ret < 0) - return ret; - - ret = ssd1307fb_write_cmd(par->client, par->col_offset); - if (ret < 0) - return ret; - - ret = ssd1307fb_write_cmd(par->client, par->col_offset + par->width - 1); - if (ret < 0) - return ret; - - /* Set page range */ - ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PAGE_RANGE); - if (ret < 0) - return ret; - - ret = ssd1307fb_write_cmd(par->client, par->page_offset); - if (ret < 0) - return ret; - - ret = ssd1307fb_write_cmd(par->client, - par->page_offset + - DIV_ROUND_UP(par->height, 8) - 1); + /* Set column and page range */ + ret = ssd1307fb_set_address_range(par, par->col_offset, par->width, + par->page_offset, + DIV_ROUND_UP(par->height, 8)); if (ret < 0) return ret; -- 2.25.1
[PATCH resend 1/5] video: fbdev: ssd1307fb: Propagate errors via ssd1307fb_update_display()
Make ssd1307fb_update_display() return an error code, so callers that can handle failures can propagate it. Signed-off-by: Geert Uytterhoeven --- drivers/video/fbdev/ssd1307fb.c | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index eda448b7a0c9d8ce..e6b6263e3bef847f 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -152,17 +152,17 @@ static inline int ssd1307fb_write_cmd(struct i2c_client *client, u8 cmd) return ret; } -static void ssd1307fb_update_display(struct ssd1307fb_par *par) +static int ssd1307fb_update_display(struct ssd1307fb_par *par) { struct ssd1307fb_array *array; u8 *vmem = par->info->screen_buffer; unsigned int line_length = par->info->fix.line_length; unsigned int pages = DIV_ROUND_UP(par->height, 8); - int i, j, k; + int ret, i, j, k; array = ssd1307fb_alloc_array(par->width * pages, SSD1307FB_DATA); if (!array) - return; + return -ENOMEM; /* * The screen is divided in pages, each having a height of 8 @@ -210,8 +210,9 @@ static void ssd1307fb_update_display(struct ssd1307fb_par *par) } } - ssd1307fb_write_array(par->client, array, par->width * pages); + ret = ssd1307fb_write_array(par->client, array, par->width * pages); kfree(array); + return ret; } @@ -222,6 +223,7 @@ static ssize_t ssd1307fb_write(struct fb_info *info, const char __user *buf, unsigned long total_size; unsigned long p = *ppos; void *dst; + int ret; total_size = info->fix.smem_len; @@ -239,7 +241,9 @@ static ssize_t ssd1307fb_write(struct fb_info *info, const char __user *buf, if (copy_from_user(dst, buf, count)) return -EFAULT; - ssd1307fb_update_display(par); + ret = ssd1307fb_update_display(par); + if (ret < 0) + return ret; *ppos += count; @@ -483,7 +487,9 @@ static int ssd1307fb_init(struct ssd1307fb_par *par) return ret; /* Clear the screen */ - ssd1307fb_update_display(par); + ret = ssd1307fb_update_display(par); + if (ret < 0) + return ret; /* Turn on the display */ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_ON); -- 2.25.1
[PATCH resend v2] dt-bindings: display: ssd1307fb: Convert to json-schema
Convert the Solomon SSD1307 Framebuffer Device Tree binding documentation to json-schema. Fix the spelling of the "pwms" property. Document default values. Make properties with default values not required. Signed-off-by: Geert Uytterhoeven Reviewed-by: Rob Herring --- v2: - Add Reviewed-by, - Document solomon,dclk-{div,freq} defaults. --- .../bindings/display/solomon,ssd1307fb.yaml | 208 ++ .../devicetree/bindings/display/ssd1307fb.txt | 60 - 2 files changed, 208 insertions(+), 60 deletions(-) create mode 100644 Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml delete mode 100644 Documentation/devicetree/bindings/display/ssd1307fb.txt diff --git a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml new file mode 100644 index ..2ed2a7d0ca2fa23e --- /dev/null +++ b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml @@ -0,0 +1,208 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/solomon,ssd1307fb.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Solomon SSD1307 OLED Controller Framebuffer + +maintainers: + - Maxime Ripard + +properties: + compatible: +enum: + - solomon,ssd1305fb-i2c + - solomon,ssd1306fb-i2c + - solomon,ssd1307fb-i2c + - solomon,ssd1309fb-i2c + + reg: +maxItems: 1 + + pwms: +maxItems: 1 + + reset-gpios: +maxItems: 1 + + vbat-supply: +description: The supply for VBAT + + solomon,height: +$ref: /schemas/types.yaml#/definitions/uint32 +default: 16 +description: + Height in pixel of the screen driven by the controller + + solomon,width: +$ref: /schemas/types.yaml#/definitions/uint32 +default: 96 +description: + Width in pixel of the screen driven by the controller + + solomon,page-offset: +$ref: /schemas/types.yaml#/definitions/uint32 +default: 1 +description: + Offset of pages (band of 8 pixels) that the screen is mapped to + + solomon,segment-no-remap: +type: boolean +description: + Display needs normal (non-inverted) data column to segment mapping + + solomon,col-offset: +$ref: /schemas/types.yaml#/definitions/uint32 +default: 0 +description: + Offset of columns (COL/SEG) that the screen is mapped to + + solomon,com-seq: +type: boolean +description: + Display uses sequential COM pin configuration + + solomon,com-lrremap: +type: boolean +description: + Display uses left-right COM pin remap + + solomon,com-invdir: +type: boolean +description: + Display uses inverted COM pin scan direction + + solomon,com-offset: +$ref: /schemas/types.yaml#/definitions/uint32 +default: 0 +description: + Number of the COM pin wired to the first display line + + solomon,prechargep1: +$ref: /schemas/types.yaml#/definitions/uint32 +default: 2 +description: + Length of deselect period (phase 1) in clock cycles + + solomon,prechargep2: +$ref: /schemas/types.yaml#/definitions/uint32 +default: 2 +description: + Length of precharge period (phase 2) in clock cycles. This needs to be + the higher, the higher the capacitance of the OLED's pixels is. + + solomon,dclk-div: +$ref: /schemas/types.yaml#/definitions/uint32 +minimum: 1 +maximum: 16 +description: + Clock divisor. The default value is controller-dependent. + + solomon,dclk-frq: +$ref: /schemas/types.yaml#/definitions/uint32 +minimum: 0 +maximum: 15 +description: + Clock frequency, higher value means higher frequency. + The default value is controller-dependent. + + solomon,lookup-table: +$ref: /schemas/types.yaml#/definitions/uint8-array +maxItems: 4 +description: + 8 bit value array of current drive pulse widths for BANK0, and colors A, + B, and C. Each value in range of 31 to 63 for pulse widths of 32 to 64. + Color D is always width 64. + + solomon,area-color-enable: +type: boolean +description: + Display uses color mode + + solomon,low-power: +type: boolean +description: + Display runs in low power mode + +required: + - compatible + - reg + +allOf: + - if: + properties: +compatible: + contains: +const: solomon,ssd1305fb-i2c +then: + properties: +solomon,dclk-div: + default: 1 +solomon,dclk-frq: + default: 7 + + - if: + properties: +compatible: + contains: +const: solomon,ssd1306fb-i2c +then: + properties: +solomon,dclk-div: + default: 1 +solomon,dclk-frq: + default: 8 + + - if: + properties: +compatible: + contains: +const: solomon,ssd1307fb-i2c +then: + properties: +
[Bug 209457] AMDGPU resume fail with RX 580 GPU
https://bugzilla.kernel.org/show_bug.cgi?id=209457 --- Comment #36 from Leandro Jacques (ls...@yahoo.com) --- Created attachment 297855 --> https://bugzilla.kernel.org/attachment.cgi?id=297855=edit Kernel crash log for linux firmware version 20210511.7685cf4 Kernel log when crashed. -- 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 209457] AMDGPU resume fail with RX 580 GPU
https://bugzilla.kernel.org/show_bug.cgi?id=209457 Leandro Jacques (ls...@yahoo.com) changed: What|Removed |Added Attachment #297851|0 |1 is obsolete|| --- Comment #35 from Leandro Jacques (ls...@yahoo.com) --- Created attachment 297853 --> https://bugzilla.kernel.org/attachment.cgi?id=297853=edit Linux Firmware version info 20210511.7685cf4 Firmware version when crashed -- 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 209457] AMDGPU resume fail with RX 580 GPU
https://bugzilla.kernel.org/show_bug.cgi?id=209457 --- Comment #34 from Leandro Jacques (ls...@yahoo.com) --- Created attachment 297851 --> https://bugzilla.kernel.org/attachment.cgi?id=297851=edit Linux Firmware version info 20210511.7685cf4 -- 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 v8 00/14] drm/tegra: Introduce a modern UABI
14.07.2021 11:30, Thierry Reding пишет: > On Sat, Jul 10, 2021 at 12:16:28AM +0300, Dmitry Osipenko wrote: >> Hello Thierry, >> >> 09.07.2021 22:31, Thierry Reding пишет: >>> From: Thierry Reding >>> >>> Hi all, >>> >>> Mikko has been away for a few weeks, so I've been testing and revising >>> the new UABI patches in the meantime. There are very minor changes to >>> the naming of some of the UABI fields, but other than that it's mostly >>> unchanged from v7. >> >> Why you haven't addressed any of the previous review comments? There >> were some obvious problems in v7 and v8 still has them. >> >>> One notable change is that mappings can now be read-only, write-only, >>> read-write or none of them (rather than just read-only or read-write), >>> since those combinations are all supported by the IOMMUs and it might >>> be useful to make some mappings write-only. >>> >>> For a full list of changes in v8, see the changelog in patch 6. >>> >>> I've also updated the libdrm_tegra library to work against this version >>> of the UABI. A branch can be found here: >>> >>> https://gitlab.freedesktop.org/tagr/drm/-/commits/drm-tegra-uabi-v8 >>> >>> That contains helper APIs for the concepts introduced in this series and >>> shows how they can be used in various tests that can be run for sanity >>> checking. >>> >>> In addition, Mikko has made updates to the following projects, though >>> they may need to be updated for the minor changes in v8: >>> >>> * vaapi-tegra-driver - https://github.com/cyndis/vaapi-tegra-driver >>> Experimental support for MPEG2 and H264 decoding on T210, T186 >>> and T194. >>> >>> * xf86-video-opentegra - >>> https://github.com/grate-driver/xf86-video-opentegra >>> X11 userspace acceleration driver for Tegra20, Tegra30, and Tegra114. >>> >>> * grate - https://github.com/grate-driver/grate >>> 3D rendering testbed for Tegra20, Tegra30, and Tegra114 >>> >>> I plan on putting this into linux-next soon after v5.14-rc1 so that this >>> can get some soak time. >> >> It should be a bit too early to push it into kernel. The UAPI is not >> ready because it's missing essential features. We can't call this a >> 'modern UABI' until it's fully implemented. The design decisions are >> still questionable because this UAPI is built around the proprietary >> firmware (and based on UAPI of downstream driver) which doesn't fit well >> into DRM world. I haven't got all the answers to my previous questions, >> should I repeat them? > > I don't know what you means by "built around the proprietary firmware". > Yes, this ends up using proprietary firmware for some of the hardware > engines that host1x drives, but that's completely orthogonal to the > UABI. No matter what UABI we'd be introducing, we'd be using that same > firmware. > > And yes, this is based on the UABI of the downstream drivers. The design > is guided by what we've learned over the last decade working with this > hardware in use-cases that customers need. It'd be dumb not to use that > knowledge to our advantage. This is the only way to ensure we can > deliver an upstream driver that's on par with our downstream drivers and > therefore make it possible to eventually adopt the upstream driver. > > And frankly, you did get answers to previous questions, though perhaps > not all, but I'm out of patience. We've been going in circles and at > some point we have to make a decision so we can make progress. By firmware I was referring to the supervisor OS and inter-VM integration, sorry for not making it clear. My rough understanding is that it's all software defined and technically it's possible to avoid going though the trouble of supporting the firmware convention defined by downstream, and thus, making driver less optimal than it could be. It's still not clear to me how much that firmware is relevant to upstream in practice. > I made several attempts over the years to get something usable merged > upstream so that we can finally make use of this hardware and get it > supported upstream and each time I made the mistake of trying to make it > perfect and accomodate all wishlist items. The result is that I wasted a > lot of time and have nothing to show for it. It's a problem that you try to do everything on your own and not collaborating as much as you could. Writing code isn't a problem, the problem is that there is no clear understanding of what needs to be done, IMO. I have a vision of whats need to be done from a perspective of older SoCs, but I never could start implementing it for upstream because it requires yours feedback and preliminary agreement since you're the only maintainer of the driver who could merge patches I don't want to waste my time too. > I've also been very hard Mikko with his work on this and I think we've > stretched this as far as we can without compromising too much on what we > are going to need from this UABI in the future. > > We've gone through the process of making sure all existing userspace can > and
[PATCH v2] drm/of: free the iterator object on failure
When bailing out due to the sanity check the iterator value needs to be freed because the early return prevents for_each_child_of_node() from doing the dereference itself. Fixes: 6529007522de ("drm: of: Add drm_of_lvds_get_dual_link_pixel_order") Signed-off-by: Steven Price --- drivers/gpu/drm/drm_of.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) v2: Fixes now refers to the original commit as suggested by Laurent, rather than 4ee48cc5586b ("drm: of: Fix double-free bug") which only fixed part of the problem. Note that 4ee48cc5586b is a dependency for this patch to cleanly apply. diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 197c57477344..997b8827fed2 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -331,8 +331,10 @@ static int drm_of_lvds_get_remote_pixels_type( * configurations by passing the endpoints explicitly to * drm_of_lvds_get_dual_link_pixel_order(). */ - if (!current_pt || pixels_type != current_pt) + if (!current_pt || pixels_type != current_pt) { + of_node_put(endpoint); return -EINVAL; + } } return pixels_type; -- 2.20.1
Re: [PATCH] drm: mxsfb: Clear FIFO_CLEAR bit
Am Donnerstag, dem 01.07.2021 um 00:50 +0200 schrieb Marek Vasut: > On 6/29/21 10:02 AM, Lucas Stach wrote: > > Am Dienstag, dem 29.06.2021 um 05:04 +0200 schrieb Marek Vasut: > > > On 6/28/21 10:09 AM, Lucas Stach wrote: > > > > Am Samstag, dem 26.06.2021 um 20:15 +0200 schrieb Marek Vasut: > > > > > On 6/24/21 2:01 PM, Lucas Stach wrote: > > > > > > Am Dienstag, dem 22.06.2021 um 11:33 +0200 schrieb Marek Vasut: > > > > > > > On 6/22/21 9:28 AM, Lucas Stach wrote: > > > > > > > > Am Montag, dem 21.06.2021 um 18:30 +0200 schrieb Marek Vasut: > > > > > > > > > On 6/21/21 2:14 PM, Lucas Stach wrote: > > > > > > > > > > > > > > > > > > [...] > > > > > > > > > > > > > > > > > > > > diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c > > > > > > > > > > > b/drivers/gpu/drm/mxsfb/mxsfb_kms.c > > > > > > > > > > > index 98d8ba0bae84..22cb749fc9bc 100644 > > > > > > > > > > > --- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c > > > > > > > > > > > +++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c > > > > > > > > > > > @@ -241,6 +241,9 @@ static void > > > > > > > > > > > mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb, > > > > > > > > > > > > > > > > > > > > > > /* Clear the FIFOs */ > > > > > > > > > > > writel(CTRL1_FIFO_CLEAR, mxsfb->base + > > > > > > > > > > > LCDC_CTRL1 + REG_SET); > > > > > > > > > > > + readl(mxsfb->base + LCDC_CTRL1); > > > > > > > > > > > > > > > > > > > > Do you really need those readbacks? As both writes are > > > > > > > > > > targeting the > > > > > > > > > > same slave interface, the memory barrier in the clear write > > > > > > > > > > should push > > > > > > > > > > the set write. > > > > > > > > > > > > > > > > > > What would push the clear write then ? We can drop one of the > > > > > > > > > readl()s, > > > > > > > > > but not the last one. > > > > > > > > > > > > > > > > There are a lot of more writes with barriers to the controller > > > > > > > > slave > > > > > > > > interface in that function after clearing the FIFO. I don't see > > > > > > > > why > > > > > > > > this readback would be required. > > > > > > > > > > > > > > Because you really do want to make sure the fifo is cleared > > > > > > > before you > > > > > > > start doing any of those other writes or configuring the > > > > > > > controller in > > > > > > > any way. > > > > > > > > > > > > I still don't see the reason. What additional properties do you > > > > > > think > > > > > > the readback provides that isn't already provided by the barriers in > > > > > > the following writes? > > > > > > > > > > See the paragraph above -- we have to make sure the writes that > > > > > trigger > > > > > the FIFO clearing really take place before any other writes do. > > > > > > > > And they do, as there are write barriers prepended to the writes > > > > following the FIFO clear. The readback just lets the CPU wait until the > > > > write reached the peripheral, which I don't see a reason to do here. > > > > The ordering of the writes from the perspective of the peripheral is > > > > completely the same with or without the readback. The later writes can > > > > not overtake the FIFO clear writes due to the barriers. > > > > > > > > I'm strongly against adding stuff because it "might have an effect", if > > > > it isn't required by architectural rules. It clutters the code and some > > > > months/years down the line nobody dares to cleanup/remove this stuff > > > > anymore, because everyone assumes that there was a good reason for > > > > adding those things. > > > > > > Since there is no RTL for any of the iMXes or their IPs, how do you > > > propose anyone except NXP can validate what is and what is not required ? > > > > > > This patch helps with a problem where I sporadically observe shifted > > > image on boot on mx8mm. > > > > The order of writes to a device mapped region are defined by the ARM > > architecture and the AMBA bus standard, not the peripheral. I'm not > > saying this patch isn't needed. I'm saying the readbacks look bogus. > > > > Have you checked that just adding the write to the REG_CLR doesn't fix > > your issue? > > No, it does not help with the issue. Okay, i don't want to hold up this patch over technicalities if it fixes the issue, in which case the readbacks probably provide just the right amount of delay for the FIFO clear to happen in hardware. FWIW: Acked-by: Lucas Stach Regards, Lucas