Re: [PATCH 2/2] drm/i915/gem: Migrate to system at dma-buf attach time (v5)

2021-07-14 Thread Daniel Vetter
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

2021-07-14 Thread Sam Ravnborg
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'

2021-07-14 Thread kernel test robot
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread Stephen Rothwell
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'

2021-07-14 Thread kernel test robot
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

2021-07-14 Thread Doug Anderson
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()

2021-07-14 Thread Yang Yingliang
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

2021-07-14 Thread Belgaumkar, Vinay




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

2021-07-14 Thread Daniele Ceraolo Spurio




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

2021-07-14 Thread Daniele Ceraolo Spurio




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

2021-07-14 Thread Matthew Brost
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+

2021-07-14 Thread Matthew Brost
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

2021-07-14 Thread Matthew Brost
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

2021-07-14 Thread Matthew Brost
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread Jason Gunthorpe
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

2021-07-14 Thread John Harrison

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

2021-07-14 Thread Matthew Brost
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

2021-07-14 Thread Matthew Brost
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

2021-07-14 Thread Matthew Brost
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

2021-07-14 Thread Rob Herring
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

2021-07-14 Thread Linus Walleij
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

2021-07-14 Thread Linus Walleij
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

2021-07-14 Thread abhinavk

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

2021-07-14 Thread Andrey Grodzovsky



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

2021-07-14 Thread Alex Deucher
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'

2021-07-14 Thread kernel test robot
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

2021-07-14 Thread Stephen Boyd
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)

2021-07-14 Thread Jason Ekstrand
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

2021-07-14 Thread Paul Cercueil

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

2021-07-14 Thread Jason Ekstrand
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

2021-07-14 Thread Paul Cercueil

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

2021-07-14 Thread Lyude Paul
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

2021-07-14 Thread Rob Herring
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

2021-07-14 Thread Rob Herring
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'

2021-07-14 Thread kernel test robot
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"

2021-07-14 Thread Jason Ekstrand
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*

2021-07-14 Thread Jason Ekstrand
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

2021-07-14 Thread Jason Ekstrand
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"

2021-07-14 Thread Jason Ekstrand
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"

2021-07-14 Thread Jason Ekstrand
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)

2021-07-14 Thread Jason Ekstrand
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

2021-07-14 Thread Lyude Paul
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

2021-07-14 Thread Lyude Paul
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

2021-07-14 Thread Lyude Paul
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

2021-07-14 Thread bugzilla-daemon
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

2021-07-14 Thread Werner Sembach

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

2021-07-14 Thread Werner Sembach

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

2021-07-14 Thread Werner Sembach

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

2021-07-14 Thread bugzilla-daemon
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

2021-07-14 Thread Jim Cromie
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

2021-07-14 Thread Jim Cromie
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

2021-07-14 Thread Jim Cromie
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

2021-07-14 Thread Jim Cromie
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

2021-07-14 Thread Jim Cromie
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

2021-07-14 Thread Jim Cromie
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

2021-07-14 Thread Rob Herring
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

2021-07-14 Thread Douglas Anderson
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

2021-07-14 Thread Randy Dunlap
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

2021-07-14 Thread Colin King
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

2021-07-14 Thread Sasha Levin

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

2021-07-14 Thread Sasha Levin

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

2021-07-14 Thread Rob Herring
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

2021-07-14 Thread Rob Herring
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

2021-07-14 Thread Rob Herring
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

2021-07-14 Thread Douglas Anderson
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

2021-07-14 Thread Daniel Vetter
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

2021-07-14 Thread Harry Wentland



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

2021-07-14 Thread Felix Kuehling
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

2021-07-14 Thread Sean Paul
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

2021-07-14 Thread Sam Ravnborg
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

2021-07-14 Thread Laurent Pinchart
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

2021-07-14 Thread Mikko Perttunen

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

2021-07-14 Thread Christian König

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

2021-07-14 Thread Daniel Vetter
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()

2021-07-14 Thread Geert Uytterhoeven
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

2021-07-14 Thread Geert Uytterhoeven
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

2021-07-14 Thread Geert Uytterhoeven
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

2021-07-14 Thread Geert Uytterhoeven
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()

2021-07-14 Thread Geert Uytterhoeven
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()

2021-07-14 Thread Geert Uytterhoeven
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

2021-07-14 Thread Geert Uytterhoeven
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

2021-07-14 Thread bugzilla-daemon
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

2021-07-14 Thread bugzilla-daemon
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

2021-07-14 Thread bugzilla-daemon
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

2021-07-14 Thread Dmitry Osipenko
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

2021-07-14 Thread Steven Price
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

2021-07-14 Thread Lucas Stach
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



  1   2   >