Re: [PATCH] fbcon: Check font dimension limits

2023-01-25 Thread Greg KH
On Thu, Jan 26, 2023 at 01:49:12AM +0100, Samuel Thibault wrote:
> blit_x and blit_y are uint32_t, so fbcon currently cannot support fonts
> larger than 32x32.

"u32" you mean, right?

> The 32x32 case also needs shifting an unsigned int, to properly set bit
> 31, otherwise we get "UBSAN: shift-out-of-bounds in fbcon_set_font",
> as reported on
> 
> http://lore.kernel.org/all/ia1pr07mb98308653e259a6f2ce94a4afab...@ia1pr07mb9830.namprd07.prod.outlook.com

Odd blank line?


> Kernel Branch: 6.2.0-rc5-next-20230124
> Kernel config: 
> https://drive.google.com/file/d/1F-LszDAizEEH0ZX0HcSR06v5q8FPl2Uv/view?usp=sharing
> Reproducer: 
> https://drive.google.com/file/d/1mP1jcLBY7vWCNM60OMf-ogw-urQRjNrm/view?usp=sharing

What are all of these lines for?

> 
> Reported-by: Sanan Hasanov 
> Signed-off-by: Samuel Thibault 

What commit id does this fix?  Should it go to stable kernels?

> 
> Index: linux-6.0/drivers/video/fbdev/core/fbcon.c
> ===
> --- linux-6.0.orig/drivers/video/fbdev/core/fbcon.c
> +++ linux-6.0/drivers/video/fbdev/core/fbcon.c
> @@ -2489,9 +2489,12 @@ static int fbcon_set_font(struct vc_data
>   h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres))
>   return -EINVAL;
>  
> + if (font->width > 32 || font->height > 32)
> + return -EINVAL;
> +
>   /* Make sure drawing engine can handle the font */
> - if (!(info->pixmap.blit_x & (1 << (font->width - 1))) ||
> - !(info->pixmap.blit_y & (1 << (font->height - 1
> + if (!(info->pixmap.blit_x & (1U << (font->width - 1))) ||
> + !(info->pixmap.blit_y & (1U << (font->height - 1

Are you sure this is still needed with the above check added?  If so,
why?  What is the difference in the compiled code?

thanks,

greg k-h


Re: [PATCH] dma-buf: actually set signaling bit for private sub fences

2023-01-25 Thread Christian König

Am 26.01.23 um 01:28 schrieb Danilo Krummrich:

In dma_fence_allocate_private_stub() set the signaling bit of the newly
allocated private stub fence rather than the signaling bit of the
shared dma_fence_stub.

Fixes: c85d00d4fd8b ("dma-buf: set signaling bit for the stub fence")
Signed-off-by: Danilo Krummrich 


Good catch, Reviewed-by: Christian König 

Should I push it upstream as well or do you have commit access?


---
  drivers/dma-buf/dma-fence.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 406b4e26f538..0de0482cd36e 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -167,7 +167,7 @@ struct dma_fence *dma_fence_allocate_private_stub(void)
   0, 0);
  
  	set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,

-   _fence_stub.flags);
+   >flags);
  
  	dma_fence_signal(fence);
  




RE: [PATCH v11 0/3] drm: exynos: dsi: Restore the bridge chain

2023-01-25 Thread SR
Hi Jagan Teki,

> -Original Message-
> From: Jagan Teki 
> Sent: Friday, January 20, 2023 3:19 AM
> To: 대인기/Tizen Platform Lab(SR)/삼성전자 
> Cc: Marek Szyprowski ; Seung-Woo Kim
> ; Kyungmin Park ; Neil
> Armstrong ; Robert Foss ;
> Andrzej Hajda ; Sam Ravnborg ;
> thierry.red...@gmail.com; Marek Vasut ; linux-samsung-
> s...@vger.kernel.org; dri-devel@lists.freedesktop.org; linux-amarula  amar...@amarulasolutions.com>
> Subject: Re: [PATCH v11 0/3] drm: exynos: dsi: Restore the bridge chain
> 
> Hi Inki Dae,
> 
> On Thu, Jan 12, 2023 at 7:56 AM 대인기/Tizen Platform Lab(SR)/삼성전자
>  wrote:
> >
> > Hi Jagan Teki,
> >
> > Sorry for late.
> >
> > > -Original Message-
> > > From: Jagan Teki 
> > > Sent: Saturday, January 7, 2023 2:56 AM
> > > To: Marek Szyprowski ; Inki Dae
> > > ; Seung-Woo Kim ; Kyungmin
> Park
> > > ; Neil Armstrong ;
> Robert
> > > Foss ; Andrzej Hajda ;
> Sam
> > > Ravnborg 
> > > Cc: Marek Vasut ; linux-samsung-...@vger.kernel.org; dri-
> > > de...@lists.freedesktop.org; linux-amarula  > > amar...@amarulasolutions.com>
> > > Subject: Re: [PATCH v11 0/3] drm: exynos: dsi: Restore the bridge chain
> > >
> > > On Mon, Dec 12, 2022 at 11:59 PM Jagan Teki 
> wrote:
> > > >
> > > > Split the Exynos DSI bridge chain update patches from Samsung DSIM
> > > > bridge driver for easy to apply.
> > > >
> > > > Changes for v11:
> > > > - enable bridge.pre_enable_prev_first
> > > > Changes for v10:
> > > > - collect Marek.V Review tag
> > >
> > > Any update on this?
> > >
> >
> > Added Thierry Reding who is a maintainer of DRM panel drivers.
> >
> > I will pick this patch series - including panel and bride patches - up.
> >
> > Thierry and Andrzej, please let me know if any problem.
> 
> Any further update on this?

Already merged to exynos-drm-next so this patch series will go to -next as long 
as no feedback from Thierry and Andrzej.
I will request a PR this or next week.

Thanks,
Inki Dae

> 
> Thanks,
> Jagan.




Re: [PATCH 1/4] dt-bindings: display: bridge: tfp410: Add tfp410 i2c example

2023-01-25 Thread Rob Herring


On Wed, 25 Jan 2023 16:09:09 -0500, Jonathan Cormier wrote:
> Add a i2c example with HDMI connector
> 
> Signed-off-by: Jonathan Cormier 
> ---
>  .../bindings/display/bridge/ti,tfp410.yaml | 42 
> ++
>  1 file changed, 42 insertions(+)
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/display/bridge/ti,tfp410.example.dts:77.37-79.19:
 ERROR (duplicate_label): /example-1/i2c/tfp410@38/ports/port@0/endpoint: 
Duplicate label 'tfp410_in' on /example-1/i2c/tfp410@38/ports/port@0/endpoint 
and /example-0/encoder/ports/port@0/endpoint
Documentation/devicetree/bindings/display/bridge/ti,tfp410.example.dts:84.38-86.19:
 ERROR (duplicate_label): /example-1/i2c/tfp410@38/ports/port@1/endpoint: 
Duplicate label 'tfp410_out' on /example-1/i2c/tfp410@38/ports/port@1/endpoint 
and /example-0/encoder/ports/port@1/endpoint
ERROR: Input tree has errors, aborting (use -f to force output)
make[1]: *** [scripts/Makefile.lib:434: 
Documentation/devicetree/bindings/display/bridge/ti,tfp410.example.dtb] Error 2
make[1]: *** Waiting for unfinished jobs
make: *** [Makefile:1508: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See 
https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20230125-tfp410_i2c-v1-1-66a4d4e39...@criticallink.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



Re: [PATCH v2 2/6] drm: lcdif: Drop unnecessary NULL pointer check on lcdif->bridge

2023-01-25 Thread Liu Ying
On Wed, 2023-01-25 at 14:56 +0100, Marek Vasut wrote:
> On 1/25/23 07:40, Liu Ying wrote:
> > A valid bridge is already found in lcdif_attach_bridge() and set
> > to lcdif->bridge, so lcdif->bridge cannot be a NULL pointer. Drop
> > the unnecessary NULL pointer check in KMS stage.
> 
> Is it possible that a panel (instead of a bridge) be attached to
> LCDIFv3 
> e.g. in case of iMXRT ?

According to IMXRT1160 and IMXRT1170 reference manuals, it looks like
LCDIFv2(similar to LCDIFv3, but not the same) may connect to a parallel
display panel through a mux(either eLCDIF or LCDIFv2).  That mux could
be a bridge.  But, it doesn't matter, because devm_drm_of_get_bridge()
may create a panel bridge if a panel is connected directly(See
kerneldoc of devm_drm_of_get_bridge()).

Regards,
Liu Ying

> 
> > Signed-off-by: Liu Ying 
> > ---
> > v1->v2:
> > * Split from patch 2/2 in v1. (Marek, Alexander)
> 
> Much appreciated, thanks.
> 
> [...]



Re: [PATCH v2 18/21] drm/amd/display: Fallback to 2020_YCBCR if the pixel encoding is not RGB

2023-01-25 Thread Sebastian Wick
On Tue, Jan 24, 2023 at 7:57 PM Harry Wentland  wrote:
>
>
>
> On 1/24/23 10:37, Harry Wentland wrote:
> >
> >
> > On 1/23/23 15:30, Sebastian Wick wrote:
> >> A new property to control YCC and subsampling would be the more
> >> complete path here. If we actually want to fix this in the short-term
> >> though, we should handle the YCC and RGB Colorspace values as
> >> equivalent, everywhere. Technically we're breaking the user space API
> >> here so it should be documented on the KMS property and other drivers
> >> must be adjusted accordingly as well.
> >>
> >
> > Could someone point me to a userspace that uses this currently?
> >
>
> To elaborate a bit more...
>
> A driver has always had the ability to pick the wire format, whether
> it'd be RGB or YCbCr (444, or 420). In some cases that selection
> is required in order to satisfy bandwidth requirements. In others
> we follow a certain policy to ensure similar behaviors between our
> Windows and Linux drivers. I don't think it makes sense for userspace
> to control this.

I disagree. The subsampling is degrading the image considerably in
some cases. We need control over this.

It does mean that user space has to be smart and try to reduce the
bandwidth if a KMS commit fails, but the same is true for resolution
and refresh rate right now and will be true for a min bpc property as
well.

> Based on what I see I am not convinced the entirety of the
> colorspace definition has a corresponding implementation in an
> upstream, canonical userspace, hence my question. Not even an IGT
> test existed when I started looking at this. In the absence of a
> missing userspace implementation I am not convinced we're breaking
> anything. Even then, this was never implemented in amdgpu so
> there is no way this regresses any existing behavior.

I don't think this breaks anything in practice. The change would only
break use cases where you want to set the infoframe to a variant which
does not match the wire format and that would be broken. So yes, I
agree.

We can't just remove the enum values though. If we deprecate the YCC
variants that must be documented and user space has to understand that
choosing the RGB variant will result in the kernel just doing the
"right thing".

>
> Harry
>
> > Harry
> >
> >> On Fri, Jan 13, 2023 at 5:26 PM Harry Wentland  
> >> wrote:
> >>>
> >>> From: Joshua Ashton 
> >>>
> >>> Userspace might not aware whether we're sending RGB or YCbCr
> >>> data to the display. If COLOR_SPACE_2020_RGB_FULLRANGE is
> >>> requested but the output encoding is YCbCr we should
> >>> send COLOR_SPACE_2020_YCBCR.
> >>>
> >>> Signed-off-by: Joshua Ashton 
> >>> Signed-off-by: Harry Wentland 
> >>> Cc: Pekka Paalanen 
> >>> Cc: Sebastian Wick 
> >>> Cc: vitaly.pros...@amd.com
> >>> Cc: Joshua Ashton 
> >>> Cc: dri-devel@lists.freedesktop.org
> >>> Cc: amd-...@lists.freedesktop.org
> >>> Reviewed-by: Harry Wentland 
> >>> ---
> >>>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 -
> >>>  1 file changed, 4 insertions(+), 1 deletion(-)
> >>>
> >>> 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 f74b125af31f..16940ea61b59 100644
> >>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >>> @@ -5184,7 +5184,10 @@ get_output_color_space(const struct dc_crtc_timing 
> >>> *dc_crtc_timing,
> >>> color_space = COLOR_SPACE_ADOBERGB;
> >>> break;
> >>> case DRM_MODE_COLORIMETRY_BT2020_RGB:
> >>> -   color_space = COLOR_SPACE_2020_RGB_FULLRANGE;
> >>> +   if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB)
> >>> +   color_space = COLOR_SPACE_2020_RGB_FULLRANGE;
> >>> +   else
> >>> +   color_space = COLOR_SPACE_2020_YCBCR;
> >>> break;
> >>> case DRM_MODE_COLORIMETRY_BT2020_YCC:
> >>> color_space = COLOR_SPACE_2020_YCBCR;
> >>> --
> >>> 2.39.0
> >>>
> >>
> >
>



Re: [LSF/MM/BPF proposal]: Physr discussion

2023-01-25 Thread Zhu Yanjun

在 2023/1/21 23:03, Jason Gunthorpe 写道:

I would like to have a session at LSF to talk about Matthew's
physr discussion starter:

  https://lore.kernel.org/linux-mm/ydykweu0htv8m...@casper.infradead.org/

I have become interested in this with some immediacy because of
IOMMUFD and this other discussion with Christoph:

  
https://lore.kernel.org/kvm/4-v2-472615b3877e+28f7-vfio_dma_buf_...@nvidia.com/


I read through the above patches. I am interested in the dma-buf.

Zhu Yanjun

 
Which results in, more or less, we have no way to do P2P DMA

operations without struct page - and from the RDMA side solving this
well at the DMA API means advancing at least some part of the physr
idea.

So - my objective is to enable to DMA API to "DMA map" something that
is not a scatterlist, may or may not contain struct pages, but can
still contain P2P DMA data. From there I would move RDMA MR's to use
this new API, modify DMABUF to export it, complete the above VFIO
series, and finally, use all of this to add back P2P support to VFIO
when working with IOMMUFD by allowing IOMMUFD to obtain a safe
reference to the VFIO memory using DMABUF. From there we'd want to see
pin_user_pages optimized, and that also will need some discussion how
best to structure it.

I also have several ideas on how something like physr can optimize the
iommu driver ops when working with dma-iommu.c and IOMMUFD.

I've been working on an implementation and hope to have something
draft to show on the lists in a few weeks. It is pretty clear there
are several interesting decisions to make that I think will benefit
from a live discussion.

Providing a kernel-wide alternative to scatterlist is something that
has general interest across all the driver subsystems. I've started to
view the general problem rather like xarray where the main focus is to
create the appropriate abstraction and then go about transforming
users to take advatange of the cleaner abstraction. scatterlist
suffers here because it has an incredibly leaky API, a huge number of
(often sketchy driver) users, and has historically been very difficult
to improve.

The session would quickly go over the current state of whatever the
mailing list discussion evolves into and an open discussion around the
different ideas.

Thanks,
Jason






Re: [PATCH v2 18/21] drm/amd/display: Fallback to 2020_YCBCR if the pixel encoding is not RGB

2023-01-25 Thread Sebastian Wick
On Wed, Jan 25, 2023 at 2:00 PM Joshua Ashton  wrote:
>
>
>
> On 1/23/23 20:30, Sebastian Wick wrote:
> > A new property to control YCC and subsampling would be the more
> > complete path here. If we actually want to fix this in the short-term
> > though, we should handle the YCC and RGB Colorspace values as
> > equivalent, everywhere. Technically we're breaking the user space API
> > here so it should be documented on the KMS property and other drivers
> > must be adjusted accordingly as well.
>
> I am happy with treating 2020_YCC and 2020_RGB as the same.
>
> I think having the YCC/RGB split here in Colorspace is a mistake.
> Pixel encoding should be completely separate from colorspace from a uAPI
> perspective when we want to expose that.
> It's just a design flaw from when it was added as it just mirrors the
> values in the colorimetry packets 1:1. I understand why this happened,
> and I don't think it's a big deal for us to correct ourselves now:
>
> I suggest we deprecate the _YCC variants, treat them the same as the RGB
> enum to avoid any potential uAPI breakage and key the split entirely off
> the pixel_encoding value.

Yeah, I agree. The kernel must know the wire encoding and can thus
always choose the correct variant. If anyone wants to provide a patch
I'll review it.

> That way when we do want to plumb more explicit pixel encoding down the
> line, userspace only has to manage one thing. There's no advantage for
> anything more here.
>
> - Joshie ✨
>
> >
> > On Fri, Jan 13, 2023 at 5:26 PM Harry Wentland  
> > wrote:
> >>
> >> From: Joshua Ashton 
> >>
> >> Userspace might not aware whether we're sending RGB or YCbCr
> >> data to the display. If COLOR_SPACE_2020_RGB_FULLRANGE is
> >> requested but the output encoding is YCbCr we should
> >> send COLOR_SPACE_2020_YCBCR.
> >>
> >> Signed-off-by: Joshua Ashton 
> >> Signed-off-by: Harry Wentland 
> >> Cc: Pekka Paalanen 
> >> Cc: Sebastian Wick 
> >> Cc: vitaly.pros...@amd.com
> >> Cc: Joshua Ashton 
> >> Cc: dri-devel@lists.freedesktop.org
> >> Cc: amd-...@lists.freedesktop.org
> >> Reviewed-by: Harry Wentland 
> >> ---
> >>   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 -
> >>   1 file changed, 4 insertions(+), 1 deletion(-)
> >>
> >> 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 f74b125af31f..16940ea61b59 100644
> >> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >> @@ -5184,7 +5184,10 @@ get_output_color_space(const struct dc_crtc_timing 
> >> *dc_crtc_timing,
> >>  color_space = COLOR_SPACE_ADOBERGB;
> >>  break;
> >>  case DRM_MODE_COLORIMETRY_BT2020_RGB:
> >> -   color_space = COLOR_SPACE_2020_RGB_FULLRANGE;
> >> +   if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB)
> >> +   color_space = COLOR_SPACE_2020_RGB_FULLRANGE;
> >> +   else
> >> +   color_space = COLOR_SPACE_2020_YCBCR;
> >>  break;
> >>  case DRM_MODE_COLORIMETRY_BT2020_YCC:
> >>  color_space = COLOR_SPACE_2020_YCBCR;
> >> --
> >> 2.39.0
> >>
> >
>



[PATCH v5 3/8] drm/i915: Fix up locking around dumping requests lists

2023-01-25 Thread John . C . Harrison
From: John Harrison 

The debugfs dump of requests was confused about what state requires
the execlist lock versus the GuC lock. There was also a bunch of
duplicated messy code between it and the error capture code.

So refactor the hung request search into a re-usable function. And
reduce the span of the execlist state lock to only the execlist
specific code paths. In order to do that, also move the report of hold
count (which is an execlist only concept) from the top level dump
function to the lower level execlist specific function. Also, move the
execlist specific code into the execlist source file.

v2: Rename some functions and move to more appropriate files (Daniele).
v3: Rename new execlist dump function (Daniele)

Signed-off-by: John Harrison 
Fixes: dc0dad365c5e ("drm/i915/guc: Fix for error capture after full GPU reset 
with GuC")
Cc: John Harrison 
Cc: Matthew Brost 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: Daniele Ceraolo Spurio 
Cc: Matt Roper 
Cc: Umesh Nerlige Ramappa 
Cc: Michael Cheng 
Cc: Lucas De Marchi 
Cc: Bruce Chang 
Cc: Alan Previn 
Cc: Matthew Auld 
---
 drivers/gpu/drm/i915/gt/intel_engine.h|  4 +-
 drivers/gpu/drm/i915/gt/intel_engine_cs.c | 74 +--
 .../drm/i915/gt/intel_execlists_submission.c  | 27 +++
 .../drm/i915/gt/intel_execlists_submission.h  |  4 +
 drivers/gpu/drm/i915/i915_gpu_error.c | 26 +--
 5 files changed, 73 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h 
b/drivers/gpu/drm/i915/gt/intel_engine.h
index 0e24af5efee9c..b58c30ac8ef02 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -250,8 +250,8 @@ void intel_engine_dump_active_requests(struct list_head 
*requests,
 ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine,
   ktime_t *now);
 
-struct i915_request *
-intel_engine_execlist_find_hung_request(struct intel_engine_cs *engine);
+void intel_engine_get_hung_entity(struct intel_engine_cs *engine,
+ struct intel_context **ce, struct 
i915_request **rq);
 
 u32 intel_engine_context_size(struct intel_gt *gt, u8 class);
 struct intel_context *
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index a86bdbee7a6be..9f703f255d721 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -2114,17 +2114,6 @@ static void print_request_ring(struct drm_printer *m, 
struct i915_request *rq)
}
 }
 
-static unsigned long list_count(struct list_head *list)
-{
-   struct list_head *pos;
-   unsigned long count = 0;
-
-   list_for_each(pos, list)
-   count++;
-
-   return count;
-}
-
 static unsigned long read_ul(void *p, size_t x)
 {
return *(unsigned long *)(p + x);
@@ -2216,11 +2205,11 @@ void intel_engine_dump_active_requests(struct list_head 
*requests,
}
 }
 
-static void engine_dump_active_requests(struct intel_engine_cs *engine, struct 
drm_printer *m)
+static void engine_dump_active_requests(struct intel_engine_cs *engine,
+   struct drm_printer *m)
 {
+   struct intel_context *hung_ce = NULL;
struct i915_request *hung_rq = NULL;
-   struct intel_context *ce;
-   bool guc;
 
/*
 * No need for an engine->irq_seqno_barrier() before the seqno reads.
@@ -2229,29 +2218,20 @@ static void engine_dump_active_requests(struct 
intel_engine_cs *engine, struct d
 * But the intention here is just to report an instantaneous snapshot
 * so that's fine.
 */
-   lockdep_assert_held(>sched_engine->lock);
+   intel_engine_get_hung_entity(engine, _ce, _rq);
 
drm_printf(m, "\tRequests:\n");
 
-   guc = intel_uc_uses_guc_submission(>gt->uc);
-   if (guc) {
-   ce = intel_engine_get_hung_context(engine);
-   if (ce)
-   hung_rq = intel_context_get_active_request(ce);
-   } else {
-   hung_rq = intel_engine_execlist_find_hung_request(engine);
-   if (hung_rq)
-   hung_rq = i915_request_get_rcu(hung_rq);
-   }
-
if (hung_rq)
engine_dump_request(hung_rq, m, "\t\thung");
+   else if (hung_ce)
+   drm_printf(m, "\t\tGot hung ce but no hung rq!\n");
 
-   if (guc)
+   if (intel_uc_uses_guc_submission(>gt->uc))
intel_guc_dump_active_requests(engine, hung_rq, m);
else
-   
intel_engine_dump_active_requests(>sched_engine->requests,
- hung_rq, m);
+   intel_execlists_dump_active_requests(engine, hung_rq, m);
+
if (hung_rq)
i915_request_put(hung_rq);
 }
@@ -2263,7 +2243,6 @@ void intel_engine_dump(struct intel_engine_cs *engine,

[PATCH v5 7/8] drm/i915/guc: Add a debug print on GuC triggered reset

2023-01-25 Thread John . C . Harrison
From: John Harrison 

For understanding bug reports, it can be useful to have an explicit
dmesg print when a reset notification is received from GuC. As opposed
to simply inferring that this happened from other messages.

Signed-off-by: John Harrison 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 4 
 1 file changed, 4 insertions(+)

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 7adc35bd4435a..2e6ab0bb5c2b6 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4666,6 +4666,10 @@ static void guc_handle_context_reset(struct intel_guc 
*guc,
 {
trace_intel_context_reset(ce);
 
+   drm_dbg(_to_gt(guc)->i915->drm, "Got GuC reset of 0x%04X, exiting = 
%d, banned = %d\n",
+   ce->guc_id.id, test_bit(CONTEXT_EXITING, >flags),
+   test_bit(CONTEXT_BANNED, >flags));
+
if (likely(intel_context_is_schedulable(ce))) {
capture_error_state(guc, ce);
guc_context_replay(ce);
-- 
2.39.1



[PATCH v5 4/8] drm/i915: Allow error capture without a request

2023-01-25 Thread John . C . Harrison
From: John Harrison 

There was a report of error captures occurring without any hung
context being indicated despite the capture being initiated by a 'hung
context notification' from GuC. The problem was not reproducible.
However, it is possible to happen if the context in question has no
active requests. For example, if the hang was in the context switch
itself then the breadcrumb write would have occurred and the KMD would
see an idle context.

In the interests of attempting to provide as much information as
possible about a hang, it seems wise to include the engine info
regardless of whether a request was found or not. As opposed to just
prentending there was no hang at all.

So update the error capture code to always record engine information
if a context is given. Which means updating record_context() to take a
context instead of a request (which it only ever used to find the
context anyway). And split the request agnostic parts of
intel_engine_coredump_add_request() out into a seaprate function.

v2: Remove a duplicate 'if' statement (Umesh) and fix a put of a null
pointer.
v3: Tidy up request locking code flow (Tvrtko)
v4: Pull in improved info message from next patch and fix up potential
leak of GuC register state (Daniele)

Signed-off-by: John Harrison 
Reviewed-by: Umesh Nerlige Ramappa  (v2)
Reviewed-by: Daniele Ceraolo Spurio 
Acked-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_gpu_error.c | 74 ++-
 1 file changed, 50 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index b20bd6365615b..225f1b11a6b93 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1370,14 +1370,14 @@ static void engine_record_execlists(struct 
intel_engine_coredump *ee)
 }
 
 static bool record_context(struct i915_gem_context_coredump *e,
-  const struct i915_request *rq)
+  struct intel_context *ce)
 {
struct i915_gem_context *ctx;
struct task_struct *task;
bool simulated;
 
rcu_read_lock();
-   ctx = rcu_dereference(rq->context->gem_context);
+   ctx = rcu_dereference(ce->gem_context);
if (ctx && !kref_get_unless_zero(>ref))
ctx = NULL;
rcu_read_unlock();
@@ -1396,8 +1396,8 @@ static bool record_context(struct 
i915_gem_context_coredump *e,
e->guilty = atomic_read(>guilty_count);
e->active = atomic_read(>active_count);
 
-   e->total_runtime = intel_context_get_total_runtime_ns(rq->context);
-   e->avg_runtime = intel_context_get_avg_runtime_ns(rq->context);
+   e->total_runtime = intel_context_get_total_runtime_ns(ce);
+   e->avg_runtime = intel_context_get_avg_runtime_ns(ce);
 
simulated = i915_gem_context_no_error_capture(ctx);
 
@@ -1532,15 +1532,37 @@ intel_engine_coredump_alloc(struct intel_engine_cs 
*engine, gfp_t gfp, u32 dump_
return ee;
 }
 
+static struct intel_engine_capture_vma *
+engine_coredump_add_context(struct intel_engine_coredump *ee,
+   struct intel_context *ce,
+   gfp_t gfp)
+{
+   struct intel_engine_capture_vma *vma = NULL;
+
+   ee->simulated |= record_context(>context, ce);
+   if (ee->simulated)
+   return NULL;
+
+   /*
+* We need to copy these to an anonymous buffer
+* as the simplest method to avoid being overwritten
+* by userspace.
+*/
+   vma = capture_vma(vma, ce->ring->vma, "ring", gfp);
+   vma = capture_vma(vma, ce->state, "HW context", gfp);
+
+   return vma;
+}
+
 struct intel_engine_capture_vma *
 intel_engine_coredump_add_request(struct intel_engine_coredump *ee,
  struct i915_request *rq,
  gfp_t gfp)
 {
-   struct intel_engine_capture_vma *vma = NULL;
+   struct intel_engine_capture_vma *vma;
 
-   ee->simulated |= record_context(>context, rq);
-   if (ee->simulated)
+   vma = engine_coredump_add_context(ee, rq->context, gfp);
+   if (!vma)
return NULL;
 
/*
@@ -1550,8 +1572,6 @@ intel_engine_coredump_add_request(struct 
intel_engine_coredump *ee,
 */
vma = capture_vma_snapshot(vma, rq->batch_res, gfp, "batch");
vma = capture_user(vma, rq, gfp);
-   vma = capture_vma(vma, rq->ring->vma, "ring", gfp);
-   vma = capture_vma(vma, rq->context->state, "HW context", gfp);
 
ee->rq_head = rq->head;
ee->rq_post = rq->postfix;
@@ -1604,25 +1624,31 @@ capture_engine(struct intel_engine_cs *engine,
return NULL;
 
intel_engine_get_hung_entity(engine, , );
-   if (!rq || !i915_request_started(rq))
-   goto no_request_capture;
+   if (rq && !i915_request_started(rq)) {
+   drm_info(>gt->i915->drm, "Got hung context on %s with 
active request 

[PATCH v5 8/8] drm/i915/guc: Rename GuC register state capture node to be more obvious

2023-01-25 Thread John . C . Harrison
From: John Harrison 

The GuC specific register state entry in the error capture object was
just called 'capture'. Although the companion 'node' entry was called
'guc_capture_node'. Rename the base entry to be 'guc_capture' instead
so that it is a) more consistent and b) more obvious what it is.

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c | 8 
 drivers/gpu/drm/i915/i915_gpu_error.h  | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index 1c1b85073b4bd..fc3b994626a4f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -1506,7 +1506,7 @@ int intel_guc_capture_print_engine_node(struct 
drm_i915_error_state_buf *ebuf,
 
if (!ebuf || !ee)
return -EINVAL;
-   cap = ee->capture;
+   cap = ee->guc_capture;
if (!cap || !ee->engine)
return -ENODEV;
 
@@ -1576,8 +1576,8 @@ void intel_guc_capture_free_node(struct 
intel_engine_coredump *ee)
if (!ee || !ee->guc_capture_node)
return;
 
-   guc_capture_add_node_to_cachelist(ee->capture, ee->guc_capture_node);
-   ee->capture = NULL;
+   guc_capture_add_node_to_cachelist(ee->guc_capture, 
ee->guc_capture_node);
+   ee->guc_capture = NULL;
ee->guc_capture_node = NULL;
 }
 
@@ -1611,7 +1611,7 @@ void intel_guc_capture_get_matching_node(struct intel_gt 
*gt,
(ce->lrc.lrca & CTX_GTT_ADDRESS_MASK)) {
list_del(>link);
ee->guc_capture_node = n;
-   ee->capture = guc->capture;
+   ee->guc_capture = guc->capture;
return;
}
}
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h 
b/drivers/gpu/drm/i915/i915_gpu_error.h
index efc75cc2ffdb9..56027ffbce51f 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.h
+++ b/drivers/gpu/drm/i915/i915_gpu_error.h
@@ -94,7 +94,7 @@ struct intel_engine_coredump {
struct intel_instdone instdone;
 
/* GuC matched capture-lists info */
-   struct intel_guc_state_capture *capture;
+   struct intel_guc_state_capture *guc_capture;
struct __guc_capture_parsed_output *guc_capture_node;
 
struct i915_gem_context_coredump {
-- 
2.39.1



[PATCH v5 6/8] drm/i915/guc: Look for a guilty context when an engine reset fails

2023-01-25 Thread John . C . Harrison
From: John Harrison 

Engine resets are supposed to never fail. But in the case when one
does (due to unknown reasons that normally come down to a missing
w/a), it is useful to get as much information out of the system as
possible. Given that the GuC intentionally dies on such a situation,
it is not possible to get a guilty context notification back. So do a
manual search instead. Given that GuC is dead, this is safe because
GuC won't be changing the engine state asynchronously.

v2: Change comment to be less alarming (Tvrtko)

Signed-off-by: John Harrison 
Acked-by: Tvrtko Ursulin 
Reviewed-by: Daniele Ceraolo Spurio 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c   | 17 +++--
 1 file changed, 15 insertions(+), 2 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 a2b263e5fd667..7adc35bd4435a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4755,11 +4755,24 @@ static void reset_fail_worker_func(struct work_struct 
*w)
guc->submission_state.reset_fail_mask = 0;
spin_unlock_irqrestore(>submission_state.lock, flags);
 
-   if (likely(reset_fail_mask))
+   if (likely(reset_fail_mask)) {
+   struct intel_engine_cs *engine;
+   enum intel_engine_id id;
+
+   /*
+* GuC is toast at this point - it dead loops after sending the 
failed
+* reset notification. So need to manually determine the guilty 
context.
+* Note that it should be reliable to do this here because the 
GuC is
+* toast and will not be scheduling behind the KMD's back.
+*/
+   for_each_engine_masked(engine, gt, reset_fail_mask, id)
+   intel_guc_find_hung_context(engine);
+
intel_gt_handle_error(gt, reset_fail_mask,
  I915_ERROR_CAPTURE,
- "GuC failed to reset engine mask=0x%x\n",
+ "GuC failed to reset engine mask=0x%x",
  reset_fail_mask);
+   }
 }
 
 int intel_guc_engine_failure_process_msg(struct intel_guc *guc,
-- 
2.39.1



[PATCH v5 1/8] drm/i915/guc: Fix locking when searching for a hung request

2023-01-25 Thread John . C . Harrison
From: John Harrison 

intel_guc_find_hung_context() was not acquiring the correct spinlock
before searching the request list. So fix that up. While at it, add
some extra whitespace padding for readability.

Fixes: dc0dad365c5e ("drm/i915/guc: Fix for error capture after full GPU reset 
with GuC")
Cc: John Harrison 
Cc: Matthew Brost 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: Daniele Ceraolo Spurio 
Cc: Matt Roper 
Cc: Umesh Nerlige Ramappa 
Cc: Michael Cheng 
Cc: Lucas De Marchi 
Cc: Tejas Upadhyay 
Cc: Chris Wilson 
Cc: Bruce Chang 
Cc: Alan Previn 
Cc: Matthew Auld 
Cc: intel-...@lists.freedesktop.org
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 11 +++
 1 file changed, 11 insertions(+)

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 b436dd7f12e42..3b34a82d692be 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4820,6 +4820,8 @@ void intel_guc_find_hung_context(struct intel_engine_cs 
*engine)
 
xa_lock_irqsave(>context_lookup, flags);
xa_for_each(>context_lookup, index, ce) {
+   bool found;
+
if (!kref_get_unless_zero(>ref))
continue;
 
@@ -4836,10 +4838,18 @@ void intel_guc_find_hung_context(struct intel_engine_cs 
*engine)
goto next;
}
 
+   found = false;
+   spin_lock(>guc_state.lock);
list_for_each_entry(rq, >guc_state.requests, sched.link) {
if (i915_test_request_state(rq) != I915_REQUEST_ACTIVE)
continue;
 
+   found = true;
+   break;
+   }
+   spin_unlock(>guc_state.lock);
+
+   if (found) {
intel_engine_set_hung_context(engine, ce);
 
/* Can only cope with one hang at a time... */
@@ -4847,6 +4857,7 @@ void intel_guc_find_hung_context(struct intel_engine_cs 
*engine)
xa_lock(>context_lookup);
goto done;
}
+
 next:
intel_context_put(ce);
xa_lock(>context_lookup);
-- 
2.39.1



[PATCH v5 2/8] drm/i915: Fix request locking during error capture & debugfs dump

2023-01-25 Thread John . C . Harrison
From: John Harrison 

When GuC support was added to error capture, the locking around the
request object was broken. Fix it up.

The context based search manages the spinlocking around the search
internally. So it needs to grab the reference count internally as
well. The execlist only request based search relies on external
locking, so it needs an external reference count but within the
spinlock not outside it.

The only other caller of the context based search is the code for
dumping engine state to debugfs. That code wasn't previously getting
an explicit reference at all as it does everything while holding the
execlist specific spinlock. So, that needs updaing as well as that
spinlock doesn't help when using GuC submission. Rather than trying to
conditionally get/put depending on submission model, just change it to
always do the get/put.

v2: Explicitly document adding an extra blank line in some dense code
(Andy Shevchenko). Fix multiple potential null pointer derefs in case
of no request found (some spotted by Tvrtko, but there was more!).
Also fix a leaked request in case of !started and another in
__guc_reset_context now that intel_context_find_active_request is
actually reference counting the returned request.
v3: Add a _get suffix to intel_context_find_active_request now that it
grabs a reference (Daniele).
v4: Split the intel_guc_find_hung_context change to a separate patch
and rename intel_context_find_active_request_get to
intel_context_get_active_request (Tvrtko).

Fixes: dc0dad365c5e ("drm/i915/guc: Fix for error capture after full GPU reset 
with GuC")
Fixes: 573ba126aef3 ("drm/i915/guc: Capture error state on context reset")
Cc: Matthew Brost 
Cc: John Harrison 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: Daniele Ceraolo Spurio 
Cc: Andrzej Hajda 
Cc: Matthew Auld 
Cc: Matt Roper 
Cc: Umesh Nerlige Ramappa 
Cc: Michael Cheng 
Cc: Lucas De Marchi 
Cc: Tejas Upadhyay 
Cc: Andy Shevchenko 
Cc: Aravind Iddamsetty 
Cc: Alan Previn 
Cc: Bruce Chang 
Cc: intel-...@lists.freedesktop.org
Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  4 +++-
 drivers/gpu/drm/i915/gt/intel_context.h   |  3 +--
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |  6 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c |  3 ++-
 drivers/gpu/drm/i915/i915_gpu_error.c | 13 ++---
 5 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index e94365b08f1ef..2aa63ec521b89 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -528,7 +528,7 @@ struct i915_request *intel_context_create_request(struct 
intel_context *ce)
return rq;
 }
 
-struct i915_request *intel_context_find_active_request(struct intel_context 
*ce)
+struct i915_request *intel_context_get_active_request(struct intel_context *ce)
 {
struct intel_context *parent = intel_context_to_parent(ce);
struct i915_request *rq, *active = NULL;
@@ -552,6 +552,8 @@ struct i915_request 
*intel_context_find_active_request(struct intel_context *ce)
 
active = rq;
}
+   if (active)
+   active = i915_request_get_rcu(active);
spin_unlock_irqrestore(>guc_state.lock, flags);
 
return active;
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h 
b/drivers/gpu/drm/i915/gt/intel_context.h
index fb62b7b8cbcda..0a8d553da3f43 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -268,8 +268,7 @@ int intel_context_prepare_remote_request(struct 
intel_context *ce,
 
 struct i915_request *intel_context_create_request(struct intel_context *ce);
 
-struct i915_request *
-intel_context_find_active_request(struct intel_context *ce);
+struct i915_request *intel_context_get_active_request(struct intel_context 
*ce);
 
 static inline bool intel_context_is_barrier(const struct intel_context *ce)
 {
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 922f1bb22dc68..a86bdbee7a6be 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -2237,9 +2237,11 @@ static void engine_dump_active_requests(struct 
intel_engine_cs *engine, struct d
if (guc) {
ce = intel_engine_get_hung_context(engine);
if (ce)
-   hung_rq = intel_context_find_active_request(ce);
+   hung_rq = intel_context_get_active_request(ce);
} else {
hung_rq = intel_engine_execlist_find_hung_request(engine);
+   if (hung_rq)
+   hung_rq = i915_request_get_rcu(hung_rq);
}
 
if (hung_rq)
@@ -2250,6 +2252,8 @@ static void engine_dump_active_requests(struct 
intel_engine_cs *engine, struct 

[PATCH v5 5/8] drm/i915: Allow error capture of a pending request

2023-01-25 Thread John . C . Harrison
From: John Harrison 

A hang situation has been observed where the only requests on the
context were either completed or not yet started according to the
breaadcrumbs. However, the register state claimed a batch was (maybe)
in progress. So, allow capture of the pending request on the grounds
that this might be better than nothing.

v2: Reword 'not started' warning message (Tvrtko)

Signed-off-by: John Harrison 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_gpu_error.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index 225f1b11a6b93..904f21e1380cd 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1624,12 +1624,9 @@ capture_engine(struct intel_engine_cs *engine,
return NULL;
 
intel_engine_get_hung_entity(engine, , );
-   if (rq && !i915_request_started(rq)) {
+   if (rq && !i915_request_started(rq))
drm_info(>gt->i915->drm, "Got hung context on %s with 
active request %lld:%lld [0x%04X] not yet started\n",
 engine->name, rq->fence.context, rq->fence.seqno, 
ce->guc_id.id);
-   i915_request_put(rq);
-   rq = NULL;
-   }
 
if (rq) {
capture = intel_engine_coredump_add_request(ee, rq, 
ATOMIC_MAYFAIL);
-- 
2.39.1



[PATCH v5 0/8] Allow error capture without a request & fix locking issues

2023-01-25 Thread John . C . Harrison
From: John Harrison 

It is technically possible to get a hung context without a valid
request. In such a situation, try to provide as much information in
the error capture as possible rather than just aborting and capturing
nothing.

Similarly, in the case of an engine reset failure the GuC is not able
to report the guilty context. So try a manual search instead of
reporting nothing.

While doing all this, it was noticed that the locking was broken in a
number of places when searching for hung requests and dumping request
info. So fix all that up as well.

v2: Tidy up code flow in error capture. Reword some comments/messages.
(review feedback from Tvrtko)
Also fix up request locking issues from earlier changes noticed during
code review of this change.
v3: Fix some potential null pointer derefs and a reference leak.
Add new patch to refactor the duplicated hung request search code into
a common backend agnostic wrapper function and use the correct
spinlocks for the correct lists. Also tweak some of the patch
descriptions for better accuracy.
v4: Shuffle some code around to more appropriate source files. Fix
potential leak of GuC capture object after code flow re-org and pull
improved info message earlier (Daniele). Also rename the GuC capture
object to be more consistent.
v5: Split one self contained locking fix out into a separate patch
and rename a function to be shorter (Tvrtko).

Signed-off-by: John Harrison 


John Harrison (8):
  drm/i915/guc: Fix locking when searching for a hung request
  drm/i915: Fix request locking during error capture & debugfs dump
  drm/i915: Fix up locking around dumping requests lists
  drm/i915: Allow error capture without a request
  drm/i915: Allow error capture of a pending request
  drm/i915/guc: Look for a guilty context when an engine reset fails
  drm/i915/guc: Add a debug print on GuC triggered reset
  drm/i915/guc: Rename GuC register state capture node to be more
obvious

 drivers/gpu/drm/i915/gt/intel_context.c   |  4 +-
 drivers/gpu/drm/i915/gt/intel_context.h   |  3 +-
 drivers/gpu/drm/i915/gt/intel_engine.h|  4 +-
 drivers/gpu/drm/i915/gt/intel_engine_cs.c | 74 ---
 .../drm/i915/gt/intel_execlists_submission.c  | 27 ++
 .../drm/i915/gt/intel_execlists_submission.h  |  4 +
 .../gpu/drm/i915/gt/uc/intel_guc_capture.c|  8 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 35 ++-
 drivers/gpu/drm/i915/i915_gpu_error.c | 92 ++-
 drivers/gpu/drm/i915/i915_gpu_error.h |  2 +-
 10 files changed, 160 insertions(+), 93 deletions(-)

-- 
2.39.1



[PATCH] dma-buf: actually set signaling bit for private sub fences

2023-01-25 Thread Danilo Krummrich
In dma_fence_allocate_private_stub() set the signaling bit of the newly
allocated private stub fence rather than the signaling bit of the
shared dma_fence_stub.

Fixes: c85d00d4fd8b ("dma-buf: set signaling bit for the stub fence")
Signed-off-by: Danilo Krummrich 
---
 drivers/dma-buf/dma-fence.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 406b4e26f538..0de0482cd36e 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -167,7 +167,7 @@ struct dma_fence *dma_fence_allocate_private_stub(void)
   0, 0);
 
set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
-   _fence_stub.flags);
+   >flags);
 
dma_fence_signal(fence);
 
-- 
2.39.1



Re: [PATCH] drm/msm/dsi: simplify pixel clk rate handling

2023-01-25 Thread Abhinav Kumar




On 1/18/2023 5:00 AM, Dmitry Baryshkov wrote:

Move a call to dsi_calc_pclk() out of calc_clk_rate directly towards
msm_dsi_host_get_phy_clk_req(). It is called for both 6g and v2 hosts.

Also, while we are at it, replace another dsi_get_pclk_rate() invocation
with using the stored value at msm_host->pixel_clk_rate.

Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/dsi/dsi.h  |  4 ++--
  drivers/gpu/drm/msm/dsi/dsi_cfg.h  |  2 +-
  drivers/gpu/drm/msm/dsi/dsi_host.c | 24 
  3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index bd3763a5d723..93ec54478eb6 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -129,8 +129,8 @@ int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, 
uint64_t *iova);
  int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *iova);
  int dsi_clk_init_v2(struct msm_dsi_host *msm_host);
  int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host);
-int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
-int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
+int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host);
+int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host);
  void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct 
mipi_dsi_host *host);
  void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host);
  struct drm_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host 
*host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h 
b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
index 44be4a88aa83..5106e66846c3 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
@@ -51,7 +51,7 @@ struct msm_dsi_host_cfg_ops {
void* (*tx_buf_get)(struct msm_dsi_host *msm_host);
void (*tx_buf_put)(struct msm_dsi_host *msm_host);
int (*dma_base_get)(struct msm_dsi_host *msm_host, uint64_t *iova);
-   int (*calc_clk_rate)(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
+   int (*calc_clk_rate)(struct msm_dsi_host *msm_host);
  };
  
  struct msm_dsi_cfg_handler {

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 18fa30e1e858..7d99a108bff6 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -616,28 +616,21 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
  
  }
  
-int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi)

+int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host)
  {
-   if (!msm_host->mode) {
-   pr_err("%s: mode not set\n", __func__);
-   return -EINVAL;
-   }
-
-   dsi_calc_pclk(msm_host, is_bonded_dsi);
msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
+
return 0;
  }
  
-int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi)

+int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host)
  {
u32 bpp = dsi_get_bpp(msm_host->format);
u64 pclk_bpp;
unsigned int esc_mhz, esc_div;
unsigned long byte_mhz;
  
-	dsi_calc_pclk(msm_host, is_bonded_dsi);

-
-   pclk_bpp = (u64)dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi) * bpp;
+   pclk_bpp = msm_host->pixel_clk_rate * bpp;
do_div(pclk_bpp, 8);
msm_host->src_clk_rate = pclk_bpp;
  
@@ -2292,7 +2285,14 @@ void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host,

const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
int ret;
  
-	ret = cfg_hnd->ops->calc_clk_rate(msm_host, is_bonded_dsi);

+   if (!msm_host->mode) {
+   pr_err("%s: mode not set\n", __func__);
+   return;
+   }
+
+   dsi_calc_pclk(msm_host, is_bonded_dsi);
+
+   ret = cfg_hnd->ops->calc_clk_rate(msm_host);


I am not too sure what we are gaining by this.

Its not that we are replacing dsi_get_pclk_rate().

We are moving the dsi_get_pclk_rate() from the calc_clk_rate() to the 
msm_dsi_host_get_phy_clk_req().


Also, with this change, dsi_calc_clk_rate_6g() looks kind of empty to 
stand on its own.


The original intention of the calc_clk_rate() op seems to be calculate 
and store all the clocks (byte, pixel and esc).


Why change that behavior by breaking it up?


if (ret) {
pr_err("%s: unable to calc clk rate, %d\n", __func__, ret);
return;


Re: [Freedreno] [PATCH] drm/msm/dpu: disable features unsupported by QCM2290

2023-01-25 Thread Abhinav Kumar




On 1/24/2023 10:46 PM, Dmitry Baryshkov wrote:

Hi,

On Wed, 25 Jan 2023 at 02:22, Abhinav Kumar  wrote:

On 1/24/2023 12:22 AM, Dmitry Baryshkov wrote:

On 24/01/2023 03:32, Abhinav Kumar wrote:

On 1/22/2023 11:11 PM, Dmitry Baryshkov wrote:

QCM2290 doesn't seem to support reg-dma, smart-dma, UBWC, CDP, exclusion
rectangles and CSC. Drop corresponding features being incorrectly
enabled for qcm2290.



Can you please point me to which vendor DT you are referring to for this?

CSC is supported on the VIG SSPPs from what I can see.


https://github.com/MiCode/kernel_devicetree/blob/psyche-r-oss/qcom/scuba-sde.dtsi


No CSC, smart-dma, excl-rect, CDP, etc.


Sorry I am missing something here.

It has one Vig and one DMA

https://github.com/MiCode/kernel_devicetree/blob/psyche-r-oss/qcom/scuba-sde.dtsi#L68


Correct



If Vig is present, CSC is supported.


This actually puzzled me. Usually the dtsi has qcom,sde-sspp-csc-off
and qcom,sde-csc-type properties. But not in this case.



Even for smart DMA I can see it supported
https://github.com/MiCode/kernel_devicetree/blob/psyche-r-oss/qcom/scuba-sde.dtsi#L76
on the DMA SSPP.

Same for excl rectangle too
https://github.com/MiCode/kernel_devicetree/blob/psyche-r-oss/qcom/scuba-sde.dtsi#L74


Ack, my mistake. Maybe I was looking at the wrong dtsi then (or just
mixed something). I'll add them back. And I see that CDP is also
there.

So, this leaves us only with the question regarding CSC. Could you
please doublecheck it?


I went through the internal documents.

This chipset supports only RGB formats for Vig pipe and hence there is 
no CSC (surprise for me too).




I also don't see the UBWC (qcom,sde-ubwc-version) and regdma
(qcom,sde-reg-dma-off) properties. Are corresponding features present
on the QCM2290?



Yes UBWC is also not supported.

You can now go ahead and update v2.




QCM2290 should be using the same MDP version as 6115 from the HW version.


It is 6.3 vs 6.5 if I remember correctly.





Cc: Loic Poulain 
Fixes: 5334087ee743 ("drm/msm: add support for QCM2290 MDSS")
Signed-off-by: Dmitry Baryshkov 
---
   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 20 +++
   1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 289fb11f99d1..1c3ffa922794 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -12,10 +12,14 @@
   #include "dpu_hw_catalog.h"
   #include "dpu_kms.h"
-#define VIG_MASK \
+#define VIG_BASE_MASK \
   (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\
+BIT(DPU_SSPP_TS_PREFILL))
+
+#define VIG_MASK \
+(VIG_BASE_MASK | \
   BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) |\
-BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT))
+BIT(DPU_SSPP_EXCL_RECT))
   #define VIG_MSM8998_MASK \
   (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
@@ -29,7 +33,7 @@
   #define VIG_SM8250_MASK \
   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) |
BIT(DPU_SSPP_SCALER_QSEED3LITE))
-#define VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
+#define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL))
   #define DMA_MSM8998_MASK \
   (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\
@@ -50,6 +54,10 @@
   #define DMA_CURSOR_MSM8998_MASK \
   (DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR))
+#define DMA_QCM2290_MASK \
+(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
+BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1))
+
   #define MIXER_MSM8998_MASK \
   (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER))
@@ -316,8 +324,6 @@ static const struct dpu_caps msm8998_dpu_caps = {
   static const struct dpu_caps qcm2290_dpu_caps = {
   .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
   .max_mixer_blendstages = 0x4,
-.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
-.ubwc_version = DPU_HW_UBWC_VER_20,
   .has_dim_layer = true,
   .has_idle_pc = true,
   .max_linewidth = 2160,
@@ -1384,7 +1390,7 @@ static const struct dpu_sspp_sub_blks
qcm2290_dma_sblk_0 = _DMA_SBLK("8", 1);
   static const struct dpu_sspp_cfg qcm2290_sspp[] = {
   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_QCM2290_MASK,
qcm2290_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
-SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK,
+SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_QCM2290_MASK,
qcm2290_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
   };
@@ -2836,8 +2842,6 @@ static const struct dpu_mdss_cfg
qcm2290_dpu_cfg = {
   .intf = qcm2290_intf,
   .vbif_count = ARRAY_SIZE(sdm845_vbif),
   .vbif = sdm845_vbif,
-.reg_dma_count = 1,
-.dma_cfg = _regdma,
   .perf = _perf_data,
   .mdss_irqs = IRQ_SC7180_MASK,
   };








Re: [PATCH v2 2/3] drm/i915/mtl: Correct implementation of Wa_18018781329

2023-01-25 Thread Matt Roper
On Wed, Jan 25, 2023 at 03:41:58PM -0800, Matt Roper wrote:
> Workaround Wa_18018781329 has applied to several recent Xe_HP-based
> platforms.  However there are some extra gotchas to implementing this
> properly for MTL that we need to take into account:
> 
>  * Due to the separation of media and render/compute into separate GTs,
>this workaround needs to be implemented on each GT, not just the
>primary GT.  Since each class of register only exists on one of the
>two GTs, we should program the appropriate registers on each GT.
> 
>  * As with past Xe_HP platforms, the registers on the primary GT (Xe_LPG
>IP) are multicast/replicated registers and should be handled with the
>MCR-aware functions.  However the registers on the media GT (Xe_LPM+
>IP) are regular singleton registers and should _not_ use MCR
>handling.  We need to create separate register definitions for the
>Xe_HP multicast form and the Xe_LPM+ singleton form and use each in
>the appropriate place.
> 
>  * Starting with MTL, workarounds documented by the hardware teams are
>technically associated with IP versions/steppings rather than
>top-level platforms.  That means we should take care to check the
>media IP version rather than the graphics IP version when deciding
>whether the workaround is needed on the Xe_LPM+ media GT (in this
>case the workaround applies to both IPs and the stepping bounds are
>identical, but we should still write the code appropriately to set a
>proper precedent for future workaround implementations).
> 
>  * It's worth noting that the GSC register and the CCS register are
>defined with the same MMIO offset (0xCF30).  Since the CCS is only
>relevant to the primary GT and the GSC is only relevant to the media
>GT there isn't actually a clash here (the media GT automatically adds
>the additional 0x38 GSI offset).  However there's currently a
>glitch in the bspec where the CCS register doesn't show up at all and
>the GSC register is listed as existing on both GTs.  That's a known
>documentation problem for several registers with shared GSC/CCS
>offsets; rest assured that the CCS register really does still exist.
> 
> Cc: Gustavo Sousa 
> Signed-off-by: Matt Roper 

Forgot to add:

Fixes: 41bb543f5598 ("drm/i915/mtl: Add initial gt workarounds")


Matt

> ---
>  drivers/gpu/drm/i915/gt/intel_gt_regs.h |  7 +--
>  drivers/gpu/drm/i915/gt/intel_workarounds.c | 22 ++---
>  drivers/gpu/drm/i915/i915_drv.h |  4 
>  3 files changed, 24 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
> b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> index 2727645864db..310bdde049ab 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> @@ -1100,8 +1100,11 @@
>  #define XEHP_MERT_MOD_CTRL   MCR_REG(0xcf28)
>  #define RENDER_MOD_CTRL  MCR_REG(0xcf2c)
>  #define COMP_MOD_CTRLMCR_REG(0xcf30)
> -#define VDBX_MOD_CTRLMCR_REG(0xcf34)
> -#define VEBX_MOD_CTRLMCR_REG(0xcf38)
> +#define XELPMP_GSC_MOD_CTRL  _MMIO(0xcf30)   /* media GT 
> only */
> +#define XEHP_VDBX_MOD_CTRL   MCR_REG(0xcf34)
> +#define XELPMP_VDBX_MOD_CTRL _MMIO(0xcf34)
> +#define XEHP_VEBX_MOD_CTRL   MCR_REG(0xcf38)
> +#define XELPMP_VEBX_MOD_CTRL _MMIO(0xcf38)
>  #define   FORCE_MISS_FTLBREG_BIT(3)
>  
>  #define GEN12_GAMSTLB_CTRL   _MMIO(0xcf4c)
> diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c 
> b/drivers/gpu/drm/i915/gt/intel_workarounds.c
> index 9db60078460a..4c978abf3e2a 100644
> --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
> +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
> @@ -1681,8 +1681,8 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct 
> i915_wa_list *wal)
>   /* Wa_18018781329 */
>   wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
>   wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);
> - wa_mcr_write_or(wal, VDBX_MOD_CTRL, FORCE_MISS_FTLB);
> - wa_mcr_write_or(wal, VEBX_MOD_CTRL, FORCE_MISS_FTLB);
> + wa_mcr_write_or(wal, XEHP_VDBX_MOD_CTRL, FORCE_MISS_FTLB);
> + wa_mcr_write_or(wal, XEHP_VEBX_MOD_CTRL, FORCE_MISS_FTLB);
>  
>   /* Wa_1509235366:dg2 */
>   wa_write_or(wal, GEN12_GAMCNTRL_CTRL,
> @@ -1700,8 +1700,8 @@ pvc_gt_workarounds_init(struct intel_gt *gt, struct 
> i915_wa_list *wal)
>   /* Wa_18018781329 */
>   wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
>   wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);
> - wa_mcr_write_or(wal, VDBX_MOD_CTRL, FORCE_MISS_FTLB);
> - wa_mcr_write_or(wal, VEBX_MOD_CTRL, FORCE_MISS_FTLB);
> + wa_mcr_write_or(wal, XEHP_VDBX_MOD_CTRL, 

[PATCH v2 3/3] drm/i915/xehp: Annotate a couple more workaround registers as MCR

2023-01-25 Thread Matt Roper
GAMSTLB_CTRL and GAMCNTRL_CTRL became multicast/replicated registers on
Xe_HP.  They should be defined accordingly and use MCR-aware operations.

These registers have only been used for some dg2/xehpsdv workarounds, so
this fix is mostly just for consistency/future-proofing; even lacking
the MCR annotation, workarounds will always be properly applied in a
multicast manner on these platforms.

Cc: Gustavo Sousa 
Fixes: 58bc2453ab8a ("drm/i915: Define multicast registers as a new type")
Signed-off-by: Matt Roper 
Reviewed-by: Gustavo Sousa 
---
 drivers/gpu/drm/i915/gt/intel_gt_regs.h |  4 ++--
 drivers/gpu/drm/i915/gt/intel_workarounds.c | 16 
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index 310bdde049ab..7fa18a3b3957 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1107,12 +1107,12 @@
 #define XELPMP_VEBX_MOD_CTRL   _MMIO(0xcf38)
 #define   FORCE_MISS_FTLB  REG_BIT(3)
 
-#define GEN12_GAMSTLB_CTRL _MMIO(0xcf4c)
+#define XEHP_GAMSTLB_CTRL  MCR_REG(0xcf4c)
 #define   CONTROL_BLOCK_CLKGATE_DISREG_BIT(12)
 #define   EGRESS_BLOCK_CLKGATE_DIS REG_BIT(11)
 #define   TAG_BLOCK_CLKGATE_DISREG_BIT(7)
 
-#define GEN12_GAMCNTRL_CTRL_MMIO(0xcf54)
+#define XEHP_GAMCNTRL_CTRL MCR_REG(0xcf54)
 #define   INVALIDATION_BROADCAST_MODE_DIS  REG_BIT(12)
 #define   GLOBAL_INVALIDATION_MODE REG_BIT(2)
 
diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c 
b/drivers/gpu/drm/i915/gt/intel_workarounds.c
index 4c978abf3e2a..3111df350f57 100644
--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
@@ -1564,8 +1564,8 @@ xehpsdv_gt_workarounds_init(struct intel_gt *gt, struct 
i915_wa_list *wal)
wa_mcr_write_or(wal, XEHP_MERT_MOD_CTRL, FORCE_MISS_FTLB);
 
/* Wa_14014368820:xehpsdv */
-   wa_write_or(wal, GEN12_GAMCNTRL_CTRL,
-   INVALIDATION_BROADCAST_MODE_DIS | GLOBAL_INVALIDATION_MODE);
+   wa_mcr_write_or(wal, XEHP_GAMCNTRL_CTRL,
+   INVALIDATION_BROADCAST_MODE_DIS | 
GLOBAL_INVALIDATION_MODE);
 }
 
 static void
@@ -1659,10 +1659,10 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct 
i915_wa_list *wal)
wa_mcr_write_or(wal, SSMCGCTL9530, RTFUNIT_CLKGATE_DIS);
 
/* Wa_14010680813:dg2_g10 */
-   wa_write_or(wal, GEN12_GAMSTLB_CTRL,
-   CONTROL_BLOCK_CLKGATE_DIS |
-   EGRESS_BLOCK_CLKGATE_DIS |
-   TAG_BLOCK_CLKGATE_DIS);
+   wa_mcr_write_or(wal, XEHP_GAMSTLB_CTRL,
+   CONTROL_BLOCK_CLKGATE_DIS |
+   EGRESS_BLOCK_CLKGATE_DIS |
+   TAG_BLOCK_CLKGATE_DIS);
}
 
/* Wa_14014830051:dg2 */
@@ -1685,8 +1685,8 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct 
i915_wa_list *wal)
wa_mcr_write_or(wal, XEHP_VEBX_MOD_CTRL, FORCE_MISS_FTLB);
 
/* Wa_1509235366:dg2 */
-   wa_write_or(wal, GEN12_GAMCNTRL_CTRL,
-   INVALIDATION_BROADCAST_MODE_DIS | GLOBAL_INVALIDATION_MODE);
+   wa_mcr_write_or(wal, XEHP_GAMCNTRL_CTRL,
+   INVALIDATION_BROADCAST_MODE_DIS | 
GLOBAL_INVALIDATION_MODE);
 }
 
 static void
-- 
2.39.1



[PATCH v2 2/3] drm/i915/mtl: Correct implementation of Wa_18018781329

2023-01-25 Thread Matt Roper
Workaround Wa_18018781329 has applied to several recent Xe_HP-based
platforms.  However there are some extra gotchas to implementing this
properly for MTL that we need to take into account:

 * Due to the separation of media and render/compute into separate GTs,
   this workaround needs to be implemented on each GT, not just the
   primary GT.  Since each class of register only exists on one of the
   two GTs, we should program the appropriate registers on each GT.

 * As with past Xe_HP platforms, the registers on the primary GT (Xe_LPG
   IP) are multicast/replicated registers and should be handled with the
   MCR-aware functions.  However the registers on the media GT (Xe_LPM+
   IP) are regular singleton registers and should _not_ use MCR
   handling.  We need to create separate register definitions for the
   Xe_HP multicast form and the Xe_LPM+ singleton form and use each in
   the appropriate place.

 * Starting with MTL, workarounds documented by the hardware teams are
   technically associated with IP versions/steppings rather than
   top-level platforms.  That means we should take care to check the
   media IP version rather than the graphics IP version when deciding
   whether the workaround is needed on the Xe_LPM+ media GT (in this
   case the workaround applies to both IPs and the stepping bounds are
   identical, but we should still write the code appropriately to set a
   proper precedent for future workaround implementations).

 * It's worth noting that the GSC register and the CCS register are
   defined with the same MMIO offset (0xCF30).  Since the CCS is only
   relevant to the primary GT and the GSC is only relevant to the media
   GT there isn't actually a clash here (the media GT automatically adds
   the additional 0x38 GSI offset).  However there's currently a
   glitch in the bspec where the CCS register doesn't show up at all and
   the GSC register is listed as existing on both GTs.  That's a known
   documentation problem for several registers with shared GSC/CCS
   offsets; rest assured that the CCS register really does still exist.

Cc: Gustavo Sousa 
Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/gt/intel_gt_regs.h |  7 +--
 drivers/gpu/drm/i915/gt/intel_workarounds.c | 22 ++---
 drivers/gpu/drm/i915/i915_drv.h |  4 
 3 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index 2727645864db..310bdde049ab 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1100,8 +1100,11 @@
 #define XEHP_MERT_MOD_CTRL MCR_REG(0xcf28)
 #define RENDER_MOD_CTRLMCR_REG(0xcf2c)
 #define COMP_MOD_CTRL  MCR_REG(0xcf30)
-#define VDBX_MOD_CTRL  MCR_REG(0xcf34)
-#define VEBX_MOD_CTRL  MCR_REG(0xcf38)
+#define XELPMP_GSC_MOD_CTRL_MMIO(0xcf30)   /* media GT 
only */
+#define XEHP_VDBX_MOD_CTRL MCR_REG(0xcf34)
+#define XELPMP_VDBX_MOD_CTRL   _MMIO(0xcf34)
+#define XEHP_VEBX_MOD_CTRL MCR_REG(0xcf38)
+#define XELPMP_VEBX_MOD_CTRL   _MMIO(0xcf38)
 #define   FORCE_MISS_FTLB  REG_BIT(3)
 
 #define GEN12_GAMSTLB_CTRL _MMIO(0xcf4c)
diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c 
b/drivers/gpu/drm/i915/gt/intel_workarounds.c
index 9db60078460a..4c978abf3e2a 100644
--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
@@ -1681,8 +1681,8 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct 
i915_wa_list *wal)
/* Wa_18018781329 */
wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);
-   wa_mcr_write_or(wal, VDBX_MOD_CTRL, FORCE_MISS_FTLB);
-   wa_mcr_write_or(wal, VEBX_MOD_CTRL, FORCE_MISS_FTLB);
+   wa_mcr_write_or(wal, XEHP_VDBX_MOD_CTRL, FORCE_MISS_FTLB);
+   wa_mcr_write_or(wal, XEHP_VEBX_MOD_CTRL, FORCE_MISS_FTLB);
 
/* Wa_1509235366:dg2 */
wa_write_or(wal, GEN12_GAMCNTRL_CTRL,
@@ -1700,8 +1700,8 @@ pvc_gt_workarounds_init(struct intel_gt *gt, struct 
i915_wa_list *wal)
/* Wa_18018781329 */
wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);
-   wa_mcr_write_or(wal, VDBX_MOD_CTRL, FORCE_MISS_FTLB);
-   wa_mcr_write_or(wal, VEBX_MOD_CTRL, FORCE_MISS_FTLB);
+   wa_mcr_write_or(wal, XEHP_VDBX_MOD_CTRL, FORCE_MISS_FTLB);
+   wa_mcr_write_or(wal, XEHP_VEBX_MOD_CTRL, FORCE_MISS_FTLB);
 }
 
 static void
@@ -1715,8 +1715,6 @@ xelpg_gt_workarounds_init(struct intel_gt *gt, struct 
i915_wa_list *wal)
/* Wa_18018781329 */
wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
   

[PATCH v2 1/3] drm/i915/xehp: GAM registers don't need to be re-applied on engine resets

2023-01-25 Thread Matt Roper
Register reset characteristics (i.e., whether the register maintains or
loses its value on engine reset) is an important factor that determines
which wa_list we want to add workarounds to.  We recently found out that
the bspec documentation for the Xe_HP's "GAM" registers in the 0xC800 -
0xCFFF range was misleading; these registers do not actually lose their
value on engine resets as the documentation implied.  This means there's
no need to re-apply workarounds touching these registers after a reset,
and the corresponding workarounds should be moved from the 'engine'
lists back to the 'gt' list.

v2:
 - Don't add Wa_18018781329 to xehpsdv; the original condition didn't
   include that platform.  (Gustavo)
 - Move the MTL code to the GT function as-is for now; we'll take care
   of the additional fixes needed in a follow-up patch.

Cc: Gustavo Sousa 
Fixes: edf176f48d87 ("drm/i915/dg2: Move misplaced 'ctx' & 'gt' wa's to engine 
wa list")
Fixes: b2006061ae28 ("drm/i915/xehpsdv: Move render/compute engine reset 
domains related workarounds")
Fixes: 41bb543f5598 ("drm/i915/mtl: Add initial gt workarounds")
Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/gt/intel_workarounds.c | 77 -
 1 file changed, 44 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c 
b/drivers/gpu/drm/i915/gt/intel_workarounds.c
index 4efc1a532982..9db60078460a 100644
--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
@@ -1559,6 +1559,13 @@ xehpsdv_gt_workarounds_init(struct intel_gt *gt, struct 
i915_wa_list *wal)
 
/* Wa_14011060649:xehpsdv */
wa_14011060649(gt, wal);
+
+   /* Wa_14012362059:xehpsdv */
+   wa_mcr_write_or(wal, XEHP_MERT_MOD_CTRL, FORCE_MISS_FTLB);
+
+   /* Wa_14014368820:xehpsdv */
+   wa_write_or(wal, GEN12_GAMCNTRL_CTRL,
+   INVALIDATION_BROADCAST_MODE_DIS | GLOBAL_INVALIDATION_MODE);
 }
 
 static void
@@ -1599,6 +1606,12 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct 
i915_wa_list *wal)
DSS_ROUTER_CLKGATE_DIS);
}
 
+   if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_B0) ||
+   IS_DG2_GRAPHICS_STEP(gt->i915, G11, STEP_A0, STEP_B0)) {
+   /* Wa_14012362059:dg2 */
+   wa_mcr_write_or(wal, XEHP_MERT_MOD_CTRL, FORCE_MISS_FTLB);
+   }
+
if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_B0)) {
/* Wa_14010948348:dg2_g10 */
wa_write_or(wal, UNSLCGCTL9430, MSQDUNIT_CLKGATE_DIS);
@@ -1644,6 +1657,12 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct 
i915_wa_list *wal)
 
/* Wa_14011028019:dg2_g10 */
wa_mcr_write_or(wal, SSMCGCTL9530, RTFUNIT_CLKGATE_DIS);
+
+   /* Wa_14010680813:dg2_g10 */
+   wa_write_or(wal, GEN12_GAMSTLB_CTRL,
+   CONTROL_BLOCK_CLKGATE_DIS |
+   EGRESS_BLOCK_CLKGATE_DIS |
+   TAG_BLOCK_CLKGATE_DIS);
}
 
/* Wa_14014830051:dg2 */
@@ -1658,6 +1677,16 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct 
i915_wa_list *wal)
 
/* Wa_14015795083 */
wa_mcr_write_clr(wal, GEN8_MISCCPCTL, 
GEN12_DOP_CLOCK_GATE_RENDER_ENABLE);
+
+   /* Wa_18018781329 */
+   wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
+   wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);
+   wa_mcr_write_or(wal, VDBX_MOD_CTRL, FORCE_MISS_FTLB);
+   wa_mcr_write_or(wal, VEBX_MOD_CTRL, FORCE_MISS_FTLB);
+
+   /* Wa_1509235366:dg2 */
+   wa_write_or(wal, GEN12_GAMCNTRL_CTRL,
+   INVALIDATION_BROADCAST_MODE_DIS | GLOBAL_INVALIDATION_MODE);
 }
 
 static void
@@ -1667,16 +1696,29 @@ pvc_gt_workarounds_init(struct intel_gt *gt, struct 
i915_wa_list *wal)
 
/* Wa_14015795083 */
wa_mcr_write_clr(wal, GEN8_MISCCPCTL, 
GEN12_DOP_CLOCK_GATE_RENDER_ENABLE);
+
+   /* Wa_18018781329 */
+   wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
+   wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);
+   wa_mcr_write_or(wal, VDBX_MOD_CTRL, FORCE_MISS_FTLB);
+   wa_mcr_write_or(wal, VEBX_MOD_CTRL, FORCE_MISS_FTLB);
 }
 
 static void
 xelpg_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-   /* Wa_14014830051 */
if (IS_MTL_GRAPHICS_STEP(gt->i915, M, STEP_A0, STEP_B0) ||
-   IS_MTL_GRAPHICS_STEP(gt->i915, P, STEP_A0, STEP_B0))
+   IS_MTL_GRAPHICS_STEP(gt->i915, P, STEP_A0, STEP_B0)) {
+   /* Wa_14014830051 */
wa_mcr_write_clr(wal, SARB_CHICKEN1, COMP_CKN_IN);
 
+   /* Wa_18018781329 */
+   wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
+   wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);
+   wa_mcr_write_or(wal, VDBX_MOD_CTRL, FORCE_MISS_FTLB);
+   wa_mcr_write_or(wal, 

Re: [PATCH 2/2] drm/msm/dp: Return IRQ_NONE for unhandled interrupts

2023-01-25 Thread Kuogee Hsieh



On 1/25/2023 10:21 AM, Doug Anderson wrote:

Hi,

On Wed, Jan 25, 2023 at 9:22 AM Kuogee Hsieh  wrote:

-void dp_ctrl_isr(struct dp_ctrl *dp_ctrl)
+irqreturn_t dp_ctrl_isr(struct dp_ctrl *dp_ctrl)
   {
   struct dp_ctrl_private *ctrl;
   u32 isr;
+ irqreturn_t ret = IRQ_NONE;

   if (!dp_ctrl)
- return;
+ return IRQ_NONE;

   ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);

   isr = dp_catalog_ctrl_get_interrupt(ctrl->catalog);

can you add (!isr) check and return IRQ_NONE here to be consistent with
dp_aux_isr()?

I could, though it doesn't really buy us a whole lot in this case and
just adds an extra test that's not needed. Here it should be easy for
someone reading the function to see that if "isr == 0" that neither of
the two "if" statements below will fire and we'll return "IRQ_NONE"
anyway.

...that actually made me go back and wonder whether we still needed
the "if" test in dp_aux_isr() or if it too was also redundant. It
turns out that it's not! The previous patch made dp_aux_irq() detect
unexpected interrupts. Thus the "if (!isr)" test earlier is important
because otherwise we'd end up WARNing "Unexpected interrupt:
0x" which would be confusing.

So unless you or others feel strongly that I should add the redundant
test here, I'd rather keep it off. Let me know.

-Doug

ack


Re: DMA-heap driver hints

2023-01-25 Thread James Jones

On 1/24/23 15:14, T.J. Mercier wrote:

On Mon, Jan 23, 2023 at 11:49 PM Christian König
 wrote:


Am 24.01.23 um 04:56 schrieb James Jones:

On 1/23/23 08:58, Laurent Pinchart wrote:

Hi Christian,

On Mon, Jan 23, 2023 at 05:29:18PM +0100, Christian König wrote:

Am 23.01.23 um 14:55 schrieb Laurent Pinchart:

Hi Christian,

CC'ing James as I think this is related to his work on the unix device
memory allocator ([1]).


Thank you for including me.


Sorry for not having you in initially. I wasn't aware of your previous
work in this area.


No worries. I've embarrassingly made no progress here since the last XDC 
talk, so I wouldn't expect everyone to know or remember.





[1]
https://lore.kernel.org/dri-devel/8b555674-1c5b-c791-4547-2ea7c16ae...@nvidia.com/

On Mon, Jan 23, 2023 at 01:37:54PM +0100, Christian König wrote:

Hi guys,

this is just an RFC! The last time we discussed the DMA-buf coherency
problem [1] we concluded that DMA-heap first needs a better way to
communicate to userspace which heap to use for a certain device.

As far as I know userspace currently just hard codes that information
which is certainly not desirable considering that we should have this
inside the kernel as well.

So what those two patches here do is to first add some
dma_heap_create_device_link() and dma_heap_remove_device_link()
function and then demonstrating the functionality with uvcvideo
driver.

The preferred DMA-heap is represented with a symlink in sysfs between
the device and the virtual DMA-heap device node.


I'll start with a few high-level comments/questions:

- Instead of tying drivers to heaps, have you considered a system
where
 a driver would expose constraints, and a heap would then be
selected
 based on those constraints ? A tight coupling between heaps and
 drivers means downstream patches to drivers in order to use
 vendor-specific heaps, that sounds painful.


I was wondering the same thing as well, but came to the conclusion that
just the other way around is the less painful approach.


  From a kernel point of view, sure, it's simpler and thus less painful.
  From the point of view of solving the whole issue, I'm not sure :-)


The problem is that there are so many driver specific constrains that I
don't even know where to start from.


That's where I was hoping James would have some feedback for us, based
on the work he did on the Unix device memory allocator. If that's not
the case, we can brainstorm this from scratch.


Simon Ser's and my presentation from XDC 2020 focused entirely on
this. The idea was not to try to enumerate every constraint up front,
but rather to develop an extensible mechanism that would be flexible
enough to encapsulate many disparate types of constraints and perform
set operations on them (merging sets was the only operation we tried
to solve). Simon implemented a prototype header-only library to
implement the mechanism:

https://gitlab.freedesktop.org/emersion/drm-constraints

The links to the presentation and talk are below, along with notes
from the follow-up workshop.

https://lpc.events/event/9/contributions/615/attachments/704/1301/XDC_2020__Allocation_Constraints.pdf

https://www.youtube.com/watch?v=HZEClOP5TIk
https://paste.sr.ht/~emersion/c43b30be08bab1882f1b107402074462bba3b64a

Note one of the hard parts of this was figuring out how to express a
device or heap within the constraint structs. One of the better ideas
proposed back then was something like heap IDs, where dma heaps would
each have one,


We already have that. Each dma_heap has it's own unique name.


Cool.


and devices could register their own heaps (or even just themselves?)
with the heap subsystem and be assigned a locally-unique ID that
userspace could pass around.


I was more considering that we expose some kind of flag noting that a
certain device needs its buffer allocated from that device to utilize
all use cases.


This sounds similar to what you're proposing. Perhaps a reasonable
identifier is a device (major, minor) pair. Such a constraint could be
expressed as a symlink for easy visualization/discoverability from
userspace, but might be easier to serialize over the wire as the
(major, minor) pair. I'm not clear which direction is better to
express this either: As a link from heap->device, or device->heap.


 A constraint-based system would also, I think, be easier to extend
 with additional constraints in the future.

- I assume some drivers will be able to support multiple heaps. How do
 you envision this being implemented ?


I don't really see an use case for this.


One use case I know of here is same-vendor GPU local memory on
different GPUs. NVIDIA GPUs have certain things they can only do on
local memory, certain things they can do on all memory, and certain
things they can only do on memory local to another NVIDIA GPU,
especially when there exists an NVLink interface between the two. So
they'd ideally express different constraints for heap 

Re: [PATCH v10 00/11] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers

2023-01-25 Thread Dmitry Osipenko
Hello Thomas and Gerd,

On 1/9/23 00:04, Dmitry Osipenko wrote:
> This series:
> 
>   1. Makes minor fixes for drm_gem_lru and Panfrost
>   2. Brings refactoring for older code
>   3. Adds common drm-shmem memory shrinker
>   4. Enables shrinker for VirtIO-GPU driver
>   5. Switches Panfrost driver to the common shrinker
> 
> Changelog:
> 
> v10:- Rebased on a recent linux-next.
> 
> - Added Rob's ack to MSM "Prevent blocking within shrinker loop" patch.
> 
> - Added Steven's ack/r-b/t-b for the Panfrost patches.
> 
> - Fixed missing export of the new drm_gem_object_evict() function.
> 
> - Added fixes tags to the first two patches that are making minor fixes,
>   for consistency.

Do you have comments on this version? Otherwise ack will be appreciated.
Thanks in advance!

-- 
Best regards,
Dmitry



[PATCH] dt-bindings: display: msm: Drop type from 'memory-region'

2023-01-25 Thread Rob Herring
'memory-region' is a common property and already has a type.

Signed-off-by: Rob Herring 
---
 Documentation/devicetree/bindings/display/msm/gpu.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/msm/gpu.yaml 
b/Documentation/devicetree/bindings/display/msm/gpu.yaml
index c5f49842dc7b..304525f81563 100644
--- a/Documentation/devicetree/bindings/display/msm/gpu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/gpu.yaml
@@ -89,7 +89,7 @@ properties:
   help bring the GPU out of secure mode.
 properties:
   memory-region:
-$ref: /schemas/types.yaml#/definitions/phandle
+maxItems: 1
 
   firmware-name:
 description: |
-- 
2.39.0



Re: [PATCH v4 1/7] drm/i915: Fix request locking during error capture & debugfs dump

2023-01-25 Thread John Harrison

On 1/23/2023 09:51, Tvrtko Ursulin wrote:

On 20/01/2023 23:28, john.c.harri...@intel.com wrote:

From: John Harrison 



  -struct i915_request *intel_context_find_active_request(struct 
intel_context *ce)
+struct i915_request *intel_context_find_active_request_get(struct 
intel_context *ce)


TBH I don't "dig" this name, it's a bit on the long side and feels out 
of character. I won't insist it be changed, but if get really has to 
be included in the name I would be happy with 
intel_context_get_active_request().

Daniele sided with you on this one. Will use your naming.

John.



[PULL] amdgpu, drm drm-fixes-6.2

2023-01-25 Thread Alex Deucher
Hi Dave, Daniel,

Fixes for 6.2.  This contains a fix for DP MST that avoids the big revert.
There are still some corner cases, but it fixes things for most users.

The following changes since commit 3f30a6e67ce49c0068f8058893326db46b6db11f:

  Merge tag 'amd-drm-fixes-6.2-2023-01-19' of 
https://gitlab.freedesktop.org/agd5f/linux into drm-fixes (2023-01-20 11:21:20 
+1000)

are available in the Git repository at:

  https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-fixes-6.2-2023-01-25

for you to fetch changes up to 4b069553246f993c4221e382d0d0ae34f5ba730e:

  drm/amd/display: Fix timing not changning when freesync video is enabled 
(2023-01-25 14:50:18 -0500)


amd-drm-fixes-6.2-2023-01-25:

amdgpu:
- GC11.x fixes
- SMU13.0.0 fix
- Freesync video fix
- DP MST fixes

drm:
- DP MST kref fix


Aurabindo Pillai (1):
  drm/amd/display: Fix timing not changning when freesync video is enabled

Evan Quan (1):
  drm/amd/pm: add missing AllowIHInterrupt message mapping for SMU13.0.0

Jonathan Kim (1):
  drm/amdgpu: remove unconditional trap enable on add gfx11 queues

Li Ma (2):
  drm/amdgpu: enable imu firmware for GC 11.0.4
  drm/amdgpu: declare firmware for new MES 11.0.4

Lyude Paul (1):
  drm/amdgpu/display/mst: Fix mst_state->pbn_div and slot count assignments

Wayne Lin (3):
  drm/amdgpu/display/mst: limit payload to be updated one by one
  drm/amdgpu/display/mst: update mst_mgr relevant variable when long HPD
  drm/display/dp_mst: Correct the kref of port.

 drivers/gpu/drm/amd/amdgpu/imu_v11_0.c |  1 +
 drivers/gpu/drm/amd/amdgpu/mes_v11_0.c |  3 +-
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 31 +
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c  | 51 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c|  5 ---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c  | 14 +-
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c   |  1 +
 drivers/gpu/drm/display/drm_dp_mst_topology.c  |  4 +-
 8 files changed, 89 insertions(+), 21 deletions(-)


Re: [PATCH 1/4] dt-bindings: display: bridge: tfp410: Add tfp410 i2c example

2023-01-25 Thread Jon Cormier
On Wed, Jan 25, 2023 at 4:24 PM Laurent Pinchart
 wrote:
>
> Hi Jonathan,
>
> Thank you for the patch.
>
> On Wed, Jan 25, 2023 at 04:09:09PM -0500, Jonathan Cormier wrote:
> > Add a i2c example with HDMI connector
> >
> > Signed-off-by: Jonathan Cormier 
> > ---
> >  .../bindings/display/bridge/ti,tfp410.yaml | 42 
> > ++
> >  1 file changed, 42 insertions(+)
> >
> > diff --git 
> > a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml 
> > b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml
> > index 4c5dd8ec2951..456214f14b47 100644
> > --- a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml
> > +++ b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml
> > @@ -116,4 +116,46 @@ examples:
> >  };
> >  };
> >
> > +  - |
> > +i2c {
> > +  #address-cells = <1>;
> > +  #size-cells = <0>;
>
> Please use 4 spaces for indentation, as in the other example.
Will do, the whole file is 2 space indents. I didn't notice the
examples switch to 4 spaces.
>
> > +
> > +  hdmi_encoder: tfp410@38 {
> > +compatible = "ti,tfp410";
> > +reg = <0x38>;
> > +
> > +ports {
> > +  address-cells = <1>;
> > +  size-cells = <0>;
> > +
> > +  port@0 {
> > +reg = <0>;
> > +tfp410_in: endpoint {
> > +  remote-endpoint = <_out>;
> > +};
> > +  };
> > +
> > +  port@1 {
> > +reg = <1>;
> > +tfp410_out: endpoint {
> > +  remote-endpoint = <_connector_in>;
> > +};
> > +  };
> > +};
> > +  };
> > +};
> > +
> > +hdmi: hdmi_connector {
> > +  compatible = "hdmi-connector";
> > +  label = "hdmi";
> > +  type = "a";
> > +  ddc-i2c-bus = <>;
> > +  port {
> > +hdmi_connector_in: endpoint {
> > +  remote-endpoint = <_out>;
> > +};
> > +  };
> > +};
> > +
>
> You can drop the hdmi connector, the example will still validate.
Okay
>
> >  ...
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Jonathan Cormier
Software Engineer

Voice:  315.425.4045 x222



http://www.CriticalLink.com
6712 Brooklawn Parkway, Syracuse, NY 13211


Re: [RESEND PATCH v11 13/18] drm: exynos: dsi: Add Exynos based host irq hooks

2023-01-25 Thread Marek Vasut

On 1/25/23 20:24, Jagan Teki wrote:

On Wed, Jan 25, 2023 at 11:33 PM Marek Vasut  wrote:


On 1/25/23 18:35, Jagan Teki wrote:

[...]


exynos_dsi_register_te_irq is done after the bridge attach is done in
Exynos, here bridge attach is triggered in the component ops bind
call, since samsung-dsim is a pure bridge w/o any component ops.
https://github.com/openedev/kernel/blob/imx8mm-dsi-v12/drivers/gpu/drm/bridge/samsung-dsim.c#L1527
https://github.com/openedev/kernel/blob/imx8mm-dsi-v12/drivers/gpu/drm/exynos/exynos_drm_dsi.c#L112

Any suggestion on how to handle this?


Why isn't the generic code calling drm_bridge_attach() in
samsung_dsim_host_attach(), like the exynos one ?


Exynos drm drivers follow component ops and generic dsim is a pure drm
bridge whose downstream bridge will attach in bridge ops attach and
the component-based drivers require an initial bridge attach (whose
previous is NULL) call in the component bind hook for establishing the
bridge chain.


Well in that case, call the exynos optional host_attach and register the
TE IRQ handler at the end, that should work just fine too, right ? If
so, then you can also move the IRQ handler registration into the generic
part of the driver.


Something like this?

samsung_dsim_host_attach()
{
 drm_bridge_add(>bridge);

 if (pdata->host_ops && pdata->host_ops->attach)
 pdata->host_ops->attach(dsi, device);

 exynos_dsi_register_te_irq

 dsi->lanes = device->lanes;
 dsi->format = device->format;
 dsi->mode_flags = device->mode_flags;
}


Yes, I think that should work .


Re: [PATCH] drm/nouveau/devinit: Convert function disable() to be void

2023-01-25 Thread Lyude Paul
Reviewed-by: Lyude Paul 

Will push upstream in a moment

On Wed, 2023-01-25 at 20:37 +0530, Deepak R Varma wrote:
> The current design of callback function disable() of struct
> nvkm_devinit_func is defined to return a u64 value. In its implementation
> in the driver modules, the function always returns a fixed value 0. Hence
> the design and implementation of this function should be enhanced to return
> void instead of a fixed value. This change also eliminates untouched
> return variables.
> 
> The change is identified using the returnvar.cocci Coccinelle semantic
> patch script.
> 
> Signed-off-by: Deepak R Varma 
> ---
> Please note: The change is compile build tested only.
> 
>  drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c  | 3 ++-
>  drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g84.c   | 5 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g98.c   | 4 +---
>  drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c | 4 +---
>  drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c | 4 +---
>  drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gt215.c | 4 +---
>  drivers/gpu/drm/nouveau/nvkm/subdev/devinit/mcp89.c | 4 +---
>  drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c  | 5 +
>  drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h  | 2 +-
>  drivers/gpu/drm/nouveau/nvkm/subdev/devinit/priv.h  | 2 +-
>  10 files changed, 11 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
> index dd4981708fe4..3d9319c319c6 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
> @@ -51,7 +51,8 @@ u64
>  nvkm_devinit_disable(struct nvkm_devinit *init)
>  {
>   if (init && init->func->disable)
> - return init->func->disable(init);
> + init->func->disable(init);
> +
>   return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g84.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g84.c
> index c224702b7bed..00df7811dd10 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g84.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g84.c
> @@ -26,13 +26,12 @@
>  #include 
>  #include 
>  
> -static u64
> +static void
>  g84_devinit_disable(struct nvkm_devinit *init)
>  {
>   struct nvkm_device *device = init->subdev.device;
>   u32 r001540 = nvkm_rd32(device, 0x001540);
>   u32 r00154c = nvkm_rd32(device, 0x00154c);
> - u64 disable = 0ULL;
>  
>   if (!(r001540 & 0x4000)) {
>   nvkm_subdev_disable(device, NVKM_ENGINE_MPEG, 0);
> @@ -47,8 +46,6 @@ g84_devinit_disable(struct nvkm_devinit *init)
>   nvkm_subdev_disable(device, NVKM_ENGINE_BSP, 0);
>   if (!(r00154c & 0x0040))
>   nvkm_subdev_disable(device, NVKM_ENGINE_CIPHER, 0);
> -
> - return disable;
>  }
>  
>  static const struct nvkm_devinit_func
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g98.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g98.c
> index 8977483a9f42..54bee499b982 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g98.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g98.c
> @@ -26,7 +26,7 @@
>  #include 
>  #include 
>  
> -static u64
> +static void
>  g98_devinit_disable(struct nvkm_devinit *init)
>  {
>   struct nvkm_device *device = init->subdev.device;
> @@ -45,8 +45,6 @@ g98_devinit_disable(struct nvkm_devinit *init)
>   nvkm_subdev_disable(device, NVKM_ENGINE_MSVLD, 0);
>   if (!(r00154c & 0x0040))
>   nvkm_subdev_disable(device, NVKM_ENGINE_SEC, 0);
> -
> - return 0ULL;
>  }
>  
>  static const struct nvkm_devinit_func
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c
> index 5b7cb1fe7897..5368e705e7fd 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c
> @@ -63,7 +63,7 @@ gf100_devinit_pll_set(struct nvkm_devinit *init, u32 type, 
> u32 freq)
>   return ret;
>  }
>  
> -static u64
> +static void
>  gf100_devinit_disable(struct nvkm_devinit *init)
>  {
>   struct nvkm_device *device = init->subdev.device;
> @@ -85,8 +85,6 @@ gf100_devinit_disable(struct nvkm_devinit *init)
>   nvkm_subdev_disable(device, NVKM_ENGINE_CE, 0);
>   if (r022500 & 0x0200)
>   nvkm_subdev_disable(device, NVKM_ENGINE_CE, 1);
> -
> - return 0ULL;
>  }
>  
>  void
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c
> index 8955af2704c7..7bcbc4895ec2 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c
> @@ -26,7 +26,7 @@
>  #include 
>  #include 
>  
> -u64
> +void
>  gm107_devinit_disable(struct nvkm_devinit *init)
>  {
>   struct nvkm_device *device = 

Re: [PATCH 1/2] drm/i915/xehp: GAM registers don't need to be re-applied on engine resets

2023-01-25 Thread Matt Roper
On Wed, Jan 25, 2023 at 04:43:29PM -0300, Gustavo Sousa wrote:
> On Tue, Jan 24, 2023 at 05:14:06PM -0800, Matt Roper wrote:
> > Register reset characteristics (i.e., whether the register maintains or
> > loses its value on engine reset) is an important factor that determines
> > which wa_list we want to add workarounds to.  We recently found out that
> > the bspec documentation for the Xe_HP's "GAM" registers in the 0xC800 -
> > 0xCFFF range was misleading; these registers do not actually lose their
> > value on engine resets as the documentation implied.  This means there's
> > no need to re-apply workarounds touching these registers after a reset,
> > and the corresponding workarounds should be moved from the 'engine'
> > lists back to the 'gt' list.
> > 
> > While moving these GAM-related workarounds to the various platforms' GT
> > workaround functions, we should also take care to handle Wa_18018781329
> > properly for MTL's two GTs --- the render/compute setting should be set
> > on the primary GT where those engines reside, and the vd/ve/gsc setting
> > should be set on the media GT.  Previously the VD/VE/GSC setting was not
> > being properly applied.
> > 
> > Cc: Gustavo Sousa 
> > Fixes: edf176f48d87 ("drm/i915/dg2: Move misplaced 'ctx' & 'gt' wa's to 
> > engine wa list")
> > Fixes: b2006061ae28 ("drm/i915/xehpsdv: Move render/compute engine reset 
> > domains related workarounds")
> > Fixes: 41bb543f5598 ("drm/i915/mtl: Add initial gt workarounds")
> > Signed-off-by: Matt Roper 
> > ---
> >  drivers/gpu/drm/i915/gt/intel_gt_regs.h |  1 +
> >  drivers/gpu/drm/i915/gt/intel_workarounds.c | 88 +
> >  drivers/gpu/drm/i915/i915_drv.h |  4 +
> >  3 files changed, 59 insertions(+), 34 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
> > b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > index 2727645864db..4a37d048b512 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > @@ -1100,6 +1100,7 @@
> >  #define XEHP_MERT_MOD_CTRL MCR_REG(0xcf28)
> >  #define RENDER_MOD_CTRLMCR_REG(0xcf2c)
> >  #define COMP_MOD_CTRL  MCR_REG(0xcf30)
> > +#define GSC_MOD_CTRL   MCR_REG(0xcf30) /* 
> > media GT only */
> >  #define VDBX_MOD_CTRL  MCR_REG(0xcf34)
> >  #define VEBX_MOD_CTRL  MCR_REG(0xcf38)
> >  #define   FORCE_MISS_FTLB  REG_BIT(3)
> > diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c 
> > b/drivers/gpu/drm/i915/gt/intel_workarounds.c
> > index 4efc1a532982..0e7f64bb2860 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
> > @@ -1559,6 +1559,19 @@ xehpsdv_gt_workarounds_init(struct intel_gt *gt, 
> > struct i915_wa_list *wal)
> >  
> > /* Wa_14011060649:xehpsdv */
> > wa_14011060649(gt, wal);
> > +
> > +   /* Wa_18018781329 */
> > +   wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
> > +   wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);
> > +   wa_mcr_write_or(wal, VDBX_MOD_CTRL, FORCE_MISS_FTLB);
> > +   wa_mcr_write_or(wal, VEBX_MOD_CTRL, FORCE_MISS_FTLB);
> 
> Maybe worth mentioning in the commit message that Wa_18018781329 is being
> extended to XEHPSDV in this patch? This could also be on its own patch.

Yeah, it's probably better to just drop it from this patch.  We could
potentially add it to xehpsdv as a separate patch down the line if
necessary.

> 
> > +
> > +   /* Wa_14012362059:xehpsdv */
> > +   wa_mcr_write_or(wal, XEHP_MERT_MOD_CTRL, FORCE_MISS_FTLB);
> > +
> > +   /* Wa_14014368820:xehpsdv */
> > +   wa_write_or(wal, GEN12_GAMCNTRL_CTRL,
> > +   INVALIDATION_BROADCAST_MODE_DIS | GLOBAL_INVALIDATION_MODE);
> >  }
> >  
> >  static void
> > @@ -1599,6 +1612,12 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct 
> > i915_wa_list *wal)
> > DSS_ROUTER_CLKGATE_DIS);
> > }
> >  
> > +   if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_B0) ||
> > +   IS_DG2_GRAPHICS_STEP(gt->i915, G11, STEP_A0, STEP_B0)) {
> > +   /* Wa_14012362059:dg2 */
> > +   wa_mcr_write_or(wal, XEHP_MERT_MOD_CTRL, FORCE_MISS_FTLB);
> > +   }
> > +
> > if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_B0)) {
> > /* Wa_14010948348:dg2_g10 */
> > wa_write_or(wal, UNSLCGCTL9430, MSQDUNIT_CLKGATE_DIS);
> > @@ -1644,6 +1663,12 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct 
> > i915_wa_list *wal)
> >  
> > /* Wa_14011028019:dg2_g10 */
> > wa_mcr_write_or(wal, SSMCGCTL9530, RTFUNIT_CLKGATE_DIS);
> > +
> > +   /* Wa_14010680813:dg2_g10 */
> > +   wa_write_or(wal, GEN12_GAMSTLB_CTRL,
> > +   CONTROL_BLOCK_CLKGATE_DIS |
> > +   EGRESS_BLOCK_CLKGATE_DIS |
> > +  

Re: [PATCH 1/4] dt-bindings: display: bridge: tfp410: Add tfp410 i2c example

2023-01-25 Thread Laurent Pinchart
Hi Jonathan,

Thank you for the patch.

On Wed, Jan 25, 2023 at 04:09:09PM -0500, Jonathan Cormier wrote:
> Add a i2c example with HDMI connector
> 
> Signed-off-by: Jonathan Cormier 
> ---
>  .../bindings/display/bridge/ti,tfp410.yaml | 42 
> ++
>  1 file changed, 42 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml 
> b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml
> index 4c5dd8ec2951..456214f14b47 100644
> --- a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml
> +++ b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml
> @@ -116,4 +116,46 @@ examples:
>  };
>  };
>  
> +  - |
> +i2c {
> +  #address-cells = <1>;
> +  #size-cells = <0>;

Please use 4 spaces for indentation, as in the other example.

> +
> +  hdmi_encoder: tfp410@38 {
> +compatible = "ti,tfp410";
> +reg = <0x38>;
> +
> +ports {
> +  address-cells = <1>;
> +  size-cells = <0>;
> +
> +  port@0 {
> +reg = <0>;
> +tfp410_in: endpoint {
> +  remote-endpoint = <_out>;
> +};
> +  };
> +
> +  port@1 {
> +reg = <1>;
> +tfp410_out: endpoint {
> +  remote-endpoint = <_connector_in>;
> +};
> +  };
> +};
> +  };
> +};
> +
> +hdmi: hdmi_connector {
> +  compatible = "hdmi-connector";
> +  label = "hdmi";
> +  type = "a";
> +  ddc-i2c-bus = <>;
> +  port {
> +hdmi_connector_in: endpoint {
> +  remote-endpoint = <_out>;
> +};
> +  };
> +};
> +

You can drop the hdmi connector, the example will still validate.

>  ...

-- 
Regards,

Laurent Pinchart


[PATCH 4/4] DRM: BRIDGE: TFP410: If connected, use I2C for polled HPD status.

2023-01-25 Thread Jonathan Cormier
From: Michael Williamson 

If the I2C bus is connected on the TFP410, then use the register
status bit to determine connection state.  This is needed, in particular,
for polling the state when the Hot Plug detect is not connected to
a controlling CPU via GPIO/IRQ lane.

Signed-off-by: Michael Williamson 
Signed-off-by: Jonathan Cormier 
---
 drivers/gpu/drm/bridge/ti-tfp410.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c 
b/drivers/gpu/drm/bridge/ti-tfp410.c
index 837e1f81a0ff..ac216eaec3c8 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -28,6 +28,9 @@
 #define TFP410_BIT_BSEL BIT(2)
 #define TFP410_BIT_DSEL BIT(3)
 
+#define TFP410_REG_CTL_2_MODE  0x09
+#define TFP410_BIT_HTPLG BIT(1)
+
 static const struct regmap_config tfp410_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -105,6 +108,16 @@ static enum drm_connector_status
 tfp410_connector_detect(struct drm_connector *connector, bool force)
 {
struct tfp410 *dvi = drm_connector_to_tfp410(connector);
+   u32 val;
+   unsigned int ret;
+
+   if (dvi->i2c) {
+   ret = regmap_test_bits(dvi->regmap, TFP410_REG_CTL_2_MODE, 
TFP410_BIT_HTPLG);
+   if (ret < 0)
+   dev_err(dvi->dev, "%s failed to read HTPLG bit : %d\n", 
__func__, ret);
+   else
+   return ret ? connector_status_connected : 
connector_status_disconnected;
+   }
 
return drm_bridge_detect(dvi->next_bridge);
 }

-- 
2.25.1


[PATCH 1/4] dt-bindings: display: bridge: tfp410: Add tfp410 i2c example

2023-01-25 Thread Jonathan Cormier
Add a i2c example with HDMI connector

Signed-off-by: Jonathan Cormier 
---
 .../bindings/display/bridge/ti,tfp410.yaml | 42 ++
 1 file changed, 42 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml 
b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml
index 4c5dd8ec2951..456214f14b47 100644
--- a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml
@@ -116,4 +116,46 @@ examples:
 };
 };
 
+  - |
+i2c {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  hdmi_encoder: tfp410@38 {
+compatible = "ti,tfp410";
+reg = <0x38>;
+
+ports {
+  address-cells = <1>;
+  size-cells = <0>;
+
+  port@0 {
+reg = <0>;
+tfp410_in: endpoint {
+  remote-endpoint = <_out>;
+};
+  };
+
+  port@1 {
+reg = <1>;
+tfp410_out: endpoint {
+  remote-endpoint = <_connector_in>;
+};
+  };
+};
+  };
+};
+
+hdmi: hdmi_connector {
+  compatible = "hdmi-connector";
+  label = "hdmi";
+  type = "a";
+  ddc-i2c-bus = <>;
+  port {
+hdmi_connector_in: endpoint {
+  remote-endpoint = <_out>;
+};
+  };
+};
+
 ...

-- 
2.25.1


[PATCH v2 6/6] mm: export dump_mm()

2023-01-25 Thread Suren Baghdasaryan
mmap_assert_write_locked() is used in vm_flags modifiers. Because
mmap_assert_write_locked() uses dump_mm() and vm_flags are sometimes
modified from from inside a module, it's necessary to export
dump_mm() function.

Signed-off-by: Suren Baghdasaryan 
---
 mm/debug.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/debug.c b/mm/debug.c
index 9d3d893dc7f4..96d594e16292 100644
--- a/mm/debug.c
+++ b/mm/debug.c
@@ -215,6 +215,7 @@ void dump_mm(const struct mm_struct *mm)
mm->def_flags, >def_flags
);
 }
+EXPORT_SYMBOL(dump_mm);
 
 static bool page_init_poisoning __read_mostly = true;
 
-- 
2.39.1



Re: [PATCH] drm/nouveau/disp: Fix nvif_outp_acquire_dp() argument size

2023-01-25 Thread Lyude Paul
Sorry! I've been pretty busy until now, this is:

Reviewed-by: Lyude Paul 

Let me know if you've pushed it already or if you want me to push it to drm-
misc

On Wed, 2023-01-25 at 12:15 -0800, Kees Cook wrote:
> Ping. I'll take this via my tree unless someone else wants to take it...
> 
> On Sun, Nov 27, 2022 at 10:30:41AM -0800, Kees Cook wrote:
> > Both Coverity and GCC with -Wstringop-overflow noticed that
> > nvif_outp_acquire_dp() accidentally defined its second argument with 1
> > additional element:
> > 
> > drivers/gpu/drm/nouveau/dispnv50/disp.c: In function 
> > 'nv50_pior_atomic_enable':
> > drivers/gpu/drm/nouveau/dispnv50/disp.c:1813:17: error: 
> > 'nvif_outp_acquire_dp' accessing 16 bytes in a region of size 15 
> > [-Werror=stringop-overflow=]
> >  1813 | nvif_outp_acquire_dp(_encoder->outp, 
> > nv_encoder->dp.dpcd, 0, 0, false, false);
> >   | 
> > ^~~
> > drivers/gpu/drm/nouveau/dispnv50/disp.c:1813:17: note: referencing argument 
> > 2 of type 'u8[16]' {aka 'unsigned char[16]'}
> > drivers/gpu/drm/nouveau/include/nvif/outp.h:24:5: note: in a call to 
> > function 'nvif_outp_acquire_dp'
> >24 | int nvif_outp_acquire_dp(struct nvif_outp *, u8 dpcd[16],
> >   | ^~~~
> > 
> > Avoid these warnings by defining the argument size using the matching
> > define (DP_RECEIVER_CAP_SIZE, 15) instead of having it be a literal
> > (and incorrect) value (16).
> > 
> > Reported-by: coverity-bot 
> > Addresses-Coverity-ID: 1527269 ("Memory - corruptions")
> > Addresses-Coverity-ID: 1527268 ("Memory - corruptions")
> > Link: https://lore.kernel.org/lkml/202211100848.FFBA2432@keescook/
> > Link: https://lore.kernel.org/lkml/202211100848.F4C2819BB@keescook/
> > Fixes: 813443721331 ("drm/nouveau/disp: move DP link config into acquire")
> > Cc: Ben Skeggs 
> > Cc: Karol Herbst 
> > Cc: Lyude Paul 
> > Cc: David Airlie 
> > Cc: Daniel Vetter 
> > Cc: Dave Airlie 
> > Cc: "Gustavo A. R. Silva" 
> > Cc: dri-devel@lists.freedesktop.org
> > Cc: nouv...@lists.freedesktop.org
> > Signed-off-by: Kees Cook 
> > ---
> >  drivers/gpu/drm/nouveau/include/nvif/outp.h | 3 ++-
> >  drivers/gpu/drm/nouveau/nvif/outp.c | 2 +-
> >  2 files changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h 
> > b/drivers/gpu/drm/nouveau/include/nvif/outp.h
> > index 45daadec3c0c..fa76a7b5e4b3 100644
> > --- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
> > +++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
> > @@ -3,6 +3,7 @@
> >  #define __NVIF_OUTP_H__
> >  #include 
> >  #include 
> > +#include 
> >  struct nvif_disp;
> >  
> >  struct nvif_outp {
> > @@ -21,7 +22,7 @@ int nvif_outp_acquire_rgb_crt(struct nvif_outp *);
> >  int nvif_outp_acquire_tmds(struct nvif_outp *, int head,
> >bool hdmi, u8 max_ac_packet, u8 rekey, u8 scdc, bool 
> > hda);
> >  int nvif_outp_acquire_lvds(struct nvif_outp *, bool dual, bool bpc8);
> > -int nvif_outp_acquire_dp(struct nvif_outp *, u8 dpcd[16],
> > +int nvif_outp_acquire_dp(struct nvif_outp *outp, u8 
> > dpcd[DP_RECEIVER_CAP_SIZE],
> >  int link_nr, int link_bw, bool hda, bool mst);
> >  void nvif_outp_release(struct nvif_outp *);
> >  int nvif_outp_infoframe(struct nvif_outp *, u8 type, struct 
> > nvif_outp_infoframe_v0 *, u32 size);
> > diff --git a/drivers/gpu/drm/nouveau/nvif/outp.c 
> > b/drivers/gpu/drm/nouveau/nvif/outp.c
> > index 7da39f1eae9f..c24bc5eae3ec 100644
> > --- a/drivers/gpu/drm/nouveau/nvif/outp.c
> > +++ b/drivers/gpu/drm/nouveau/nvif/outp.c
> > @@ -127,7 +127,7 @@ nvif_outp_acquire(struct nvif_outp *outp, u8 proto, 
> > struct nvif_outp_acquire_v0
> >  }
> >  
> >  int
> > -nvif_outp_acquire_dp(struct nvif_outp *outp, u8 dpcd[16],
> > +nvif_outp_acquire_dp(struct nvif_outp *outp, u8 dpcd[DP_RECEIVER_CAP_SIZE],
> >  int link_nr, int link_bw, bool hda, bool mst)
> >  {
> > struct nvif_outp_acquire_v0 args;
> > -- 
> > 2.34.1
> > 
> 

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



[PATCH v2 3/6] mm: replace vma->vm_flags direct modifications with modifier calls

2023-01-25 Thread Suren Baghdasaryan
Replace direct modifications to vma->vm_flags with calls to modifier
functions to be able to track flag changes and to keep vma locking
correctness.

Signed-off-by: Suren Baghdasaryan 
---
 arch/arm/kernel/process.c  |  2 +-
 arch/ia64/mm/init.c|  8 
 arch/loongarch/include/asm/tlb.h   |  2 +-
 arch/powerpc/kvm/book3s_xive_native.c  |  2 +-
 arch/powerpc/mm/book3s64/subpage_prot.c|  2 +-
 arch/powerpc/platforms/book3s/vas-api.c|  2 +-
 arch/powerpc/platforms/cell/spufs/file.c   | 14 +++---
 arch/s390/mm/gmap.c|  3 +--
 arch/x86/entry/vsyscall/vsyscall_64.c  |  2 +-
 arch/x86/kernel/cpu/sgx/driver.c   |  2 +-
 arch/x86/kernel/cpu/sgx/virt.c |  2 +-
 arch/x86/mm/pat/memtype.c  |  6 +++---
 arch/x86/um/mem_32.c   |  2 +-
 drivers/acpi/pfr_telemetry.c   |  2 +-
 drivers/android/binder.c   |  3 +--
 drivers/char/mspec.c   |  2 +-
 drivers/crypto/hisilicon/qm.c  |  2 +-
 drivers/dax/device.c   |  2 +-
 drivers/dma/idxd/cdev.c|  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c|  2 +-
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c   |  4 ++--
 drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c  |  4 ++--
 drivers/gpu/drm/amd/amdkfd/kfd_events.c|  4 ++--
 drivers/gpu/drm/amd/amdkfd/kfd_process.c   |  4 ++--
 drivers/gpu/drm/drm_gem.c  |  2 +-
 drivers/gpu/drm/drm_gem_dma_helper.c   |  3 +--
 drivers/gpu/drm/drm_gem_shmem_helper.c |  2 +-
 drivers/gpu/drm/drm_vm.c   |  8 
 drivers/gpu/drm/etnaviv/etnaviv_gem.c  |  2 +-
 drivers/gpu/drm/exynos/exynos_drm_gem.c|  4 ++--
 drivers/gpu/drm/gma500/framebuffer.c   |  2 +-
 drivers/gpu/drm/i810/i810_dma.c|  2 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c   |  4 ++--
 drivers/gpu/drm/mediatek/mtk_drm_gem.c |  2 +-
 drivers/gpu/drm/msm/msm_gem.c  |  2 +-
 drivers/gpu/drm/omapdrm/omap_gem.c |  3 +--
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c|  3 +--
 drivers/gpu/drm/tegra/gem.c|  5 ++---
 drivers/gpu/drm/ttm/ttm_bo_vm.c|  3 +--
 drivers/gpu/drm/virtio/virtgpu_vram.c  |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c   |  2 +-
 drivers/gpu/drm/xen/xen_drm_front_gem.c|  3 +--
 drivers/hsi/clients/cmt_speech.c   |  2 +-
 drivers/hwtracing/intel_th/msu.c   |  2 +-
 drivers/hwtracing/stm/core.c   |  2 +-
 drivers/infiniband/hw/hfi1/file_ops.c  |  4 ++--
 drivers/infiniband/hw/mlx5/main.c  |  4 ++--
 drivers/infiniband/hw/qib/qib_file_ops.c   | 13 ++---
 drivers/infiniband/hw/usnic/usnic_ib_verbs.c   |  2 +-
 drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c|  2 +-
 .../media/common/videobuf2/videobuf2-dma-contig.c  |  2 +-
 drivers/media/common/videobuf2/videobuf2-vmalloc.c |  2 +-
 drivers/media/v4l2-core/videobuf-dma-contig.c  |  2 +-
 drivers/media/v4l2-core/videobuf-dma-sg.c  |  4 ++--
 drivers/media/v4l2-core/videobuf-vmalloc.c |  2 +-
 drivers/misc/cxl/context.c |  2 +-
 drivers/misc/habanalabs/common/memory.c|  2 +-
 drivers/misc/habanalabs/gaudi/gaudi.c  |  4 ++--
 drivers/misc/habanalabs/gaudi2/gaudi2.c|  8 
 drivers/misc/habanalabs/goya/goya.c|  4 ++--
 drivers/misc/ocxl/context.c|  4 ++--
 drivers/misc/ocxl/sysfs.c  |  2 +-
 drivers/misc/open-dice.c   |  4 ++--
 drivers/misc/sgi-gru/grufile.c |  4 ++--
 drivers/misc/uacce/uacce.c |  2 +-
 drivers/sbus/char/oradax.c |  2 +-
 drivers/scsi/cxlflash/ocxl_hw.c|  2 +-
 drivers/scsi/sg.c  |  2 +-
 drivers/staging/media/atomisp/pci/hmm/hmm_bo.c |  2 +-
 drivers/staging/media/deprecated/meye/meye.c   |  4 ++--
 .../media/deprecated/stkwebcam/stk-webcam.c|  2 +-
 drivers/target/target_core_user.c  |  2 +-
 drivers/uio/uio.c  |  2 +-
 drivers/usb/core/devio.c   |  3 +--
 drivers/usb/mon/mon_bin.c  |  3 +--
 drivers/vdpa/vdpa_user/iova_domain.c   |  2 +-
 drivers/vfio/pci/vfio_pci_core.c   |  2 +-
 drivers/vhost/vdpa.c   |  2 +-
 drivers/video/fbdev/68328fb.c 

[PATCH 0/4] DRM: BRIDGE: TFP410: Add i2c support

2023-01-25 Thread Jonathan Cormier
The TFP410 driver does not support I2C.  As such, the device remains in
Power Down if the I2C is enabled by the bootstrap pins.

Add basic support for the I2C interface, and provide support to take
the device out of power down when enabled.  Also read the bootstrap mode
pins via the CTL_1_MODE register when using the I2C bus.

Also allow polling device to support hdmi/dvi hotplug detection.

To: Andrzej Hajda 
To: Neil Armstrong 
To: Robert Foss 
To: Laurent Pinchart 
To: Jonas Karlman 
To: Jernej Skrabec 
To: David Airlie 
To: Daniel Vetter 
To: Rob Herring 
To: Krzysztof Kozlowski 
To: Tomi Valkeinen 
To: Jyri Sarha 
Cc: dri-devel@lists.freedesktop.org
Cc: devicet...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Cc: Michael Williamson 
Cc: Bob Duke 
Signed-off-by: Jonathan Cormier 

---
Jonathan Cormier (1):
  dt-bindings: display: bridge: tfp410: Add tfp410 i2c example

Michael Williamson (3):
  DRM: BRIDGE: TFP410: Support basic I2C interface
  DRM: BRIDGE: TFP410: Fix logic to configured polled HPD
  DRM: BRIDGE: TFP410: If connected, use I2C for polled HPD status.

 .../bindings/display/bridge/ti,tfp410.yaml |  42 
 drivers/gpu/drm/bridge/ti-tfp410.c | 110 +++--
 2 files changed, 124 insertions(+), 28 deletions(-)
---
base-commit: 93f875a8526a291005e7f38478079526c843cbec
change-id: 20230125-tfp410_i2c-3b270b0bf3e0

Best regards,
-- 
Jonathan Cormier 


Re: [PATCH v2 1/6] mm: introduce vma->vm_flags modifier functions

2023-01-25 Thread Peter Zijlstra
On Wed, Jan 25, 2023 at 12:38:46AM -0800, Suren Baghdasaryan wrote:

> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 2d6d790d9bed..6c7c70bf50dd 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -491,7 +491,13 @@ struct vm_area_struct {
>* See vmf_insert_mixed_prot() for discussion.
>*/
>   pgprot_t vm_page_prot;
> - unsigned long vm_flags; /* Flags, see mm.h. */
> +
> + /*
> +  * Flags, see mm.h.
> +  * WARNING! Do not modify directly.
> +  * Use {init|reset|set|clear|mod}_vm_flags() functions instead.
> +  */
> + unsigned long vm_flags;

We have __private and ACCESS_PRIVATE() to help with enforcing this.


Re: [PATCH v2 6/6] mm: export dump_mm()

2023-01-25 Thread Michal Hocko
On Wed 25-01-23 00:38:51, Suren Baghdasaryan wrote:
> mmap_assert_write_locked() is used in vm_flags modifiers. Because
> mmap_assert_write_locked() uses dump_mm() and vm_flags are sometimes
> modified from from inside a module, it's necessary to export
> dump_mm() function.
> 
> Signed-off-by: Suren Baghdasaryan 

Acked-by: Michal Hocko 

> ---
>  mm/debug.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/mm/debug.c b/mm/debug.c
> index 9d3d893dc7f4..96d594e16292 100644
> --- a/mm/debug.c
> +++ b/mm/debug.c
> @@ -215,6 +215,7 @@ void dump_mm(const struct mm_struct *mm)
>   mm->def_flags, >def_flags
>   );
>  }
> +EXPORT_SYMBOL(dump_mm);
>  
>  static bool page_init_poisoning __read_mostly = true;
>  
> -- 
> 2.39.1

-- 
Michal Hocko
SUSE Labs


Re: [PATCH v2 2/6] mm: replace VM_LOCKED_CLEAR_MASK with VM_LOCKED_MASK

2023-01-25 Thread Michal Hocko
On Wed 25-01-23 00:38:47, Suren Baghdasaryan wrote:
> To simplify the usage of VM_LOCKED_CLEAR_MASK in clear_vm_flags(),
> replace it with VM_LOCKED_MASK bitmask and convert all users.
>
> Signed-off-by: Suren Baghdasaryan 

Acked-by: Michal Hocko 

> ---
>  include/linux/mm.h | 4 ++--
>  kernel/fork.c  | 2 +-
>  mm/hugetlb.c   | 4 ++--
>  mm/mlock.c | 6 +++---
>  mm/mmap.c  | 6 +++---
>  mm/mremap.c| 2 +-
>  6 files changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index b71f2809caac..da62bdd627bf 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -421,8 +421,8 @@ extern unsigned int kobjsize(const void *objp);
>  /* This mask defines which mm->def_flags a process can inherit its parent */
>  #define VM_INIT_DEF_MASK VM_NOHUGEPAGE
>  
> -/* This mask is used to clear all the VMA flags used by mlock */
> -#define VM_LOCKED_CLEAR_MASK (~(VM_LOCKED | VM_LOCKONFAULT))
> +/* This mask represents all the VMA flag bits used by mlock */
> +#define VM_LOCKED_MASK   (VM_LOCKED | VM_LOCKONFAULT)
>  
>  /* Arch-specific flags to clear when updating VM flags on protection change 
> */
>  #ifndef VM_ARCH_CLEAR
> diff --git a/kernel/fork.c b/kernel/fork.c
> index 6683c1b0f460..03d472051236 100644
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -669,7 +669,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
>   tmp->anon_vma = NULL;
>   } else if (anon_vma_fork(tmp, mpnt))
>   goto fail_nomem_anon_vma_fork;
> - tmp->vm_flags &= ~(VM_LOCKED | VM_LOCKONFAULT);
> + clear_vm_flags(tmp, VM_LOCKED_MASK);
>   file = tmp->vm_file;
>   if (file) {
>   struct address_space *mapping = file->f_mapping;
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index d20c8b09890e..4ecdbad9a451 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -6973,8 +6973,8 @@ static unsigned long page_table_shareable(struct 
> vm_area_struct *svma,
>   unsigned long s_end = sbase + PUD_SIZE;
>  
>   /* Allow segments to share if only one is marked locked */
> - unsigned long vm_flags = vma->vm_flags & VM_LOCKED_CLEAR_MASK;
> - unsigned long svm_flags = svma->vm_flags & VM_LOCKED_CLEAR_MASK;
> + unsigned long vm_flags = vma->vm_flags & ~VM_LOCKED_MASK;
> + unsigned long svm_flags = svma->vm_flags & ~VM_LOCKED_MASK;
>  
>   /*
>* match the virtual addresses, permission and the alignment of the
> diff --git a/mm/mlock.c b/mm/mlock.c
> index 0336f52e03d7..5c4fff93cd6b 100644
> --- a/mm/mlock.c
> +++ b/mm/mlock.c
> @@ -497,7 +497,7 @@ static int apply_vma_lock_flags(unsigned long start, 
> size_t len,
>   if (vma->vm_start != tmp)
>   return -ENOMEM;
>  
> - newflags = vma->vm_flags & VM_LOCKED_CLEAR_MASK;
> + newflags = vma->vm_flags & ~VM_LOCKED_MASK;
>   newflags |= flags;
>   /* Here we know that  vma->vm_start <= nstart < vma->vm_end. */
>   tmp = vma->vm_end;
> @@ -661,7 +661,7 @@ static int apply_mlockall_flags(int flags)
>   struct vm_area_struct *vma, *prev = NULL;
>   vm_flags_t to_add = 0;
>  
> - current->mm->def_flags &= VM_LOCKED_CLEAR_MASK;
> + current->mm->def_flags &= ~VM_LOCKED_MASK;
>   if (flags & MCL_FUTURE) {
>   current->mm->def_flags |= VM_LOCKED;
>  
> @@ -681,7 +681,7 @@ static int apply_mlockall_flags(int flags)
>   for_each_vma(vmi, vma) {
>   vm_flags_t newflags;
>  
> - newflags = vma->vm_flags & VM_LOCKED_CLEAR_MASK;
> + newflags = vma->vm_flags & ~VM_LOCKED_MASK;
>   newflags |= to_add;
>  
>   /* Ignore errors */
> diff --git a/mm/mmap.c b/mm/mmap.c
> index d4abc6feced1..323bd253b25a 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -2671,7 +2671,7 @@ unsigned long mmap_region(struct file *file, unsigned 
> long addr,
>   if ((vm_flags & VM_SPECIAL) || vma_is_dax(vma) ||
>   is_vm_hugetlb_page(vma) ||
>   vma == get_gate_vma(current->mm))
> - vma->vm_flags &= VM_LOCKED_CLEAR_MASK;
> + clear_vm_flags(vma, VM_LOCKED_MASK);
>   else
>   mm->locked_vm += (len >> PAGE_SHIFT);
>   }
> @@ -3340,8 +3340,8 @@ static struct vm_area_struct *__install_special_mapping(
>   vma->vm_start = addr;
>   vma->vm_end = addr + len;
>  
> - vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND | VM_SOFTDIRTY;
> - vma->vm_flags &= VM_LOCKED_CLEAR_MASK;
> + init_vm_flags(vma, (vm_flags | mm->def_flags |
> +   VM_DONTEXPAND | VM_SOFTDIRTY) & ~VM_LOCKED_MASK);
>   vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
>  
>   vma->vm_ops = ops;
> diff --git a/mm/mremap.c b/mm/mremap.c
> index 

[PATCH v2 0/6] introduce vm_flags modifier functions

2023-01-25 Thread Suren Baghdasaryan
This patchset was originally published as a part of per-VMA locking [1] and
was split after suggestion that it's viable on its own and to facilitate
the review process. It is now a preprequisite for the next version of per-VMA
lock patchset, which reuses vm_flags modifier functions to lock the VMA when
vm_flags are being updated.

VMA vm_flags modifications are usually done under exclusive mmap_lock
protection because this attrubute affects other decisions like VMA merging
or splitting and races should be prevented. Introduce vm_flags modifier
functions to enforce correct locking.

[1] https://lore.kernel.org/all/20230109205336.3665937-1-sur...@google.com/

The patchset applies cleanly over mm-unstable branch of mm tree.

My apologies for an extremely large distribution list. The patch touches
lots of files and many are in arch/ and drivers/.

Suren Baghdasaryan (6):
  mm: introduce vma->vm_flags modifier functions
  mm: replace VM_LOCKED_CLEAR_MASK with VM_LOCKED_MASK
  mm: replace vma->vm_flags direct modifications with modifier calls
  mm: replace vma->vm_flags indirect modification in ksm_madvise
  mm: introduce mod_vm_flags_nolock and use it in untrack_pfn
  mm: export dump_mm()

 arch/arm/kernel/process.c |  2 +-
 arch/ia64/mm/init.c   |  8 +--
 arch/loongarch/include/asm/tlb.h  |  2 +-
 arch/powerpc/kvm/book3s_hv_uvmem.c|  5 +-
 arch/powerpc/kvm/book3s_xive_native.c |  2 +-
 arch/powerpc/mm/book3s64/subpage_prot.c   |  2 +-
 arch/powerpc/platforms/book3s/vas-api.c   |  2 +-
 arch/powerpc/platforms/cell/spufs/file.c  | 14 ++---
 arch/s390/mm/gmap.c   |  8 +--
 arch/x86/entry/vsyscall/vsyscall_64.c |  2 +-
 arch/x86/kernel/cpu/sgx/driver.c  |  2 +-
 arch/x86/kernel/cpu/sgx/virt.c|  2 +-
 arch/x86/mm/pat/memtype.c | 14 +++--
 arch/x86/um/mem_32.c  |  2 +-
 drivers/acpi/pfr_telemetry.c  |  2 +-
 drivers/android/binder.c  |  3 +-
 drivers/char/mspec.c  |  2 +-
 drivers/crypto/hisilicon/qm.c |  2 +-
 drivers/dax/device.c  |  2 +-
 drivers/dma/idxd/cdev.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  2 +-
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c  |  4 +-
 drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c |  4 +-
 drivers/gpu/drm/amd/amdkfd/kfd_events.c   |  4 +-
 drivers/gpu/drm/amd/amdkfd/kfd_process.c  |  4 +-
 drivers/gpu/drm/drm_gem.c |  2 +-
 drivers/gpu/drm/drm_gem_dma_helper.c  |  3 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c|  2 +-
 drivers/gpu/drm/drm_vm.c  |  8 +--
 drivers/gpu/drm/etnaviv/etnaviv_gem.c |  2 +-
 drivers/gpu/drm/exynos/exynos_drm_gem.c   |  4 +-
 drivers/gpu/drm/gma500/framebuffer.c  |  2 +-
 drivers/gpu/drm/i810/i810_dma.c   |  2 +-
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_gem.c|  2 +-
 drivers/gpu/drm/msm/msm_gem.c |  2 +-
 drivers/gpu/drm/omapdrm/omap_gem.c|  3 +-
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c   |  3 +-
 drivers/gpu/drm/tegra/gem.c   |  5 +-
 drivers/gpu/drm/ttm/ttm_bo_vm.c   |  3 +-
 drivers/gpu/drm/virtio/virtgpu_vram.c |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c  |  2 +-
 drivers/gpu/drm/xen/xen_drm_front_gem.c   |  3 +-
 drivers/hsi/clients/cmt_speech.c  |  2 +-
 drivers/hwtracing/intel_th/msu.c  |  2 +-
 drivers/hwtracing/stm/core.c  |  2 +-
 drivers/infiniband/hw/hfi1/file_ops.c |  4 +-
 drivers/infiniband/hw/mlx5/main.c |  4 +-
 drivers/infiniband/hw/qib/qib_file_ops.c  | 13 +++--
 drivers/infiniband/hw/usnic/usnic_ib_verbs.c  |  2 +-
 .../infiniband/hw/vmw_pvrdma/pvrdma_verbs.c   |  2 +-
 .../common/videobuf2/videobuf2-dma-contig.c   |  2 +-
 .../common/videobuf2/videobuf2-vmalloc.c  |  2 +-
 drivers/media/v4l2-core/videobuf-dma-contig.c |  2 +-
 drivers/media/v4l2-core/videobuf-dma-sg.c |  4 +-
 drivers/media/v4l2-core/videobuf-vmalloc.c|  2 +-
 drivers/misc/cxl/context.c|  2 +-
 drivers/misc/habanalabs/common/memory.c   |  2 +-
 drivers/misc/habanalabs/gaudi/gaudi.c |  4 +-
 drivers/misc/habanalabs/gaudi2/gaudi2.c   |  8 +--
 drivers/misc/habanalabs/goya/goya.c   |  4 +-
 drivers/misc/ocxl/context.c   |  4 +-
 drivers/misc/ocxl/sysfs.c |  2 +-
 drivers/misc/open-dice.c  |  4 +-
 drivers/misc/sgi-gru/grufile.c|  4 +-
 drivers/misc/uacce/uacce.c|  2 +-
 drivers/sbus/char/oradax.c|  2 +-
 drivers/scsi/cxlflash/ocxl_hw.c   |  2 +-
 drivers/scsi/sg.c

Re: [PATCH v2 1/6] mm: introduce vma->vm_flags modifier functions

2023-01-25 Thread Matthew Wilcox
On Wed, Jan 25, 2023 at 12:38:46AM -0800, Suren Baghdasaryan wrote:
> +/* Use when VMA is not part of the VMA tree and needs no locking */
> +static inline void init_vm_flags(struct vm_area_struct *vma,
> +  unsigned long flags)
> +{
> + vma->vm_flags = flags;

vm_flags are supposed to have type vm_flags_t.  That's not been
fully realised yet, but perhaps we could avoid making it worse?

>   pgprot_t vm_page_prot;
> - unsigned long vm_flags; /* Flags, see mm.h. */
> +
> + /*
> +  * Flags, see mm.h.
> +  * WARNING! Do not modify directly.
> +  * Use {init|reset|set|clear|mod}_vm_flags() functions instead.
> +  */
> + unsigned long vm_flags;

Including changing this line to vm_flags_t


[PATCH 2/4] DRM: BRIDGE: TFP410: Support basic I2C interface

2023-01-25 Thread Jonathan Cormier
From: Michael Williamson 

The TFP410 driver does not support I2C.  As such, the device remains in
Power Down if the I2C is enabled by the bootstrap pins.

Add basic support for the I2C interface, and provide support to take
the device out of power down when enabled.  Also read the bootstrap mode
pins via the CTL_1_MODE register when using the I2C bus.

Signed-off-by: Michael Williamson 
Signed-off-by: Jonathan Cormier 
---
 drivers/gpu/drm/bridge/ti-tfp410.c | 95 +++---
 1 file changed, 68 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c 
b/drivers/gpu/drm/bridge/ti-tfp410.c
index b9635abbad16..323a6d9ed188 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -6,6 +6,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -21,6 +22,20 @@
 
 #define HOTPLUG_DEBOUNCE_MS1100
 
+#define TFP410_REG_CTL_1_MODE  0x08
+#define TFP410_BIT_PD   BIT(0)
+#define TFP410_BIT_EDGE BIT(1)
+#define TFP410_BIT_BSEL BIT(2)
+#define TFP410_BIT_DSEL BIT(3)
+
+static const struct regmap_config tfp410_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+
+   .max_register = 0xff,
+   .cache_type = REGCACHE_NONE,
+};
+
 struct tfp410 {
struct drm_bridge   bridge;
struct drm_connectorconnector;
@@ -33,6 +48,8 @@ struct tfp410 {
struct drm_bridge   *next_bridge;
 
struct device *dev;
+   struct i2c_client *i2c;
+   struct regmap *regmap;
 };
 
 static inline struct tfp410 *
@@ -183,6 +200,9 @@ static void tfp410_enable(struct drm_bridge *bridge)
 {
struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
 
+   if (dvi->i2c)
+   regmap_set_bits(dvi->regmap, TFP410_REG_CTL_1_MODE, 
TFP410_BIT_PD);
+
gpiod_set_value_cansleep(dvi->powerdown, 0);
 }
 
@@ -190,6 +210,9 @@ static void tfp410_disable(struct drm_bridge *bridge)
 {
struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
 
+   if (dvi->i2c)
+   regmap_clear_bits(dvi->regmap, TFP410_REG_CTL_1_MODE, 
TFP410_BIT_PD);
+
gpiod_set_value_cansleep(dvi->powerdown, 1);
 }
 
@@ -221,38 +244,48 @@ static const struct drm_bridge_timings 
tfp410_default_timings = {
.hold_time_ps = 1300,
 };
 
-static int tfp410_parse_timings(struct tfp410 *dvi, bool i2c)
+static int tfp410_parse_timings(struct tfp410 *dvi)
 {
struct drm_bridge_timings *timings = >timings;
struct device_node *ep;
u32 pclk_sample = 0;
u32 bus_width = 24;
u32 deskew = 0;
+   unsigned int val = 0;
+   int ret = 0;
 
/* Start with defaults. */
*timings = tfp410_default_timings;
 
-   if (i2c)
+   if (dvi->i2c) {
/*
-* In I2C mode timings are configured through the I2C interface.
-* As the driver doesn't support I2C configuration yet, we just
-* go with the defaults (BSEL=1, DSEL=1, DKEN=0, EDGE=1).
+* For now, assume settings are latched from pins on reset / 
power up.
+* Should add options to optionally set them out of DT 
properties.
 */
-   return 0;
-
-   /*
-* In non-I2C mode, timings are configured through the BSEL, DSEL, DKEN
-* and EDGE pins. They are specified in DT through endpoint properties
-* and vendor-specific properties.
-*/
-   ep = of_graph_get_endpoint_by_regs(dvi->dev->of_node, 0, 0);
-   if (!ep)
-   return -EINVAL;
-
-   /* Get the sampling edge from the endpoint. */
-   of_property_read_u32(ep, "pclk-sample", _sample);
-   of_property_read_u32(ep, "bus-width", _width);
-   of_node_put(ep);
+   ret = regmap_read(dvi->regmap, TFP410_REG_CTL_1_MODE, );
+   if (ret) {
+   dev_err(dvi->dev, "Read failed on CTL_1_MODE\n");
+   return ret;
+   }
+   pclk_sample = (val & TFP410_BIT_EDGE) ? 1 : 0;
+   bus_width = (val & TFP410_BIT_BSEL) ? 24 : 12;
+   dev_dbg(dvi->dev, "(0x%02X) : detected %d bus width, %s edge 
sampling\n",
+   val, bus_width, pclk_sample ? "positive" : "negative");
+   } else {
+   /*
+* In non-I2C mode, timings are configured through the BSEL, 
DSEL, DKEN
+* and EDGE pins. They are specified in DT through endpoint 
properties
+* and vendor-specific properties.
+*/
+   ep = of_graph_get_endpoint_by_regs(dvi->dev->of_node, 0, 0);
+   if (!ep)
+   return -EINVAL;
+
+   /* Get the sampling edge from the endpoint. */
+   of_property_read_u32(ep, "pclk-sample", _sample);
+   of_property_read_u32(ep, "bus-width", _width);
+   of_node_put(ep);
+   }
 

[PATCH v2 4/6] mm: replace vma->vm_flags indirect modification in ksm_madvise

2023-01-25 Thread Suren Baghdasaryan
Replace indirect modifications to vma->vm_flags with calls to modifier
functions to be able to track flag changes and to keep vma locking
correctness. Add a BUG_ON check in ksm_madvise() to catch indirect
vm_flags modification attempts.

Signed-off-by: Suren Baghdasaryan 
---
 arch/powerpc/kvm/book3s_hv_uvmem.c | 5 -
 arch/s390/mm/gmap.c| 5 -
 mm/khugepaged.c| 2 ++
 mm/ksm.c   | 2 ++
 4 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c 
b/arch/powerpc/kvm/book3s_hv_uvmem.c
index 1d67baa5557a..325a7a47d348 100644
--- a/arch/powerpc/kvm/book3s_hv_uvmem.c
+++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
@@ -393,6 +393,7 @@ static int kvmppc_memslot_page_merge(struct kvm *kvm,
 {
unsigned long gfn = memslot->base_gfn;
unsigned long end, start = gfn_to_hva(kvm, gfn);
+   unsigned long vm_flags;
int ret = 0;
struct vm_area_struct *vma;
int merge_flag = (merge) ? MADV_MERGEABLE : MADV_UNMERGEABLE;
@@ -409,12 +410,14 @@ static int kvmppc_memslot_page_merge(struct kvm *kvm,
ret = H_STATE;
break;
}
+   vm_flags = vma->vm_flags;
ret = ksm_madvise(vma, vma->vm_start, vma->vm_end,
- merge_flag, >vm_flags);
+ merge_flag, _flags);
if (ret) {
ret = H_STATE;
break;
}
+   reset_vm_flags(vma, vm_flags);
start = vma->vm_end;
} while (end > vma->vm_end);
 
diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
index 3a695b8a1e3c..d5eb47dcdacb 100644
--- a/arch/s390/mm/gmap.c
+++ b/arch/s390/mm/gmap.c
@@ -2587,14 +2587,17 @@ int gmap_mark_unmergeable(void)
 {
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
+   unsigned long vm_flags;
int ret;
VMA_ITERATOR(vmi, mm, 0);
 
for_each_vma(vmi, vma) {
+   vm_flags = vma->vm_flags;
ret = ksm_madvise(vma, vma->vm_start, vma->vm_end,
- MADV_UNMERGEABLE, >vm_flags);
+ MADV_UNMERGEABLE, _flags);
if (ret)
return ret;
+   reset_vm_flags(vma, vm_flags);
}
mm->def_flags &= ~VM_MERGEABLE;
return 0;
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 8abc59345bf2..76b24cd0c179 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -354,6 +354,8 @@ struct attribute_group khugepaged_attr_group = {
 int hugepage_madvise(struct vm_area_struct *vma,
 unsigned long *vm_flags, int advice)
 {
+   /* vma->vm_flags can be changed only using modifier functions */
+   BUG_ON(vm_flags == >vm_flags);
switch (advice) {
case MADV_HUGEPAGE:
 #ifdef CONFIG_S390
diff --git a/mm/ksm.c b/mm/ksm.c
index 04f1c8c2df11..992b2be9f5e6 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -2573,6 +2573,8 @@ int ksm_madvise(struct vm_area_struct *vma, unsigned long 
start,
struct mm_struct *mm = vma->vm_mm;
int err;
 
+   /* vma->vm_flags can be changed only using modifier functions */
+   BUG_ON(vm_flags == >vm_flags);
switch (advice) {
case MADV_MERGEABLE:
/*
-- 
2.39.1



Re: [PATCH v2 4/6] mm: replace vma->vm_flags indirect modification in ksm_madvise

2023-01-25 Thread Michal Hocko
On Wed 25-01-23 00:38:49, Suren Baghdasaryan wrote:
> Replace indirect modifications to vma->vm_flags with calls to modifier
> functions to be able to track flag changes and to keep vma locking
> correctness. Add a BUG_ON check in ksm_madvise() to catch indirect
> vm_flags modification attempts.

Those BUG_ONs scream to much IMHO. KSM is an MM internal code so I
gueess we should be willing to trust it.

> Signed-off-by: Suren Baghdasaryan 

Acked-by: Michal Hocko 
-- 
Michal Hocko
SUSE Labs


Re: [PATCH v2 5/6] mm: introduce mod_vm_flags_nolock and use it in untrack_pfn

2023-01-25 Thread Suren Baghdasaryan
On Wed, Jan 25, 2023 at 1:42 AM Michal Hocko  wrote:
>
> On Wed 25-01-23 00:38:50, Suren Baghdasaryan wrote:
> > In cases when VMA flags are modified after VMA was isolated and mmap_lock
> > was downgraded, flags modifications would result in an assertion because
> > mmap write lock is not held.
> > Introduce mod_vm_flags_nolock to be used in such situation.
> > Pass a hint to untrack_pfn to conditionally use mod_vm_flags_nolock for
> > flags modification and to avoid assertion.
>
> The changelog nor the documentation of mod_vm_flags_nolock
> really explain when it is safe to use it. This is really important for
> future potential users.

True. I'll add clarification in the comments and in the changelog. Thanks!

>
> > Signed-off-by: Suren Baghdasaryan 
> > ---
> >  arch/x86/mm/pat/memtype.c | 10 +++---
> >  include/linux/mm.h| 12 +---
> >  include/linux/pgtable.h   |  5 +++--
> >  mm/memory.c   | 13 +++--
> >  mm/memremap.c |  4 ++--
> >  mm/mmap.c | 16 ++--
> >  6 files changed, 38 insertions(+), 22 deletions(-)
> >
> > diff --git a/arch/x86/mm/pat/memtype.c b/arch/x86/mm/pat/memtype.c
> > index ae9645c900fa..d8adc0b42cf2 100644
> > --- a/arch/x86/mm/pat/memtype.c
> > +++ b/arch/x86/mm/pat/memtype.c
> > @@ -1046,7 +1046,7 @@ void track_pfn_insert(struct vm_area_struct *vma, 
> > pgprot_t *prot, pfn_t pfn)
> >   * can be for the entire vma (in which case pfn, size are zero).
> >   */
> >  void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
> > -  unsigned long size)
> > +  unsigned long size, bool mm_wr_locked)
> >  {
> >   resource_size_t paddr;
> >   unsigned long prot;
> > @@ -1065,8 +1065,12 @@ void untrack_pfn(struct vm_area_struct *vma, 
> > unsigned long pfn,
> >   size = vma->vm_end - vma->vm_start;
> >   }
> >   free_pfn_range(paddr, size);
> > - if (vma)
> > - clear_vm_flags(vma, VM_PAT);
> > + if (vma) {
> > + if (mm_wr_locked)
> > + clear_vm_flags(vma, VM_PAT);
> > + else
> > + mod_vm_flags_nolock(vma, 0, VM_PAT);
> > + }
> >  }
> >
> >  /*
> > diff --git a/include/linux/mm.h b/include/linux/mm.h
> > index 55335edd1373..48d49930c411 100644
> > --- a/include/linux/mm.h
> > +++ b/include/linux/mm.h
> > @@ -656,12 +656,18 @@ static inline void clear_vm_flags(struct 
> > vm_area_struct *vma,
> >   vma->vm_flags &= ~flags;
> >  }
> >
> > +static inline void mod_vm_flags_nolock(struct vm_area_struct *vma,
> > +unsigned long set, unsigned long clear)
> > +{
> > + vma->vm_flags |= set;
> > + vma->vm_flags &= ~clear;
> > +}
> > +
> >  static inline void mod_vm_flags(struct vm_area_struct *vma,
> >   unsigned long set, unsigned long clear)
> >  {
> >   mmap_assert_write_locked(vma->vm_mm);
> > - vma->vm_flags |= set;
> > - vma->vm_flags &= ~clear;
> > + mod_vm_flags_nolock(vma, set, clear);
> >  }
> >
> >  static inline void vma_set_anonymous(struct vm_area_struct *vma)
> > @@ -2087,7 +2093,7 @@ static inline void zap_vma_pages(struct 
> > vm_area_struct *vma)
> >  }
> >  void unmap_vmas(struct mmu_gather *tlb, struct maple_tree *mt,
> >   struct vm_area_struct *start_vma, unsigned long start,
> > - unsigned long end);
> > + unsigned long end, bool mm_wr_locked);
> >
> >  struct mmu_notifier_range;
> >
> > diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> > index 5fd45454c073..c63cd44777ec 100644
> > --- a/include/linux/pgtable.h
> > +++ b/include/linux/pgtable.h
> > @@ -1185,7 +1185,8 @@ static inline int track_pfn_copy(struct 
> > vm_area_struct *vma)
> >   * can be for the entire vma (in which case pfn, size are zero).
> >   */
> >  static inline void untrack_pfn(struct vm_area_struct *vma,
> > -unsigned long pfn, unsigned long size)
> > +unsigned long pfn, unsigned long size,
> > +bool mm_wr_locked)
> >  {
> >  }
> >
> > @@ -1203,7 +1204,7 @@ extern void track_pfn_insert(struct vm_area_struct 
> > *vma, pgprot_t *prot,
> >pfn_t pfn);
> >  extern int track_pfn_copy(struct vm_area_struct *vma);
> >  extern void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
> > - unsigned long size);
> > + unsigned long size, bool mm_wr_locked);
> >  extern void untrack_pfn_moved(struct vm_area_struct *vma);
> >  #endif
> >
> > diff --git a/mm/memory.c b/mm/memory.c
> > index d6902065e558..5b11b50e2c4a 100644
> > --- a/mm/memory.c
> > +++ b/mm/memory.c
> > @@ -1613,7 +1613,7 @@ void unmap_page_range(struct mmu_gather *tlb,
> >  static void unmap_single_vma(struct mmu_gather *tlb,
> >   struct vm_area_struct *vma, unsigned long start_addr,
> >   unsigned long 

Re: [PATCH v2 1/6] mm: introduce vma->vm_flags modifier functions

2023-01-25 Thread Suren Baghdasaryan
On Wed, Jan 25, 2023 at 10:37 AM Matthew Wilcox  wrote:
>
> On Wed, Jan 25, 2023 at 08:49:50AM -0800, Suren Baghdasaryan wrote:
> > On Wed, Jan 25, 2023 at 1:10 AM Peter Zijlstra  wrote:
> > > > + /*
> > > > +  * Flags, see mm.h.
> > > > +  * WARNING! Do not modify directly.
> > > > +  * Use {init|reset|set|clear|mod}_vm_flags() functions instead.
> > > > +  */
> > > > + unsigned long vm_flags;
> > >
> > > We have __private and ACCESS_PRIVATE() to help with enforcing this.
> >
> > Thanks for pointing this out, Peter! I guess for that I'll need to
> > convert all read accesses and provide get_vm_flags() too? That will
> > cause some additional churt (a quick search shows 801 hits over 248
> > files) but maybe it's worth it? I think Michal suggested that too in
> > another patch. Should I do that while we are at it?
>
> Here's a trick I saw somewhere in the VFS:
>
> union {
> const vm_flags_t vm_flags;
> vm_flags_t __private __vm_flags;
> };
>
> Now it can be read by anybody but written only by those using
> ACCESS_PRIVATE.

Huh, this is quite nice! I think it does not save us from the cases
when vma->vm_flags is passed by a reference and modified indirectly,
like in ksm_madvise()? Though maybe such usecases are so rare (I found
only 2 cases) that we can ignore this?


[PATCH v2 2/6] mm: replace VM_LOCKED_CLEAR_MASK with VM_LOCKED_MASK

2023-01-25 Thread Suren Baghdasaryan
To simplify the usage of VM_LOCKED_CLEAR_MASK in clear_vm_flags(),
replace it with VM_LOCKED_MASK bitmask and convert all users.

Signed-off-by: Suren Baghdasaryan 
---
 include/linux/mm.h | 4 ++--
 kernel/fork.c  | 2 +-
 mm/hugetlb.c   | 4 ++--
 mm/mlock.c | 6 +++---
 mm/mmap.c  | 6 +++---
 mm/mremap.c| 2 +-
 6 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index b71f2809caac..da62bdd627bf 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -421,8 +421,8 @@ extern unsigned int kobjsize(const void *objp);
 /* This mask defines which mm->def_flags a process can inherit its parent */
 #define VM_INIT_DEF_MASK   VM_NOHUGEPAGE
 
-/* This mask is used to clear all the VMA flags used by mlock */
-#define VM_LOCKED_CLEAR_MASK   (~(VM_LOCKED | VM_LOCKONFAULT))
+/* This mask represents all the VMA flag bits used by mlock */
+#define VM_LOCKED_MASK (VM_LOCKED | VM_LOCKONFAULT)
 
 /* Arch-specific flags to clear when updating VM flags on protection change */
 #ifndef VM_ARCH_CLEAR
diff --git a/kernel/fork.c b/kernel/fork.c
index 6683c1b0f460..03d472051236 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -669,7 +669,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
tmp->anon_vma = NULL;
} else if (anon_vma_fork(tmp, mpnt))
goto fail_nomem_anon_vma_fork;
-   tmp->vm_flags &= ~(VM_LOCKED | VM_LOCKONFAULT);
+   clear_vm_flags(tmp, VM_LOCKED_MASK);
file = tmp->vm_file;
if (file) {
struct address_space *mapping = file->f_mapping;
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index d20c8b09890e..4ecdbad9a451 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -6973,8 +6973,8 @@ static unsigned long page_table_shareable(struct 
vm_area_struct *svma,
unsigned long s_end = sbase + PUD_SIZE;
 
/* Allow segments to share if only one is marked locked */
-   unsigned long vm_flags = vma->vm_flags & VM_LOCKED_CLEAR_MASK;
-   unsigned long svm_flags = svma->vm_flags & VM_LOCKED_CLEAR_MASK;
+   unsigned long vm_flags = vma->vm_flags & ~VM_LOCKED_MASK;
+   unsigned long svm_flags = svma->vm_flags & ~VM_LOCKED_MASK;
 
/*
 * match the virtual addresses, permission and the alignment of the
diff --git a/mm/mlock.c b/mm/mlock.c
index 0336f52e03d7..5c4fff93cd6b 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -497,7 +497,7 @@ static int apply_vma_lock_flags(unsigned long start, size_t 
len,
if (vma->vm_start != tmp)
return -ENOMEM;
 
-   newflags = vma->vm_flags & VM_LOCKED_CLEAR_MASK;
+   newflags = vma->vm_flags & ~VM_LOCKED_MASK;
newflags |= flags;
/* Here we know that  vma->vm_start <= nstart < vma->vm_end. */
tmp = vma->vm_end;
@@ -661,7 +661,7 @@ static int apply_mlockall_flags(int flags)
struct vm_area_struct *vma, *prev = NULL;
vm_flags_t to_add = 0;
 
-   current->mm->def_flags &= VM_LOCKED_CLEAR_MASK;
+   current->mm->def_flags &= ~VM_LOCKED_MASK;
if (flags & MCL_FUTURE) {
current->mm->def_flags |= VM_LOCKED;
 
@@ -681,7 +681,7 @@ static int apply_mlockall_flags(int flags)
for_each_vma(vmi, vma) {
vm_flags_t newflags;
 
-   newflags = vma->vm_flags & VM_LOCKED_CLEAR_MASK;
+   newflags = vma->vm_flags & ~VM_LOCKED_MASK;
newflags |= to_add;
 
/* Ignore errors */
diff --git a/mm/mmap.c b/mm/mmap.c
index d4abc6feced1..323bd253b25a 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2671,7 +2671,7 @@ unsigned long mmap_region(struct file *file, unsigned 
long addr,
if ((vm_flags & VM_SPECIAL) || vma_is_dax(vma) ||
is_vm_hugetlb_page(vma) ||
vma == get_gate_vma(current->mm))
-   vma->vm_flags &= VM_LOCKED_CLEAR_MASK;
+   clear_vm_flags(vma, VM_LOCKED_MASK);
else
mm->locked_vm += (len >> PAGE_SHIFT);
}
@@ -3340,8 +3340,8 @@ static struct vm_area_struct *__install_special_mapping(
vma->vm_start = addr;
vma->vm_end = addr + len;
 
-   vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND | VM_SOFTDIRTY;
-   vma->vm_flags &= VM_LOCKED_CLEAR_MASK;
+   init_vm_flags(vma, (vm_flags | mm->def_flags |
+ VM_DONTEXPAND | VM_SOFTDIRTY) & ~VM_LOCKED_MASK);
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
 
vma->vm_ops = ops;
diff --git a/mm/mremap.c b/mm/mremap.c
index 1b3ee02bead7..35db9752cb6a 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -687,7 +687,7 @@ static unsigned long move_vma(struct vm_area_struct *vma,
 
if (unlikely(!err && (flags & MREMAP_DONTUNMAP))) {
  

Re: [PATCH v2 3/6] mm: replace vma->vm_flags direct modifications with modifier calls

2023-01-25 Thread Suren Baghdasaryan
On Wed, Jan 25, 2023 at 1:30 AM 'Michal Hocko' via kernel-team
 wrote:
>
> On Wed 25-01-23 00:38:48, Suren Baghdasaryan wrote:
> > Replace direct modifications to vma->vm_flags with calls to modifier
> > functions to be able to track flag changes and to keep vma locking
> > correctness.
>
> Is this a manual (git grep) based work or have you used Coccinele for
> the patch generation?

It was a manual "search and replace" and in the process I temporarily
renamed vm_flags to ensure I did not miss any usage.

>
> My potentially incomplete check
> $ git grep ">[[:space:]]*vm_flags[[:space:]]*[&|^]="
>
> shows that nothing should be left after this. There is still quite a lot
> of direct checks of the flags (more than 600). Maybe it would be good to
> make flags accessible only via accessors which would also prevent any
> future direct setting of those flags in uncontrolled way as well.

Yes, I think Peter's suggestion in the first patch would also require
that. Much more churn but probably worth it for the future
maintenance. I'll add a patch which converts all readers as well.

>
> Anyway
> Acked-by: Michal Hocko 

Thanks for all the reviews!

> --
> Michal Hocko
> SUSE Labs
>
> --
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to kernel-team+unsubscr...@android.com.
>


Re: [PATCH v2 1/6] mm: introduce vma->vm_flags modifier functions

2023-01-25 Thread Suren Baghdasaryan
On Wed, Jan 25, 2023 at 10:33 AM Matthew Wilcox  wrote:
>
> On Wed, Jan 25, 2023 at 12:38:46AM -0800, Suren Baghdasaryan wrote:
> > +/* Use when VMA is not part of the VMA tree and needs no locking */
> > +static inline void init_vm_flags(struct vm_area_struct *vma,
> > +  unsigned long flags)
> > +{
> > + vma->vm_flags = flags;
>
> vm_flags are supposed to have type vm_flags_t.  That's not been
> fully realised yet, but perhaps we could avoid making it worse?
>
> >   pgprot_t vm_page_prot;
> > - unsigned long vm_flags; /* Flags, see mm.h. */
> > +
> > + /*
> > +  * Flags, see mm.h.
> > +  * WARNING! Do not modify directly.
> > +  * Use {init|reset|set|clear|mod}_vm_flags() functions instead.
> > +  */
> > + unsigned long vm_flags;
>
> Including changing this line to vm_flags_t

Good point. Will make the change. Thanks!


[PATCH v2 1/6] mm: introduce vma->vm_flags modifier functions

2023-01-25 Thread Suren Baghdasaryan
vm_flags are among VMA attributes which affect decisions like VMA merging
and splitting. Therefore all vm_flags modifications are performed after
taking exclusive mmap_lock to prevent vm_flags updates racing with such
operations. Introduce modifier functions for vm_flags to be used whenever
flags are updated. This way we can better check and control correct
locking behavior during these updates.

Signed-off-by: Suren Baghdasaryan 
---
 include/linux/mm.h   | 37 +
 include/linux/mm_types.h |  8 +++-
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index c2f62bdce134..b71f2809caac 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -627,6 +627,43 @@ static inline void vma_init(struct vm_area_struct *vma, 
struct mm_struct *mm)
INIT_LIST_HEAD(>anon_vma_chain);
 }
 
+/* Use when VMA is not part of the VMA tree and needs no locking */
+static inline void init_vm_flags(struct vm_area_struct *vma,
+unsigned long flags)
+{
+   vma->vm_flags = flags;
+}
+
+/* Use when VMA is part of the VMA tree and modifications need coordination */
+static inline void reset_vm_flags(struct vm_area_struct *vma,
+ unsigned long flags)
+{
+   mmap_assert_write_locked(vma->vm_mm);
+   init_vm_flags(vma, flags);
+}
+
+static inline void set_vm_flags(struct vm_area_struct *vma,
+   unsigned long flags)
+{
+   mmap_assert_write_locked(vma->vm_mm);
+   vma->vm_flags |= flags;
+}
+
+static inline void clear_vm_flags(struct vm_area_struct *vma,
+ unsigned long flags)
+{
+   mmap_assert_write_locked(vma->vm_mm);
+   vma->vm_flags &= ~flags;
+}
+
+static inline void mod_vm_flags(struct vm_area_struct *vma,
+   unsigned long set, unsigned long clear)
+{
+   mmap_assert_write_locked(vma->vm_mm);
+   vma->vm_flags |= set;
+   vma->vm_flags &= ~clear;
+}
+
 static inline void vma_set_anonymous(struct vm_area_struct *vma)
 {
vma->vm_ops = NULL;
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 2d6d790d9bed..6c7c70bf50dd 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -491,7 +491,13 @@ struct vm_area_struct {
 * See vmf_insert_mixed_prot() for discussion.
 */
pgprot_t vm_page_prot;
-   unsigned long vm_flags; /* Flags, see mm.h. */
+
+   /*
+* Flags, see mm.h.
+* WARNING! Do not modify directly.
+* Use {init|reset|set|clear|mod}_vm_flags() functions instead.
+*/
+   unsigned long vm_flags;
 
/*
 * For areas with an address space and backing store,
-- 
2.39.1



Re: [PATCH v2 1/6] mm: introduce vma->vm_flags modifier functions

2023-01-25 Thread Suren Baghdasaryan
On Wed, Jan 25, 2023 at 1:10 AM Peter Zijlstra  wrote:
>
> On Wed, Jan 25, 2023 at 12:38:46AM -0800, Suren Baghdasaryan wrote:
>
> > diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> > index 2d6d790d9bed..6c7c70bf50dd 100644
> > --- a/include/linux/mm_types.h
> > +++ b/include/linux/mm_types.h
> > @@ -491,7 +491,13 @@ struct vm_area_struct {
> >* See vmf_insert_mixed_prot() for discussion.
> >*/
> >   pgprot_t vm_page_prot;
> > - unsigned long vm_flags; /* Flags, see mm.h. */
> > +
> > + /*
> > +  * Flags, see mm.h.
> > +  * WARNING! Do not modify directly.
> > +  * Use {init|reset|set|clear|mod}_vm_flags() functions instead.
> > +  */
> > + unsigned long vm_flags;
>
> We have __private and ACCESS_PRIVATE() to help with enforcing this.

Thanks for pointing this out, Peter! I guess for that I'll need to
convert all read accesses and provide get_vm_flags() too? That will
cause some additional churt (a quick search shows 801 hits over 248
files) but maybe it's worth it? I think Michal suggested that too in
another patch. Should I do that while we are at it?

>


Re: [PATCH v2 1/6] mm: introduce vma->vm_flags modifier functions

2023-01-25 Thread Matthew Wilcox
On Wed, Jan 25, 2023 at 08:49:50AM -0800, Suren Baghdasaryan wrote:
> On Wed, Jan 25, 2023 at 1:10 AM Peter Zijlstra  wrote:
> > > + /*
> > > +  * Flags, see mm.h.
> > > +  * WARNING! Do not modify directly.
> > > +  * Use {init|reset|set|clear|mod}_vm_flags() functions instead.
> > > +  */
> > > + unsigned long vm_flags;
> >
> > We have __private and ACCESS_PRIVATE() to help with enforcing this.
> 
> Thanks for pointing this out, Peter! I guess for that I'll need to
> convert all read accesses and provide get_vm_flags() too? That will
> cause some additional churt (a quick search shows 801 hits over 248
> files) but maybe it's worth it? I think Michal suggested that too in
> another patch. Should I do that while we are at it?

Here's a trick I saw somewhere in the VFS:

union {
const vm_flags_t vm_flags;
vm_flags_t __private __vm_flags;
};

Now it can be read by anybody but written only by those using
ACCESS_PRIVATE.


Re: [PATCH 10/15] serial: ambarella: add support for Ambarella uart_port

2023-01-25 Thread Li Chen
On Mon, 23 Jan 2023 17:51:25 +0800,

Hi Greg,

Sorry for my late reply.

Greg Kroah-Hartman wrote:
> 
> On Mon, Jan 23, 2023 at 03:32:25PM +0800, Li Chen wrote:
> > This driver add support for Ambarella's uart, which
> > can be used for console and etc.
> > 
> > Signed-off-by: Li Chen 
> > Change-Id: Ie68af7ad2187e21853e58d52cd97fd7145303730
> > ---
> >  MAINTAINERS |1 +
> >  drivers/tty/serial/Kconfig  |   16 +
> >  drivers/tty/serial/Makefile |1 +
> >  drivers/tty/serial/ambarella_uart.c | 1581 +++
> >  drivers/tty/serial/ambarella_uart.h |  120 ++
> 
> Why do you need a .h file for a single .c file?  They should all be in
> one file please.

Ok, I will combine them into single source file.

> Also, no change-id, you know this...
> 
> thanks,
> 
> greg k-h

Regards,
Li


Re: [PATCH v2 1/6] mm: introduce vma->vm_flags modifier functions

2023-01-25 Thread Michal Hocko
On Wed 25-01-23 00:38:46, Suren Baghdasaryan wrote:
> vm_flags are among VMA attributes which affect decisions like VMA merging
> and splitting. Therefore all vm_flags modifications are performed after
> taking exclusive mmap_lock to prevent vm_flags updates racing with such
> operations. Introduce modifier functions for vm_flags to be used whenever
> flags are updated. This way we can better check and control correct
> locking behavior during these updates.
> 
> Signed-off-by: Suren Baghdasaryan 

Acked-by: Michal Hocko 

> ---
>  include/linux/mm.h   | 37 +
>  include/linux/mm_types.h |  8 +++-
>  2 files changed, 44 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index c2f62bdce134..b71f2809caac 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -627,6 +627,43 @@ static inline void vma_init(struct vm_area_struct *vma, 
> struct mm_struct *mm)
>   INIT_LIST_HEAD(>anon_vma_chain);
>  }
>  
> +/* Use when VMA is not part of the VMA tree and needs no locking */
> +static inline void init_vm_flags(struct vm_area_struct *vma,
> +  unsigned long flags)
> +{
> + vma->vm_flags = flags;
> +}
> +
> +/* Use when VMA is part of the VMA tree and modifications need coordination 
> */
> +static inline void reset_vm_flags(struct vm_area_struct *vma,
> +   unsigned long flags)
> +{
> + mmap_assert_write_locked(vma->vm_mm);
> + init_vm_flags(vma, flags);
> +}
> +
> +static inline void set_vm_flags(struct vm_area_struct *vma,
> + unsigned long flags)
> +{
> + mmap_assert_write_locked(vma->vm_mm);
> + vma->vm_flags |= flags;
> +}
> +
> +static inline void clear_vm_flags(struct vm_area_struct *vma,
> +   unsigned long flags)
> +{
> + mmap_assert_write_locked(vma->vm_mm);
> + vma->vm_flags &= ~flags;
> +}
> +
> +static inline void mod_vm_flags(struct vm_area_struct *vma,
> + unsigned long set, unsigned long clear)
> +{
> + mmap_assert_write_locked(vma->vm_mm);
> + vma->vm_flags |= set;
> + vma->vm_flags &= ~clear;
> +}
> +
>  static inline void vma_set_anonymous(struct vm_area_struct *vma)
>  {
>   vma->vm_ops = NULL;
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 2d6d790d9bed..6c7c70bf50dd 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -491,7 +491,13 @@ struct vm_area_struct {
>* See vmf_insert_mixed_prot() for discussion.
>*/
>   pgprot_t vm_page_prot;
> - unsigned long vm_flags; /* Flags, see mm.h. */
> +
> + /*
> +  * Flags, see mm.h.
> +  * WARNING! Do not modify directly.
> +  * Use {init|reset|set|clear|mod}_vm_flags() functions instead.
> +  */
> + unsigned long vm_flags;
>  
>   /*
>* For areas with an address space and backing store,
> -- 
> 2.39.1

-- 
Michal Hocko
SUSE Labs


Re: [PATCH v2 3/6] mm: replace vma->vm_flags direct modifications with modifier calls

2023-01-25 Thread Michal Hocko
On Wed 25-01-23 00:38:48, Suren Baghdasaryan wrote:
> Replace direct modifications to vma->vm_flags with calls to modifier
> functions to be able to track flag changes and to keep vma locking
> correctness.

Is this a manual (git grep) based work or have you used Coccinele for
the patch generation?

My potentially incomplete check
$ git grep ">[[:space:]]*vm_flags[[:space:]]*[&|^]="

shows that nothing should be left after this. There is still quite a lot
of direct checks of the flags (more than 600). Maybe it would be good to
make flags accessible only via accessors which would also prevent any
future direct setting of those flags in uncontrolled way as well.

Anyway
Acked-by: Michal Hocko 
-- 
Michal Hocko
SUSE Labs


Re: [PATCH v2 5/6] mm: introduce mod_vm_flags_nolock and use it in untrack_pfn

2023-01-25 Thread Michal Hocko
On Wed 25-01-23 00:38:50, Suren Baghdasaryan wrote:
> In cases when VMA flags are modified after VMA was isolated and mmap_lock
> was downgraded, flags modifications would result in an assertion because
> mmap write lock is not held.
> Introduce mod_vm_flags_nolock to be used in such situation.
> Pass a hint to untrack_pfn to conditionally use mod_vm_flags_nolock for
> flags modification and to avoid assertion.

The changelog nor the documentation of mod_vm_flags_nolock 
really explain when it is safe to use it. This is really important for
future potential users.

> Signed-off-by: Suren Baghdasaryan 
> ---
>  arch/x86/mm/pat/memtype.c | 10 +++---
>  include/linux/mm.h| 12 +---
>  include/linux/pgtable.h   |  5 +++--
>  mm/memory.c   | 13 +++--
>  mm/memremap.c |  4 ++--
>  mm/mmap.c | 16 ++--
>  6 files changed, 38 insertions(+), 22 deletions(-)
> 
> diff --git a/arch/x86/mm/pat/memtype.c b/arch/x86/mm/pat/memtype.c
> index ae9645c900fa..d8adc0b42cf2 100644
> --- a/arch/x86/mm/pat/memtype.c
> +++ b/arch/x86/mm/pat/memtype.c
> @@ -1046,7 +1046,7 @@ void track_pfn_insert(struct vm_area_struct *vma, 
> pgprot_t *prot, pfn_t pfn)
>   * can be for the entire vma (in which case pfn, size are zero).
>   */
>  void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
> -  unsigned long size)
> +  unsigned long size, bool mm_wr_locked)
>  {
>   resource_size_t paddr;
>   unsigned long prot;
> @@ -1065,8 +1065,12 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned 
> long pfn,
>   size = vma->vm_end - vma->vm_start;
>   }
>   free_pfn_range(paddr, size);
> - if (vma)
> - clear_vm_flags(vma, VM_PAT);
> + if (vma) {
> + if (mm_wr_locked)
> + clear_vm_flags(vma, VM_PAT);
> + else
> + mod_vm_flags_nolock(vma, 0, VM_PAT);
> + }
>  }
>  
>  /*
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 55335edd1373..48d49930c411 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -656,12 +656,18 @@ static inline void clear_vm_flags(struct vm_area_struct 
> *vma,
>   vma->vm_flags &= ~flags;
>  }
>  
> +static inline void mod_vm_flags_nolock(struct vm_area_struct *vma,
> +unsigned long set, unsigned long clear)
> +{
> + vma->vm_flags |= set;
> + vma->vm_flags &= ~clear;
> +}
> +
>  static inline void mod_vm_flags(struct vm_area_struct *vma,
>   unsigned long set, unsigned long clear)
>  {
>   mmap_assert_write_locked(vma->vm_mm);
> - vma->vm_flags |= set;
> - vma->vm_flags &= ~clear;
> + mod_vm_flags_nolock(vma, set, clear);
>  }
>  
>  static inline void vma_set_anonymous(struct vm_area_struct *vma)
> @@ -2087,7 +2093,7 @@ static inline void zap_vma_pages(struct vm_area_struct 
> *vma)
>  }
>  void unmap_vmas(struct mmu_gather *tlb, struct maple_tree *mt,
>   struct vm_area_struct *start_vma, unsigned long start,
> - unsigned long end);
> + unsigned long end, bool mm_wr_locked);
>  
>  struct mmu_notifier_range;
>  
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index 5fd45454c073..c63cd44777ec 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -1185,7 +1185,8 @@ static inline int track_pfn_copy(struct vm_area_struct 
> *vma)
>   * can be for the entire vma (in which case pfn, size are zero).
>   */
>  static inline void untrack_pfn(struct vm_area_struct *vma,
> -unsigned long pfn, unsigned long size)
> +unsigned long pfn, unsigned long size,
> +bool mm_wr_locked)
>  {
>  }
>  
> @@ -1203,7 +1204,7 @@ extern void track_pfn_insert(struct vm_area_struct 
> *vma, pgprot_t *prot,
>pfn_t pfn);
>  extern int track_pfn_copy(struct vm_area_struct *vma);
>  extern void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
> - unsigned long size);
> + unsigned long size, bool mm_wr_locked);
>  extern void untrack_pfn_moved(struct vm_area_struct *vma);
>  #endif
>  
> diff --git a/mm/memory.c b/mm/memory.c
> index d6902065e558..5b11b50e2c4a 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -1613,7 +1613,7 @@ void unmap_page_range(struct mmu_gather *tlb,
>  static void unmap_single_vma(struct mmu_gather *tlb,
>   struct vm_area_struct *vma, unsigned long start_addr,
>   unsigned long end_addr,
> - struct zap_details *details)
> + struct zap_details *details, bool mm_wr_locked)
>  {
>   unsigned long start = max(vma->vm_start, start_addr);
>   unsigned long end;
> @@ -1628,7 +1628,7 @@ static void unmap_single_vma(struct mmu_gather *tlb,
>   uprobe_munmap(vma, start, end);
>  
>   if 

[PATCH 3/4] DRM: BRIDGE: TFP410: Fix logic to configured polled HPD

2023-01-25 Thread Jonathan Cormier
From: Michael Williamson 

The logic to configure polling (vs async/irq notification) of hot-plug
events was not correct.  If the connected bridge requires polling,
then inform the upstream bridge we also require polling.

Signed-off-by: Michael Williamson 
Signed-off-by: Jonathan Cormier 
---
 drivers/gpu/drm/bridge/ti-tfp410.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c 
b/drivers/gpu/drm/bridge/ti-tfp410.c
index 323a6d9ed188..837e1f81a0ff 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -155,7 +155,7 @@ static int tfp410_attach(struct drm_bridge *bridge,
return -ENODEV;
}
 
-   if (dvi->next_bridge->ops & DRM_BRIDGE_OP_DETECT)
+   if (dvi->next_bridge->ops & DRM_BRIDGE_OP_HPD)
dvi->connector.polled = DRM_CONNECTOR_POLL_HPD;
else
dvi->connector.polled = DRM_CONNECTOR_POLL_CONNECT | 
DRM_CONNECTOR_POLL_DISCONNECT;

-- 
2.25.1


[PATCH v2 5/6] mm: introduce mod_vm_flags_nolock and use it in untrack_pfn

2023-01-25 Thread Suren Baghdasaryan
In cases when VMA flags are modified after VMA was isolated and mmap_lock
was downgraded, flags modifications would result in an assertion because
mmap write lock is not held.
Introduce mod_vm_flags_nolock to be used in such situation.
Pass a hint to untrack_pfn to conditionally use mod_vm_flags_nolock for
flags modification and to avoid assertion.

Signed-off-by: Suren Baghdasaryan 
---
 arch/x86/mm/pat/memtype.c | 10 +++---
 include/linux/mm.h| 12 +---
 include/linux/pgtable.h   |  5 +++--
 mm/memory.c   | 13 +++--
 mm/memremap.c |  4 ++--
 mm/mmap.c | 16 ++--
 6 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/arch/x86/mm/pat/memtype.c b/arch/x86/mm/pat/memtype.c
index ae9645c900fa..d8adc0b42cf2 100644
--- a/arch/x86/mm/pat/memtype.c
+++ b/arch/x86/mm/pat/memtype.c
@@ -1046,7 +1046,7 @@ void track_pfn_insert(struct vm_area_struct *vma, 
pgprot_t *prot, pfn_t pfn)
  * can be for the entire vma (in which case pfn, size are zero).
  */
 void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
-unsigned long size)
+unsigned long size, bool mm_wr_locked)
 {
resource_size_t paddr;
unsigned long prot;
@@ -1065,8 +1065,12 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned 
long pfn,
size = vma->vm_end - vma->vm_start;
}
free_pfn_range(paddr, size);
-   if (vma)
-   clear_vm_flags(vma, VM_PAT);
+   if (vma) {
+   if (mm_wr_locked)
+   clear_vm_flags(vma, VM_PAT);
+   else
+   mod_vm_flags_nolock(vma, 0, VM_PAT);
+   }
 }
 
 /*
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 55335edd1373..48d49930c411 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -656,12 +656,18 @@ static inline void clear_vm_flags(struct vm_area_struct 
*vma,
vma->vm_flags &= ~flags;
 }
 
+static inline void mod_vm_flags_nolock(struct vm_area_struct *vma,
+  unsigned long set, unsigned long clear)
+{
+   vma->vm_flags |= set;
+   vma->vm_flags &= ~clear;
+}
+
 static inline void mod_vm_flags(struct vm_area_struct *vma,
unsigned long set, unsigned long clear)
 {
mmap_assert_write_locked(vma->vm_mm);
-   vma->vm_flags |= set;
-   vma->vm_flags &= ~clear;
+   mod_vm_flags_nolock(vma, set, clear);
 }
 
 static inline void vma_set_anonymous(struct vm_area_struct *vma)
@@ -2087,7 +2093,7 @@ static inline void zap_vma_pages(struct vm_area_struct 
*vma)
 }
 void unmap_vmas(struct mmu_gather *tlb, struct maple_tree *mt,
struct vm_area_struct *start_vma, unsigned long start,
-   unsigned long end);
+   unsigned long end, bool mm_wr_locked);
 
 struct mmu_notifier_range;
 
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 5fd45454c073..c63cd44777ec 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -1185,7 +1185,8 @@ static inline int track_pfn_copy(struct vm_area_struct 
*vma)
  * can be for the entire vma (in which case pfn, size are zero).
  */
 static inline void untrack_pfn(struct vm_area_struct *vma,
-  unsigned long pfn, unsigned long size)
+  unsigned long pfn, unsigned long size,
+  bool mm_wr_locked)
 {
 }
 
@@ -1203,7 +1204,7 @@ extern void track_pfn_insert(struct vm_area_struct *vma, 
pgprot_t *prot,
 pfn_t pfn);
 extern int track_pfn_copy(struct vm_area_struct *vma);
 extern void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
-   unsigned long size);
+   unsigned long size, bool mm_wr_locked);
 extern void untrack_pfn_moved(struct vm_area_struct *vma);
 #endif
 
diff --git a/mm/memory.c b/mm/memory.c
index d6902065e558..5b11b50e2c4a 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1613,7 +1613,7 @@ void unmap_page_range(struct mmu_gather *tlb,
 static void unmap_single_vma(struct mmu_gather *tlb,
struct vm_area_struct *vma, unsigned long start_addr,
unsigned long end_addr,
-   struct zap_details *details)
+   struct zap_details *details, bool mm_wr_locked)
 {
unsigned long start = max(vma->vm_start, start_addr);
unsigned long end;
@@ -1628,7 +1628,7 @@ static void unmap_single_vma(struct mmu_gather *tlb,
uprobe_munmap(vma, start, end);
 
if (unlikely(vma->vm_flags & VM_PFNMAP))
-   untrack_pfn(vma, 0, 0);
+   untrack_pfn(vma, 0, 0, mm_wr_locked);
 
if (start != end) {
if (unlikely(is_vm_hugetlb_page(vma))) {
@@ -1675,7 +1675,7 @@ static void unmap_single_vma(struct mmu_gather *tlb,
  */
 void unmap_vmas(struct mmu_gather *tlb, struct maple_tree *mt,

Re: [PATCH v2 4/6] mm: replace vma->vm_flags indirect modification in ksm_madvise

2023-01-25 Thread Suren Baghdasaryan
On Wed, Jan 25, 2023 at 9:08 AM Michal Hocko  wrote:
>
> On Wed 25-01-23 08:57:48, Suren Baghdasaryan wrote:
> > On Wed, Jan 25, 2023 at 1:38 AM 'Michal Hocko' via kernel-team
> >  wrote:
> > >
> > > On Wed 25-01-23 00:38:49, Suren Baghdasaryan wrote:
> > > > Replace indirect modifications to vma->vm_flags with calls to modifier
> > > > functions to be able to track flag changes and to keep vma locking
> > > > correctness. Add a BUG_ON check in ksm_madvise() to catch indirect
> > > > vm_flags modification attempts.
> > >
> > > Those BUG_ONs scream to much IMHO. KSM is an MM internal code so I
> > > gueess we should be willing to trust it.
> >
> > Yes, but I really want to prevent an indirect misuse since it was not
> > easy to find these. If you feel strongly about it I will remove them
> > or if you have a better suggestion I'm all for it.
>
> You can avoid that by making flags inaccesible directly, right?

Ah, you mean Peter's suggestion of using __private? I guess that would
cover it. I'll drop these BUG_ONs in the next version. Thanks!

>
> --
> Michal Hocko
> SUSE Labs


Re: [PATCH v2 4/6] mm: replace vma->vm_flags indirect modification in ksm_madvise

2023-01-25 Thread Suren Baghdasaryan
On Wed, Jan 25, 2023 at 1:38 AM 'Michal Hocko' via kernel-team
 wrote:
>
> On Wed 25-01-23 00:38:49, Suren Baghdasaryan wrote:
> > Replace indirect modifications to vma->vm_flags with calls to modifier
> > functions to be able to track flag changes and to keep vma locking
> > correctness. Add a BUG_ON check in ksm_madvise() to catch indirect
> > vm_flags modification attempts.
>
> Those BUG_ONs scream to much IMHO. KSM is an MM internal code so I
> gueess we should be willing to trust it.

Yes, but I really want to prevent an indirect misuse since it was not
easy to find these. If you feel strongly about it I will remove them
or if you have a better suggestion I'm all for it.

>
> > Signed-off-by: Suren Baghdasaryan 
>
> Acked-by: Michal Hocko 
> --
> Michal Hocko
> SUSE Labs
>
> --
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to kernel-team+unsubscr...@android.com.
>


Re: [PATCH v2 4/6] mm: replace vma->vm_flags indirect modification in ksm_madvise

2023-01-25 Thread Michal Hocko
On Wed 25-01-23 08:57:48, Suren Baghdasaryan wrote:
> On Wed, Jan 25, 2023 at 1:38 AM 'Michal Hocko' via kernel-team
>  wrote:
> >
> > On Wed 25-01-23 00:38:49, Suren Baghdasaryan wrote:
> > > Replace indirect modifications to vma->vm_flags with calls to modifier
> > > functions to be able to track flag changes and to keep vma locking
> > > correctness. Add a BUG_ON check in ksm_madvise() to catch indirect
> > > vm_flags modification attempts.
> >
> > Those BUG_ONs scream to much IMHO. KSM is an MM internal code so I
> > gueess we should be willing to trust it.
> 
> Yes, but I really want to prevent an indirect misuse since it was not
> easy to find these. If you feel strongly about it I will remove them
> or if you have a better suggestion I'm all for it.

You can avoid that by making flags inaccesible directly, right?

-- 
Michal Hocko
SUSE Labs


Re: [PATCH v3 04/10] drm/fbdev-generic: Initialize fb-helper structure in generic setup

2023-01-25 Thread Sam Ravnborg
Hi Thomas,

On Wed, Jan 25, 2023 at 09:04:09PM +0100, Thomas Zimmermann wrote:
> Initialize the fb-helper structure immediately after its allocation
> in drm_fbdev_generic_setup(). That will make it easier to fill it with
> driver-specific values, such as the preferred BPP.
> 
> Signed-off-by: Thomas Zimmermann 
> Reviewed-by: Javier Martinez Canillas 
> ---
>  drivers/gpu/drm/drm_fbdev_generic.c | 13 +
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_fbdev_generic.c 
> b/drivers/gpu/drm/drm_fbdev_generic.c
> index 135d58b8007b..63f66325a8a5 100644
> --- a/drivers/gpu/drm/drm_fbdev_generic.c
> +++ b/drivers/gpu/drm/drm_fbdev_generic.c
> @@ -385,8 +385,6 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev 
> *client)
>   if (dev->fb_helper)
>   return drm_fb_helper_hotplug_event(dev->fb_helper);
>  
> - drm_fb_helper_prepare(dev, fb_helper, _fb_helper_generic_funcs);
> -
>   ret = drm_fb_helper_init(dev, fb_helper);
>   if (ret)
>   goto err;

>From the documentation:
The drm_fb_helper_prepare()
helper must be called first to initialize the minimum required to make
hotplug detection work.
...
To finish up the fbdev helper initialization, the
drm_fb_helper_init() function is called.

So this change do not follow the documentation as drm_fb_helper_init()
is now called before drm_fb_helper_prepare()

I did not follow all the code - but my gut feeling is that the
documentation is right.

Sam


> @@ -456,12 +454,12 @@ void drm_fbdev_generic_setup(struct drm_device *dev,
>   fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
>   if (!fb_helper)
>   return;
> + drm_fb_helper_prepare(dev, fb_helper, _fb_helper_generic_funcs);
>  
>   ret = drm_client_init(dev, _helper->client, "fbdev", 
> _fbdev_client_funcs);
>   if (ret) {
> - kfree(fb_helper);
>   drm_err(dev, "Failed to register client: %d\n", ret);
> - return;
> + goto err_drm_client_init;
>   }
>  
>   /*
> @@ -484,5 +482,12 @@ void drm_fbdev_generic_setup(struct drm_device *dev,
>   drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);
>  
>   drm_client_register(_helper->client);
> +
> + return;
> +
> +err_drm_client_init:
> + drm_fb_helper_unprepare(fb_helper);
> + kfree(fb_helper);
> + return;
>  }
>  EXPORT_SYMBOL(drm_fbdev_generic_setup);
> -- 
> 2.39.0


Re: [PATCH v3 02/10] drm/client: Add hotplug_failed flag

2023-01-25 Thread Sam Ravnborg
Hi Thomas,

On Wed, Jan 25, 2023 at 09:04:07PM +0100, Thomas Zimmermann wrote:
> Signal failed hotplugging with a flag in struct drm_client_dev. If set,
> the client helpers will not further try to set up the fbdev display.
> 
> This used to be signalled with a combination of cleared pointers in
> struct drm_fb_helper,
I failed to find where we clear the pointers. What do I miss?
(I had assumed we would stop clearing the pointers after this change).

Sam

which prevents us from initializing these pointers
> early after allocation.
> 
> The change also harmonizes behavior among DRM clients. Additional DRM
> clients will now handle failed hotplugging like fbdev does.
> 
> Signed-off-by: Thomas Zimmermann 
> Reviewed-by: Javier Martinez Canillas 
> ---
>  drivers/gpu/drm/drm_client.c| 5 +
>  drivers/gpu/drm/drm_fbdev_generic.c | 4 
>  include/drm/drm_client.h| 8 
>  3 files changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
> index 09ac191c202d..009e7b10455c 100644
> --- a/drivers/gpu/drm/drm_client.c
> +++ b/drivers/gpu/drm/drm_client.c
> @@ -208,8 +208,13 @@ void drm_client_dev_hotplug(struct drm_device *dev)
>   if (!client->funcs || !client->funcs->hotplug)
>   continue;
>  
> + if (client->hotplug_failed)
> + continue;
> +
>   ret = client->funcs->hotplug(client);
>   drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);
> + if (ret)
> + client->hotplug_failed = true;
>   }
>   mutex_unlock(>clientlist_mutex);
>  }
> diff --git a/drivers/gpu/drm/drm_fbdev_generic.c 
> b/drivers/gpu/drm/drm_fbdev_generic.c
> index 3d455a2e3fb5..135d58b8007b 100644
> --- a/drivers/gpu/drm/drm_fbdev_generic.c
> +++ b/drivers/gpu/drm/drm_fbdev_generic.c
> @@ -382,10 +382,6 @@ static int drm_fbdev_client_hotplug(struct 
> drm_client_dev *client)
>   struct drm_device *dev = client->dev;
>   int ret;
>  
> - /* Setup is not retried if it has failed */
> - if (!fb_helper->dev && fb_helper->funcs)
> - return 0;
> -
>   if (dev->fb_helper)
>   return drm_fb_helper_hotplug_event(dev->fb_helper);
>  
> diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h
> index 4fc8018eddda..39482527a775 100644
> --- a/include/drm/drm_client.h
> +++ b/include/drm/drm_client.h
> @@ -106,6 +106,14 @@ struct drm_client_dev {
>* @modesets: CRTC configurations
>*/
>   struct drm_mode_set *modesets;
> +
> + /**
> +  * @hotplug failed:
> +  *
> +  * Set by client hotplug helpers if the hotplugging failed
> +  * before. It is usually not tried again.
> +  */
> + bool hotplug_failed;
>  };
>  
>  int drm_client_init(struct drm_device *dev, struct drm_client_dev *client,
> -- 
> 2.39.0


Re: [PATCH v3 01/10] drm/client: Test for connectors before sending hotplug event

2023-01-25 Thread Sam Ravnborg
Hi Thomas,

On Wed, Jan 25, 2023 at 09:04:06PM +0100, Thomas Zimmermann wrote:
> Test for connectors in the client code and remove a similar test
> from the generic fbdev emulation. Do nothing if the test fails.
> Not having connectors indicates a driver bug.
> 
> Signed-off-by: Thomas Zimmermann 
> Reviewed-by: Javier Martinez Canillas 
> ---
>  drivers/gpu/drm/drm_client.c| 5 +
>  drivers/gpu/drm/drm_fbdev_generic.c | 5 -
>  2 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
> index 262ec64d4397..09ac191c202d 100644
> --- a/drivers/gpu/drm/drm_client.c
> +++ b/drivers/gpu/drm/drm_client.c
> @@ -198,6 +198,11 @@ void drm_client_dev_hotplug(struct drm_device *dev)
>   if (!drm_core_check_feature(dev, DRIVER_MODESET))
>   return;
>  
> + if (!dev->mode_config.num_connector) {
> + drm_dbg_kms(dev, "No connectors found, will not send hotplug 
> events!\n");
> + return;
This deserves a more visible logging - if a driver fails here it would
be good to spot it in the normal kernel log.
drm_info or drm_notice?

The original code had this on the debug level, but when moving the log
level could also be updated.

Sam

> + }
> +
>   mutex_lock(>clientlist_mutex);
>   list_for_each_entry(client, >clientlist, list) {
>   if (!client->funcs || !client->funcs->hotplug)
> diff --git a/drivers/gpu/drm/drm_fbdev_generic.c 
> b/drivers/gpu/drm/drm_fbdev_generic.c
> index 0a4c160e0e58..3d455a2e3fb5 100644
> --- a/drivers/gpu/drm/drm_fbdev_generic.c
> +++ b/drivers/gpu/drm/drm_fbdev_generic.c
> @@ -389,11 +389,6 @@ static int drm_fbdev_client_hotplug(struct 
> drm_client_dev *client)
>   if (dev->fb_helper)
>   return drm_fb_helper_hotplug_event(dev->fb_helper);
>  
> - if (!dev->mode_config.num_connector) {
> - drm_dbg_kms(dev, "No connectors found, will not create 
> framebuffer!\n");
> - return 0;
> - }
> -
>   drm_fb_helper_prepare(dev, fb_helper, _fb_helper_generic_funcs);
>  
>   ret = drm_fb_helper_init(dev, fb_helper);
> -- 
> 2.39.0


[PATCH v3 13/19] dyndbg-API: DYNDBG_CLASSMAP_DEFINE() improvements

2023-01-25 Thread Jim Cromie
patch 1 in this series fixed a CLASSMAP usage error, this improves the
api so that misuse is less likely.

changes here:

0- Add William Swanson's public domain map macro:
   https://github.com/swansontec/map-macro/blob/master/map.h
   this makes 1 possible.

1- classname args to CLASSMAP macros were given as strings: "DRM_UT_CORE".
   Now they are the actual enum const symbols: DRM_UT_CORE.
   Direct use of symbols is tighter, more comprehensible by tools, grep

2- drop _base arg.
   _base was the value of the 1st classname
   that is now available due to 1, no need to require it 2x

So take _base out of the API/kdoc.  Note that the macro impl keeps the
_base arg so that it can be used to set classmap.base, but reuses it
in the MAP-stringify _base, __VA_ARGS__ expression.

Also cleanup the API usage comment in test_dynamic_debug.c, and since
comments in test-code might not be noticed, restate that here.

Using the CLASSMAP api:

  - class-specifications are enum consts/symbols,
like DRM_UT_CORE, DRM_UT_KMS, etc.
their values define bits in the sysfs-node (like drm.debug)

  - they are stringified and accepted at >control
echo class DRM_UT_CORE +p >control

  - multiple class-maps must share the per-module: 0-62 class_id space
(by setting initial enum values to non-overlapping subranges)

todo: fixup the 'i' prefix, a quick/dirty avoidance of MAP.

NOTE: test_dynamic_debug.c also has this helper macro to wire a
classmap to a drm.debug style parameter; its easier to just use it as
a model/template as needed, rather than try to make it general enough
to be an official API helper.

 define DD_SYS_WRAP(_model, _flags) \
static unsigned long bits_##_model; \
static struct ddebug_class_param _flags##_model = { \
.bits = _##_model, \
.flags = #_flags,   \
.map = _##_model,   \
};  \
module_param_cb(_flags##_##_model, _ops_dyndbg_classes, 
&_flags##_model, 0600)

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c   | 22 +++---
 include/drm/drm_print.h   |  1 +
 include/linux/dynamic_debug.h | 17 +--
 include/linux/map.h   | 55 +++
 lib/test_dynamic_debug.c  | 43 +--
 5 files changed, 96 insertions(+), 42 deletions(-)
 create mode 100644 include/linux/map.h

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 4b697e18238d..07c25241e8cc 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -56,17 +56,17 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each 
bit enables a debug cat
 module_param_named(debug, __drm_debug, ulong, 0600);
 #else
 /* classnames must match vals of enum drm_debug_category */
-DYNDBG_CLASSMAP_DEFINE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
-   "DRM_UT_CORE",
-   "DRM_UT_DRIVER",
-   "DRM_UT_KMS",
-   "DRM_UT_PRIME",
-   "DRM_UT_ATOMIC",
-   "DRM_UT_VBL",
-   "DRM_UT_STATE",
-   "DRM_UT_LEASE",
-   "DRM_UT_DP",
-   "DRM_UT_DRMRES");
+DYNDBG_CLASSMAP_DEFINE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS,
+  DRM_UT_CORE,
+  DRM_UT_DRIVER,
+  DRM_UT_KMS,
+  DRM_UT_PRIME,
+  DRM_UT_ATOMIC,
+  DRM_UT_VBL,
+  DRM_UT_STATE,
+  DRM_UT_LEASE,
+  DRM_UT_DP,
+  DRM_UT_DRMRES);
 
 static struct ddebug_class_param drm_debug_bitmap = {
.bits = &__drm_debug,
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index a44fb7ef257f..6a27e8f26770 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -333,6 +333,7 @@ static inline bool drm_debug_enabled_raw(enum 
drm_debug_category category)
})
 
 #if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
+//extern struct ddebug_class_map drm_debug_classes[];
 /*
  * the drm.debug API uses dyndbg, so each drm_*dbg macro/callsite gets
  * a descriptor, and only enabled callsites are reachable.  They use
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 91015d1a04e0..7cdfc4b533ae 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -7,6 +7,7 @@
 #endif
 
 #include 
+#include 
 
 /*
  * An instance of this structure is created in a special
@@ -90,18 +91,16 @@ struct ddebug_class_map {
 };
 
 /**
- * DYNDBG_CLASSMAP_DEFINE - define debug-classes used by a module.
- * @_var:   name of the classmap, 

[PATCH v3 18/19] test-dyndbg: tune sub-module behavior

2023-01-25 Thread Jim Cromie
lib/test_dynamic_debug.c is used to build 2 modules:
test_dynamic_debug.ko and test_dynamic_debug_submod.ko

Define DEBUG only in the main module, not in the submod.  Its purpose
is to insure that prdbgs are enabled by default, so that a modprobe
without params actually logs something, showing that compile-time
enablement works.  This doesn't need to be repeated in the submodule.

Rather, the submodule's purpose is to prove that classmaps defined and
exported from a parent module are propagated to submodules, setting
their class'd debugs accordingly.

Signed-off-by: Jim Cromie 
---
 lib/test_dynamic_debug.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index 6b7bd35c3e15..70a1e8955ad0 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -10,10 +10,9 @@
   #define pr_fmt(fmt) "test_dd_submod: " fmt
 #else
   #define pr_fmt(fmt) "test_dd: " fmt
+  #define DEBUG/* enable all prdbgs (plain & class'd), to log by 
default */
 #endif
 
-#define DEBUG /* enable all prdbgs (plain & class'd) at compiletime */
-
 #include 
 
 /* run tests by reading or writing sysfs node: do_prints */
-- 
2.39.1



[PATCH v3 11/19] dyndbg-API: specialize DYNDBG_CLASSMAP_(DEFINE|USE)

2023-01-25 Thread Jim Cromie
Now that the DECLARE_DYNDBG_CLASSMAP macro has been split into
DYNDBG_CLASSMAP_DEFINE and DYNDBG_CLASSMAP_USE, lets differentiate
them according to their separate jobs.

Dyndbg's existing __dyndbg_classes[] section does:

. catalogs the classmaps defined by the module (or builtin modules)
. authorizes dyndbg to >control those class'd prdbgs for the module.

This patch adds __dyndbg_class_refs[] section:

. catalogs refs/uses of the classmap definitions.
. authorizes dyndbg to >control those class'd prdbgs in ref'g module.
. maps the client module to classmap definitions
  drm-drivers and helpers are clients.
  this allows dyndbg to apply drm.debug to the client module, when added.

The distinction of the 2 roles yields these gains:

It follows the define-once-declare-elsewhere pattern that K gave us,
dumping the weird coordinated-changes-by-identical-classmaps API.

It allows separate handling of class-refs, to find the classed
kernel-params (if any) using this classmap, and propagate their
settings to the class'd prdbgs in the client module.

It fixes the chicken-egg problem that DRM_USE_DYNAMIC_DEBUG=y has; the
new type allows dyndbg to handle class-refs found while adding the
module.

The new DYNDBG_CLASSMAP_* macros add records to the sections:

DYNDBG_CLASSMAP_DEFINE:
  invoked just once per sub-system.
  for drm, its drm_print, where drm.debug is exposed.
  defines the classmap, names "DRM_UT_*", maps to class_id's
  authorizes dyndbg to exert >control
  populates __dyndbg_classes[] "section", __used.
  exports the classmap.

DYNDBG_CLASSMAP_USE:
  invoked by modules using classmaps defined & exported elsewhere
  populates __dyndbg_class_refs[] "section", __used.
  maps client-module name to the extern'd classmap.
  has client-name, so dyndbg can recognize loading client modules.

To support this, a few data changes:

. struct ddebug_class_user
  contains: user-module-name, ref to classmap-defn
  encodes drm-driver's use of a classmap, allowing lookup

struct ddebug_info gets 2 new fields to encapsulate the new section:
  class_refs, num_class_refs.
  set by dynamic_debug_init() for builtins.
  or by kernel/module/main:load_info() for loadable modules.

vmlinux.lds.h: new BOUNDED_SECTION for class-refs, with linker symbols

dynamic_debug.c: changes to:
  setup - in/under ddebug_add_module(), immediately following
  prdbg enables - in/under ddebug_change(), further below

ddebug_attach_module_classes() - largely unchanged:
  called from ddebug_add_module
  finds classmaps whose .mod_name matches module being added.
  attaches them to the module's ddebug_table.
  minor tweaks for code regularity, debug output

ddebug_attach_client_module_classes() - new fn:
. like above, but works class-refs, not classes.
. called from ddebug_add_module, after list-add to ddebug-tables.
  this lets ddebug_change find it to apply the settings
. scans class-refs, for the block "owned" by the module being added.
  for builtins, its N consecutive of many. for loadables, N of N
. calls ddebug_apply_parents_params() for each.

ddebug_apply_parents_params(new fn)

scans module's/builtin kernel-params, calls ddebug_match_attach_kparam
for each to find the params/sysfs-nodes using a classmap.

ddebug_match_apply_kparam(new fn):

1st, it tests the kernel-param.ops is dyndbg's; this guarantees that
the attached arg is a struct ddebug_class_param, which has a ref to
the param's state, and to the classmap.

2nd, it requires that the classmap attached to the kparam is the one
were called for; modules can use many separate classmaps (as
test_dynamic_debug does).

Then apply the "parent" kparam's setting to the client.

The ddebug_change() support:

ddebug_find_valid_class(): This does the search over classmaps,
looking for the class FOO echo'd to >control.  So now it searches over
__dyndbg_class_refs[] after __dyndbg_classes[].

ddebug_apply_class_bitmap(): now quieter when not changing things.

ddebug_class_name(): return class-names for defined AND used classes.

Signed-off-by: Jim Cromie 
--
v3 - s/BUG_ON/WARN_ON/ in __dyndbg_class_refs handling
 simpler args in callchain
v2 - rebase past merge conflicts
---
 include/asm-generic/vmlinux.lds.h |   1 +
 include/linux/dynamic_debug.h |  39 ---
 kernel/module/main.c  |   3 +
 lib/dynamic_debug.c   | 170 ++
 4 files changed, 179 insertions(+), 34 deletions(-)

diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 659bf3b31c91..5beb0321613e 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -373,6 +373,7 @@
/* implement dynamic printk debug */\
. = ALIGN(8);   \
BOUNDED_SECTION_BY(__dyndbg_classes, ___dyndbg_classes) \
+   BOUNDED_SECTION_BY(__dyndbg_class_refs, ___dyndbg_class_refs)   \
BOUNDED_SECTION_BY(__dyndbg, ___dyndbg)  

[PATCH v3 15/19] test-dyndbg: build test_dynamic_debug_submod

2023-01-25 Thread Jim Cromie
CONFIG_DRM_USE_DYNAMIC_DEBUG=y has a regression; drm subsystem
modules, which depend upon drm.ko and use the drm.debug API, do not
get enabled when __drm_debug is set by `modprobe drm debug=0x1f`.

With =N, __drm_debug is checked before logging the msg, so the
end-of-modprobe debug=$init affected all later checks.  But with =y,
each run-time check is replaced by a static-key that is set at
end-of-modprobe.

This creates a chicken-egg dependency; i915 must be modprobed before
its drm.debugs are enabled, but drm.ko (and __drm_debug=$init) must be
done before modprobe i915, so its callsites arent there yet to be
enabled.

The fix is to split DECLARE_DYNDBG_CLASSMAP to:

DYNDBG_CLASSMAP_DEFINE - invoked in 'parent'
DYNDBG_CLASSMAP_USE - invoked in dependent, to USE the exported definition

To prove the fix w/o involving DRM, we need 2 modules, one dependent
on the other.  Add test_dynamic_debug_submod.ko, which _USEs the
classmaps _exported by test_dynamic_debug.ko

To keep code to a minimum, test_dynamic_debug.c ifdefs on
TEST_DYNAMIC_DEBUG_SUBMOD to build either parent or dependent, with
either DYNDBG_CLASSMAP_DEFINE or DYNDBG_CLASSMAP_USE invocations.

So test_dynamic_debug_submod.c is just 2 lines: include the .c after
defining SUBMOD.  This also gives the 2 modules identical prdbg
callsites, only differing by enablement/configuration.

Signed-off-by: Jim Cromie 
---
 lib/Makefile|  3 +-
 lib/test_dynamic_debug.c| 52 -
 lib/test_dynamic_debug_submod.c | 10 +++
 3 files changed, 57 insertions(+), 8 deletions(-)
 create mode 100644 lib/test_dynamic_debug_submod.c

diff --git a/lib/Makefile b/lib/Makefile
index 4d9461bfea42..7f7e75f44cd7 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -77,7 +77,7 @@ obj-$(CONFIG_TEST_SORT) += test_sort.o
 obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o
 obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o
 obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o
-obj-$(CONFIG_TEST_DYNAMIC_DEBUG) += test_dynamic_debug.o
+obj-$(CONFIG_TEST_DYNAMIC_DEBUG) += test_dynamic_debug.o 
test_dynamic_debug_submod.o
 obj-$(CONFIG_TEST_PRINTF) += test_printf.o
 obj-$(CONFIG_TEST_SCANF) += test_scanf.o
 obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o
@@ -98,6 +98,7 @@ obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o
 obj-$(CONFIG_TEST_REF_TRACKER) += test_ref_tracker.o
 CFLAGS_test_fprobe.o += $(CC_FLAGS_FTRACE)
 obj-$(CONFIG_FPROBE_SANITY_TEST) += test_fprobe.o
+
 #
 # CFLAGS for compiling floating point code inside the kernel. x86/Makefile 
turns
 # off the generation of FPU/SSE* instructions for kernel proper but FPU_FLAGS
diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index e678884066bf..8c005c17f2db 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -6,7 +6,11 @@
  *  Jim Cromie 
  */
 
-#define pr_fmt(fmt) "test_dd: " fmt
+#if defined(TEST_DYNAMIC_DEBUG_SUBMOD)
+  #define pr_fmt(fmt) "test_dd_submod: " fmt
+#else
+  #define pr_fmt(fmt) "test_dd: " fmt
+#endif
 
 #define DEBUG /* enable all prdbgs (plain & class'd) at compiletime */
 
@@ -49,6 +53,14 @@ module_param_cb(do_prints, _ops_do_prints, NULL, 0600);
};  \
module_param_cb(_flags##_##_model, _ops_dyndbg_classes, 
&_flags##_model, 0600)
 
+/*
+ * dynamic-debug imitates drm.debug's use of enums (DRM_UT_CORE etc)
+ * to define its classes/categories.  dyndbg allows class-id's 0..62,
+ * reserving 63 for plain old (non-class'd) prdbgs.  A module can
+ * define multiple classmaps, as long as they claim non-overlapping
+ * subranges.
+ */
+
 /* numeric input, independent bits */
 enum cat_disjoint_bits {
D2_CORE = 0,
@@ -61,7 +73,36 @@ enum cat_disjoint_bits {
D2_LEASE,
D2_DP,
D2_DRMRES };
+
+/* symbolic input, independent bits */
+enum cat_disjoint_names { LOW = 10, MID, HI };
+
+/* numeric verbosity, V2 > V1 related */
+enum cat_level_num { V0 = 14, V1, V2, V3, V4, V5, V6, V7 };
+
+/* symbolic verbosity */
+enum cat_level_names { L0 = 22, L1, L2, L3, L4, L5, L6, L7 };
+
+#if defined(TEST_DYNAMIC_DEBUG_SUBMOD)
+
+/* use the classmaps defined in 'parent' module below */
+DYNDBG_CLASSMAP_USE(map_disjoint_bits);
+DYNDBG_CLASSMAP_USE(map_disjoint_names);
+DYNDBG_CLASSMAP_USE(map_level_num);
+DYNDBG_CLASSMAP_USE(map_level_names);
+
+#else
+
+/*
+ * parent module, define a classmap of each of 4 types.
+ * enum values are class-ids
+ * enum symbols are stringified, used as classnames
+ * param bits are mapped in order: 0..N
+ * (a straight, obvious, linear map is encouraged)
+ */
+
 DYNDBG_CLASSMAP_DEFINE(map_disjoint_bits, DD_CLASS_TYPE_DISJOINT_BITS,
+  /* bits 0..N of param are mapped to these class-ids */
   D2_CORE,
   D2_DRIVER,
   D2_KMS,
@@ -75,27 +116,23 @@ DYNDBG_CLASSMAP_DEFINE(map_disjoint_bits, 
DD_CLASS_TYPE_DISJOINT_BITS,
 

[PATCH v3 14/19] drm_print: fix stale macro-name in comment

2023-01-25 Thread Jim Cromie
Cited commit uses stale macro name, fix this, and explain better.

When DRM_USE_DYNAMIC_DEBUG=y, DYNDBG_CLASSMAP_DEFINE() maps DRM_UT_*
onto BITs in drm.debug.  This still uses enum drm_debug_category, but
it is somewhat indirect, with the ordered set of DRM_UT_* enum-vals.
This requires that the macro args: DRM_UT_* list must be kept in sync
and in order.

Fixes: f158936b60a7 ("drm: POC drm on dyndbg - use in core, 2 helpers, 3 
drivers.")
Signed-off-by: Jim Cromie 
---
. emphasize ABI non-change despite enum val change - Jani Nikula
. reorder to back of patchset to follow API name changes.
---
 include/drm/drm_print.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 6a27e8f26770..7695ba31b3a4 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -276,7 +276,10 @@ static inline struct drm_printer drm_err_printer(const 
char *prefix)
  *
  */
 enum drm_debug_category {
-   /* These names must match those in DYNAMIC_DEBUG_CLASSBITS */
+   /*
+* Keep DYNDBG_CLASSMAP_DEFINE args in sync with changes here,
+* the enum-values define BIT()s in drm.debug, so are ABI.
+*/
/**
 * @DRM_UT_CORE: Used in the generic drm code: drm_ioctl.c, drm_mm.c,
 * drm_memory.c, ...
-- 
2.39.1



[PATCH v3 09/19] dyndbg: constify ddebug_apply_class_bitmap args

2023-01-25 Thread Jim Cromie
ddebug_apply_class_bitmap() does not alter its 2 bitmap args, make
this guarantee in the interface.

NOTE: the bitmap is also available in the dcp arg, but the 2 vars
serve a 2nd purpose; the CLASS_TYPE callers use them to translate
levels into their underlying disjoint representation.

no functional change

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 10c29bc19901..b51f4bde6198 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -592,7 +592,7 @@ static int ddebug_exec_queries(char *query, const char 
*modname)
 
 /* apply a new bitmap to the sys-knob's current bit-state */
 static int ddebug_apply_class_bitmap(const struct ddebug_class_param *dcp,
-unsigned long *new_bits, unsigned long 
*old_bits,
+const unsigned long *new_bits, const 
unsigned long *old_bits,
 const char *query_modname)
 {
 #define QUERY_SIZE 128
-- 
2.39.1



[PATCH v3 17/19] test-dyndbg: disable WIP dyndbg-trace params

2023-01-25 Thread Jim Cromie
The dyndbg-to-trace feature is WIP, and not in mainline, so the
presence of the interface to use/test it is unhelpful/confusing.

So define DYNDBG_CLASSMAP_PARAM_T() as DYNDBG_CLASSMAP_PARAM() or
blank, depending upon ifdef DYDBG_TRACE, and update 4 params
controlling the T-flag to use it.

Signed-off-by: Jim Cromie 
---
 lib/test_dynamic_debug.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index ff1e70ae060e..6b7bd35c3e15 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -54,6 +54,14 @@ module_param_cb(do_prints, _ops_do_prints, NULL, 0600);
module_param_cb(_flags##_##_model, _ops_dyndbg_classes,   \
&_flags##_##_model, 0600)
 
+/* TBD */
+#ifdef DYNDBG_TRACE
+#define DYNDBG_CLASSMAP_PARAM_T(_model, _flags)\
+   DYNDBG_CLASSMAP_PARAM(_model, _flags)
+#else
+#define DYNDBG_CLASSMAP_PARAM_T(_model, _flags)
+#endif
+
 /*
  * dynamic-debug imitates drm.debug's use of enums (DRM_UT_CORE etc)
  * to define its classes/categories.  dyndbg allows class-id's 0..62,
@@ -115,22 +123,22 @@ DYNDBG_CLASSMAP_DEFINE(map_disjoint_bits, 
DD_CLASS_TYPE_DISJOINT_BITS,
   D2_DP,
   D2_DRMRES);
 DYNDBG_CLASSMAP_PARAM(disjoint_bits, p);
-DYNDBG_CLASSMAP_PARAM(disjoint_bits, T);
+DYNDBG_CLASSMAP_PARAM_T(disjoint_bits, T);
 
 DYNDBG_CLASSMAP_DEFINE(map_disjoint_names, DD_CLASS_TYPE_DISJOINT_NAMES,
   LOW, MID, HI);
 DYNDBG_CLASSMAP_PARAM(disjoint_names, p);
-DYNDBG_CLASSMAP_PARAM(disjoint_names, T);
+DYNDBG_CLASSMAP_PARAM_T(disjoint_names, T);
 
 DYNDBG_CLASSMAP_DEFINE(map_level_num, DD_CLASS_TYPE_LEVEL_NUM,
   V0, V1, V2, V3, V4, V5, V6, V7);
 DYNDBG_CLASSMAP_PARAM(level_num, p);
-DYNDBG_CLASSMAP_PARAM(level_num, T);
+DYNDBG_CLASSMAP_PARAM_T(level_num, T);
 
 DYNDBG_CLASSMAP_DEFINE(map_level_names, DD_CLASS_TYPE_LEVEL_NAMES,
   L0, L1, L2, L3, L4, L5, L6, L7);
 DYNDBG_CLASSMAP_PARAM(level_names, p);
-DYNDBG_CLASSMAP_PARAM(level_names, T);
+DYNDBG_CLASSMAP_PARAM_T(level_names, T);
 
 #endif /* TEST_DYNAMIC_DEBUG_SUBMOD */
 
-- 
2.39.1



[PATCH v3 19/19] jump_label: RFC / temporary for CI - tolerate toggled state

2023-01-25 Thread Jim Cromie
__jump_label_patch currently will "crash the box" if it finds a
jump_entry not as expected; it makes no allowances for the well-formed
but incorrect "toggled" state.  This patch changes panic-on-toggled
into a warning, allowing to reduce the problem to a repeatable script.

note: this patch is arch/x86 only, so might not help CI at all.

submod () {
# set drm.debug analogues
echo  MP test_dynamic_debug p_disjoint_bits=${1:-0} p_level_num=${2:-0}
modprobe test_dynamic_debug p_disjoint_bits=${1:-0} p_level_num=${2:-0} 
dyndbg=+p
# _submod should pick up kparams
echo  MP test_dynamic_debug_submod dyndbg=+pmf
modprobe test_dynamic_debug_submod dyndbg=+pmf
}
unmod () {
rmmod test_dynamic_debug_submod
rmmod test_dynamic_debug
}
note () {
echo NOTE: $* >&2
sleep 0.1
}

submod_probe () {

echo 4 > /sys/module/dynamic_debug/parameters/verbose
unmod
submod $*

note submod prdbgs are supposedly enabled
grep test_dynamic_debug /proc/dynamic_debug/control
cat /sys/module/test_dynamic_debug/parameters/do_prints

note but they dont print here
cat /sys/module/test_dynamic_debug_submod/parameters/do_prints

note if D2_CORE in $1, trigger toggled warning
note echo class D2_CORE -p
echo class D2_CORE -p > /proc/dynamic_debug/control
}

heres the repeatable results

[   17.023758] virtme-init: triggering udev coldplug
[   18.285949] virtme-init: waiting for udev to settle
[   22.550866] i2c_piix4: module verification failed: signature and/or required 
key missing - tainting kernel
[   22.551945] dyndbg: add-module: i2c_piix4 12 sites 0.0
[   22.552277] dyndbg:  12 debug prints in module i2c_piix4
[   22.555099] piix4_smbus :00:01.3: SMBus Host Controller at 0x700, 
revision 0
[   22.597344] dyndbg: add-module: serio_raw 2 sites 0.0
[   22.597633] dyndbg:   2 debug prints in module serio_raw
[   22.603506] input: PC Speaker as /devices/platform/pcspkr/input/input4
[   23.556657] dyndbg: add-module: intel_rapl_common 12 sites 0.0
[   23.557000] dyndbg:  12 debug prints in module intel_rapl_common
[   23.759499] dyndbg: add-module: intel_rapl_msr 2 sites 0.0
[   23.759928] dyndbg:   2 debug prints in module intel_rapl_msr
[   26.081050] virtme-init: udev is done
virtme-init: console is ttyS0
bash-5.2# . test-funcs.rc
:#> submod_probe 1 0
rmmod: ERROR: Module test_dynamic_debug_submod is not currently loaded
rmmod: ERROR: Module test_dynamic_debug is not currently loaded
MP test_dynamic_debug p_disjoint_bits=1 p_level_num=0 dyndbg=+pm
[   61.712445] dyndbg: add-module: test_dynamic_debug 33 sites 4.0
[   61.712789] dyndbg: classes[0..]: module:test_dynamic_debug base:22 len:8 
ty:3
[   61.713144] dyndbg: module:test_dynamic_debug attached 4 classes
[   61.713894] dyndbg:  33 debug prints in module test_dynamic_debug
[   61.715486] dyndbg: bits:0x1 > *.p_disjoint_bits
[   61.715732] dyndbg: apply bitmap: 0x1 to: 0x0 for '*'
[   61.715983] dyndbg: query 0: "class D2_CORE +p" mod:*
[   61.716253] dyndbg: split into words: "class" "D2_CORE" "+p"
[   61.716539] dyndbg: op='+' flags=0x1 maskp=0x
[   61.716794] dyndbg: parsed: func="" file="" module="" format="" lineno=0-0 
class=D2_CORE
[   61.717232] dyndbg: good-class: test_dynamic_debug.D2_CORE  
module:test_dynamic_debug nd:33 nc:4 nu:0
[   61.717690] dyndbg: processed 1 queries, with 1 matches, 0 errs
[   61.717982] dyndbg: bit_0: 1 matches on class: D2_CORE -> 0x1
[   61.718283] dyndbg: applied bitmap: 0x1 to: 0x0 for '*'
[   61.718542] dyndbg: p_disjoint_bits: total matches: 1
[   61.718799] dyndbg: lvl:0 bits:0x0 > p_level_num
[   61.719029] dyndbg: p_level_num: total matches: 0
[   61.719279] dyndbg: module: test_dynamic_debug dyndbg="+pm"
[   61.719554] dyndbg: query 0: "+pm" mod:test_dynamic_debug
[   61.719824] dyndbg: split into words: "+pm"
[   61.720034] dyndbg: op='+' flags=0x3 maskp=0x
[   61.720299] dyndbg: parsed: func="" file="" module="test_dynamic_debug" 
format="" lineno=0-0 class=(null)
[   61.720786] dyndbg: changed lib/test_dynamic_debug.c:206 
[test_dynamic_debug]test_dynamic_debug_exit p => pm
[   61.721289] dyndbg: changed lib/test_dynamic_debug.c:200 
[test_dynamic_debug]test_dynamic_debug_init p => pm
[   61.721778] dyndbg: changed lib/test_dynamic_debug.c:198 
[test_dynamic_debug]test_dynamic_debug_init p => pm
[   61.722283] dyndbg: changed lib/test_dynamic_debug.c:191 
[test_dynamic_debug]do_prints p => pm
[   61.722711] dyndbg: changed lib/test_dynamic_debug.c:170 
[test_dynamic_debug]do_levels p => pm
[   61.723128] dyndbg: changed lib/test_dynamic_debug.c:150 
[test_dynamic_debug]do_cats p => pm
[   61.723554] dyndbg: processed 1 queries, with 6 matches, 0 errs
[   61.725233] test_dynamic_debug: test_dd: init start
[   61.725487] test_dynamic_debug: test_dd: do_prints:
[   61.725745] test_dynamic_debug: test_dd: doing categories
[   61.726011] test_dd: LOW msg
[   61.726176] test_dd: MID msg
[   61.726328] test_dd: HI msg
[   61.726470] test_dd: 

[PATCH v3 08/19] dyndbg: tighten ddebug_class_name() 1st arg

2023-01-25 Thread Jim Cromie
Change function's 1st arg-type, by derefing in the caller.
The fn doesn't need any other fields in the struct.

no functional change.

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 2d4640479e5b..10c29bc19901 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -1110,12 +1110,12 @@ static void *ddebug_proc_next(struct seq_file *m, void 
*p, loff_t *pos)
 #define class_in_range(class_id, map)  \
(class_id >= map->base && class_id < map->base + map->length)
 
-static const char *ddebug_class_name(struct ddebug_iter *iter, struct _ddebug 
*dp)
+static const char *ddebug_class_name(struct ddebug_table *dt, struct _ddebug 
*dp)
 {
-   struct ddebug_class_map *map = iter->table->classes;
-   int i, nc = iter->table->num_classes;
+   struct ddebug_class_map *map = dt->classes;
+   int i;
 
-   for (i = 0; i < nc; i++, map++)
+   for (i = 0; i < dt->num_classes; i++, map++)
if (class_in_range(dp->class_id, map))
return map->class_names[dp->class_id - map->base];
 
@@ -1149,7 +1149,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
seq_puts(m, "\"");
 
if (dp->class_id != _DPRINTK_CLASS_DFLT) {
-   class = ddebug_class_name(iter, dp);
+   class = ddebug_class_name(iter->table, dp);
if (class)
seq_printf(m, " class:%s", class);
else
-- 
2.39.1



[PATCH v3 16/19] test-dyndbg: rename DD_SYS_WRAP to DYNDBG_CLASSMAP_PARAM

2023-01-25 Thread Jim Cromie
Original name was a punt; but the macro is maybe general enough to put
in the API later.  Rename and improve the macro towards that end.

Also tweak internal name constructed in the macro, to add a '_'
between the name components.  This changes the .i file only.

no functional change.

Signed-off-by: Jim Cromie 
---
 lib/test_dynamic_debug.c | 23 ---
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index 8c005c17f2db..ff1e70ae060e 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -44,14 +44,15 @@ module_param_cb(do_prints, _ops_do_prints, NULL, 
0600);
  * Additionally, here:
  * - tie together sysname, mapname, bitsname, flagsname
  */
-#define DD_SYS_WRAP(_model, _flags)\
+#define DYNDBG_CLASSMAP_PARAM(_model, _flags)  \
static unsigned long bits_##_model; \
-   static struct ddebug_class_param _flags##_model = { \
+   static struct ddebug_class_param _flags##_##_model = {  \
.bits = _##_model, \
.flags = #_flags,   \
.map = _##_model,   \
};  \
-   module_param_cb(_flags##_##_model, _ops_dyndbg_classes, 
&_flags##_model, 0600)
+   module_param_cb(_flags##_##_model, _ops_dyndbg_classes,   \
+   &_flags##_##_model, 0600)
 
 /*
  * dynamic-debug imitates drm.debug's use of enums (DRM_UT_CORE etc)
@@ -113,23 +114,23 @@ DYNDBG_CLASSMAP_DEFINE(map_disjoint_bits, 
DD_CLASS_TYPE_DISJOINT_BITS,
   D2_LEASE,
   D2_DP,
   D2_DRMRES);
-DD_SYS_WRAP(disjoint_bits, p);
-DD_SYS_WRAP(disjoint_bits, T);
+DYNDBG_CLASSMAP_PARAM(disjoint_bits, p);
+DYNDBG_CLASSMAP_PARAM(disjoint_bits, T);
 
 DYNDBG_CLASSMAP_DEFINE(map_disjoint_names, DD_CLASS_TYPE_DISJOINT_NAMES,
   LOW, MID, HI);
-DD_SYS_WRAP(disjoint_names, p);
-DD_SYS_WRAP(disjoint_names, T);
+DYNDBG_CLASSMAP_PARAM(disjoint_names, p);
+DYNDBG_CLASSMAP_PARAM(disjoint_names, T);
 
 DYNDBG_CLASSMAP_DEFINE(map_level_num, DD_CLASS_TYPE_LEVEL_NUM,
   V0, V1, V2, V3, V4, V5, V6, V7);
-DD_SYS_WRAP(level_num, p);
-DD_SYS_WRAP(level_num, T);
+DYNDBG_CLASSMAP_PARAM(level_num, p);
+DYNDBG_CLASSMAP_PARAM(level_num, T);
 
 DYNDBG_CLASSMAP_DEFINE(map_level_names, DD_CLASS_TYPE_LEVEL_NAMES,
   L0, L1, L2, L3, L4, L5, L6, L7);
-DD_SYS_WRAP(level_names, p);
-DD_SYS_WRAP(level_names, T);
+DYNDBG_CLASSMAP_PARAM(level_names, p);
+DYNDBG_CLASSMAP_PARAM(level_names, T);
 
 #endif /* TEST_DYNAMIC_DEBUG_SUBMOD */
 
-- 
2.39.1



[PATCH v3 10/19] dyndbg-API: split DECLARE_(DYNDBG_CLASSMAP) to $1(_DEFINE|_USE)

2023-01-25 Thread Jim Cromie
DECLARE_DYNDBG_CLASSMAP's job was to allow modules to declare the debug
classes/categories they want dyndbg to >control on their behalf.  Its
args give the class-names, their mapping to class_ids, and the sysfs
interface style (usually a class-bitmap).  Modules wanting a drm.debug
style knob need to create the kparam, and call module_param_cb() to
wire the sysfs node to the classmap.  DRM does this is in drm_print.c

In DRM, multiple modules declare identical DRM_UT_* classmaps, so that
the class'd prdbgs are modified across those modules in a coordinated
way across the subsystem, by either explicit class DRM_UT_* queries to
>control, or by writes to /sys/module/drm/parameters/debug (drm.debug)

This coordination-by-identical-declarations is weird, so this patch
splits the macro into _DEFINE and _USE flavors.  This distinction
follows the definition vs declaration that K gave us, improving the
api; _DEFINE is used once to specify the classmap, and multiple users
_USE the single definition explicitly.

Currently the latter just reuses the former, and still needs all the
same args, but that can be tuned later; the _DEFINE can initialize an
(extern/global) struct classmap, and _USE can, well use/reference
that struct.

Also wrap DYNDBG_CLASSMAP_USEs with ifdef DRM_USE_DYNAMIC_DEBUG to
balance with the one around drm_print's use of DYNDBG_CLASSMAP_DEFINE.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  4 +++-
 drivers/gpu/drm/display/drm_dp_helper.c |  4 +++-
 drivers/gpu/drm/drm_crtc_helper.c   |  4 +++-
 drivers/gpu/drm/drm_print.c |  2 +-
 drivers/gpu/drm/i915/i915_params.c  |  4 +++-
 drivers/gpu/drm/nouveau/nouveau_drm.c   |  4 +++-
 include/linux/dynamic_debug.h   | 20 
 lib/test_dynamic_debug.c| 32 -
 8 files changed, 48 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index cd4caaa29528..a7a3a382c4a6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -189,7 +189,8 @@ int amdgpu_vcnfw_log;
 
 static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
 
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
+#if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
+DYNDBG_CLASSMAP_USE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
"DRM_UT_CORE",
"DRM_UT_DRIVER",
"DRM_UT_KMS",
@@ -200,6 +201,7 @@ DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, 
DD_CLASS_TYPE_DISJOINT_BITS, 0,
"DRM_UT_LEASE",
"DRM_UT_DP",
"DRM_UT_DRMRES");
+#endif
 
 struct amdgpu_mgpu_info mgpu_info = {
.mutex = __MUTEX_INITIALIZER(mgpu_info.mutex),
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index 16565a0a5da6..8fa7a88299e7 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -41,7 +41,8 @@
 
 #include "drm_dp_helper_internal.h"
 
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
+#if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
+DYNDBG_CLASSMAP_USE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
"DRM_UT_CORE",
"DRM_UT_DRIVER",
"DRM_UT_KMS",
@@ -52,6 +53,7 @@ DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, 
DD_CLASS_TYPE_DISJOINT_BITS, 0,
"DRM_UT_LEASE",
"DRM_UT_DP",
"DRM_UT_DRMRES");
+#endif
 
 struct dp_aux_backlight {
struct backlight_device *base;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c 
b/drivers/gpu/drm/drm_crtc_helper.c
index a209659a996c..7e6b25446303 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -50,7 +50,8 @@
 
 #include "drm_crtc_helper_internal.h"
 
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
+#if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
+DYNDBG_CLASSMAP_USE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
"DRM_UT_CORE",
"DRM_UT_DRIVER",
"DRM_UT_KMS",
@@ -61,6 +62,7 @@ DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, 
DD_CLASS_TYPE_DISJOINT_BITS, 0,
"DRM_UT_LEASE",
"DRM_UT_DP",
"DRM_UT_DRMRES");
+#endif
 
 /**
  * DOC: overview
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 5b93c11895bb..4b697e18238d 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit 
enables a debug cat
 module_param_named(debug, __drm_debug, ulong, 0600);
 #else
 /* classnames must match vals of enum drm_debug_category */

[PATCH v3 07/19] dyndbg: reduce verbose/debug clutter

2023-01-25 Thread Jim Cromie
currently, for verbose=3, this is logged:

 dyndbg: query 0: "class DRM_UT_CORE +p" mod:*
 dyndbg: split into words: "class" "DRM_UT_CORE" "+p"

 dyndbg: op='+'
 dyndbg: flags=0x1
 dyndbg: *flagsp=0x1 *maskp=0x

 dyndbg: parsed: func="" file="" module="" format="" lineno=0-0 
class=DRM_UT_CORE
 dyndbg: no matches for query
 dyndbg: no-match: func="" file="" module="" format="" lineno=0-0 
class=DRM_UT_CORE
 dyndbg: processed 1 queries, with 0 matches, 0 errs

This patch:

shrinks 3 lines of 2nd stanza to single line

drops 2 middle lines of 3rd stanza
 3 differs from 1 only by status
 2 is just status, retold in 4, with more info.

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 0a5efc735b36..2d4640479e5b 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -265,9 +265,6 @@ static int ddebug_change(const struct ddebug_query *query,
}
mutex_unlock(_lock);
 
-   if (!nfound && verbose)
-   pr_info("no matches for query\n");
-
return nfound;
 }
 
@@ -496,7 +493,6 @@ static int ddebug_parse_flags(const char *str, struct 
flag_settings *modifiers)
pr_err("bad flag-op %c, at start of %s\n", *str, str);
return -EINVAL;
}
-   v3pr_info("op='%c'\n", op);
 
for (; *str ; ++str) {
for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
@@ -510,7 +506,6 @@ static int ddebug_parse_flags(const char *str, struct 
flag_settings *modifiers)
return -EINVAL;
}
}
-   v3pr_info("flags=0x%x\n", modifiers->flags);
 
/* calculate final flags, mask based upon op */
switch (op) {
@@ -526,7 +521,7 @@ static int ddebug_parse_flags(const char *str, struct 
flag_settings *modifiers)
modifiers->flags = 0;
break;
}
-   v3pr_info("*flagsp=0x%x *maskp=0x%x\n", modifiers->flags, 
modifiers->mask);
+   v3pr_info("op='%c' flags=0x%x maskp=0x%x\n", op, modifiers->flags, 
modifiers->mask);
 
return 0;
 }
@@ -536,7 +531,7 @@ static int ddebug_exec_query(char *query_string, const char 
*modname)
struct flag_settings modifiers = {};
struct ddebug_query query = {};
 #define MAXWORDS 9
-   int nwords, nfound;
+   int nwords;
char *words[MAXWORDS];
 
nwords = ddebug_tokenize(query_string, words, MAXWORDS);
@@ -554,10 +549,7 @@ static int ddebug_exec_query(char *query_string, const 
char *modname)
return -EINVAL;
}
/* actually go and implement the change */
-   nfound = ddebug_change(, );
-   vpr_info_dq(, nfound ? "applied" : "no-match");
-
-   return nfound;
+   return ddebug_change(, );
 }
 
 /* handle multiple queries in query string, continue on error, return
-- 
2.39.1



[PATCH v3 12/19] dyndbg-API: DYNDBG_CLASSMAP_USE drop extra args

2023-01-25 Thread Jim Cromie
Drop macro args after _var.  Since DYNDBG_CLASSMAP_USE no longer
forwards to DYNDBG_CLASSMAP_DEFINE, it doesn't need those args to
forward.  Keep only the _var arg, which is the extern'd struct
classmap with all the class info.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 12 +-
 drivers/gpu/drm/display/drm_dp_helper.c | 12 +-
 drivers/gpu/drm/drm_crtc_helper.c   | 12 +-
 drivers/gpu/drm/i915/i915_params.c  | 12 +-
 drivers/gpu/drm/nouveau/nouveau_drm.c   | 12 +-
 include/linux/dynamic_debug.h   | 30 ++---
 6 files changed, 22 insertions(+), 68 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index a7a3a382c4a6..6c57e598b7d2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -190,17 +190,7 @@ int amdgpu_vcnfw_log;
 static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
 
 #if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
-DYNDBG_CLASSMAP_USE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
-   "DRM_UT_CORE",
-   "DRM_UT_DRIVER",
-   "DRM_UT_KMS",
-   "DRM_UT_PRIME",
-   "DRM_UT_ATOMIC",
-   "DRM_UT_VBL",
-   "DRM_UT_STATE",
-   "DRM_UT_LEASE",
-   "DRM_UT_DP",
-   "DRM_UT_DRMRES");
+DYNDBG_CLASSMAP_USE(drm_debug_classes);
 #endif
 
 struct amdgpu_mgpu_info mgpu_info = {
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index 8fa7a88299e7..3bc188cb1116 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -42,17 +42,7 @@
 #include "drm_dp_helper_internal.h"
 
 #if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
-DYNDBG_CLASSMAP_USE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
-   "DRM_UT_CORE",
-   "DRM_UT_DRIVER",
-   "DRM_UT_KMS",
-   "DRM_UT_PRIME",
-   "DRM_UT_ATOMIC",
-   "DRM_UT_VBL",
-   "DRM_UT_STATE",
-   "DRM_UT_LEASE",
-   "DRM_UT_DP",
-   "DRM_UT_DRMRES");
+DYNDBG_CLASSMAP_USE(drm_debug_classes);
 #endif
 
 struct dp_aux_backlight {
diff --git a/drivers/gpu/drm/drm_crtc_helper.c 
b/drivers/gpu/drm/drm_crtc_helper.c
index 7e6b25446303..1780db9de069 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -51,17 +51,7 @@
 #include "drm_crtc_helper_internal.h"
 
 #if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
-DYNDBG_CLASSMAP_USE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
-   "DRM_UT_CORE",
-   "DRM_UT_DRIVER",
-   "DRM_UT_KMS",
-   "DRM_UT_PRIME",
-   "DRM_UT_ATOMIC",
-   "DRM_UT_VBL",
-   "DRM_UT_STATE",
-   "DRM_UT_LEASE",
-   "DRM_UT_DP",
-   "DRM_UT_DRMRES");
+DYNDBG_CLASSMAP_USE(drm_debug_classes);
 #endif
 
 /**
diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index b5b2542ae364..e959d0384ead 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -30,17 +30,7 @@
 #include "i915_drv.h"
 
 #if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
-DYNDBG_CLASSMAP_USE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
-   "DRM_UT_CORE",
-   "DRM_UT_DRIVER",
-   "DRM_UT_KMS",
-   "DRM_UT_PRIME",
-   "DRM_UT_ATOMIC",
-   "DRM_UT_VBL",
-   "DRM_UT_STATE",
-   "DRM_UT_LEASE",
-   "DRM_UT_DP",
-   "DRM_UT_DRMRES");
+DYNDBG_CLASSMAP_USE(drm_debug_classes);
 #endif
 
 #define i915_param_named(name, T, perm, desc) \
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c 
b/drivers/gpu/drm/nouveau/nouveau_drm.c
index e4146b9af357..ad341411687f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -72,17 +72,7 @@
 #include "nouveau_dmem.h"
 
 #if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
-DYNDBG_CLASSMAP_USE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
-   "DRM_UT_CORE",
-   "DRM_UT_DRIVER",
-   "DRM_UT_KMS",
-   "DRM_UT_PRIME",
-   "DRM_UT_ATOMIC",
-   "DRM_UT_VBL",
-   "DRM_UT_STATE",
-   "DRM_UT_LEASE",
-   "DRM_UT_DP",
-   "DRM_UT_DRMRES");

[PATCH v3 06/19] dyndbg: drop NUM_TYPE_ARRAY

2023-01-25 Thread Jim Cromie
ARRAY_SIZE works here, since array decl is complete.

no functional change

Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index bf47bcfad8e6..81b643ab7f6e 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -104,11 +104,9 @@ struct ddebug_class_map {
.mod_name = KBUILD_MODNAME, \
.base = _base,  \
.map_type = _maptype,   \
-   .length = NUM_TYPE_ARGS(char*, __VA_ARGS__),\
+   .length = ARRAY_SIZE(_var##_classnames),\
.class_names = _var##_classnames,   \
}
-#define NUM_TYPE_ARGS(eltype, ...) \
-(sizeof((eltype[]){__VA_ARGS__}) / sizeof(eltype))
 
 /* encapsulate linker provided built-in (or module) dyndbg data */
 struct _ddebug_info {
-- 
2.39.1



[PATCH v3 05/19] dyndbg: split param_set_dyndbg_classes to inner/outer fns

2023-01-25 Thread Jim Cromie
Inner fn adds mod_name param, allowing caller to guarantee that only
one module is affected by a prdbgs update.  Outer fn preserves
kernel_param interface, passing NULL to inner fn.

no functional change.

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 36 +---
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 943e0597ecd4..0a5efc735b36 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -707,18 +707,9 @@ static int param_set_dyndbg_classnames(const char *instr, 
const struct kernel_pa
return 0;
 }
 
-/**
- * param_set_dyndbg_classes - class FOO >control
- * @instr: string echo>d to sysfs, input depends on map_type
- * @kp:kp->arg has state: bits/lvl, map, map_type
- *
- * Enable/disable prdbgs by their class, as given in the arguments to
- * DECLARE_DYNDBG_CLASSMAP.  For LEVEL map-types, enforce relative
- * levels by bitpos.
- *
- * Returns: 0 or <0 if error.
- */
-int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp)
+static int param_set_dyndbg_module_classes(const char *instr,
+  const struct kernel_param *kp,
+  const char *modnm)
 {
const struct ddebug_class_param *dcp = kp->arg;
const struct ddebug_class_map *map = dcp->map;
@@ -755,8 +746,8 @@ int param_set_dyndbg_classes(const char *instr, const 
struct kernel_param *kp)
KP_NAME(kp), inrep, 
CLASSMAP_BITMASK(map->length));
inrep &= CLASSMAP_BITMASK(map->length);
}
-   v2pr_info("bits:%lx > %s\n", inrep, KP_NAME(kp));
-   totct += ddebug_apply_class_bitmap(dcp, , dcp->bits, 
NULL);
+   v2pr_info("bits:0x%lx > %s.%s\n", inrep, modnm ?: "*", 
KP_NAME(kp));
+   totct += ddebug_apply_class_bitmap(dcp, , dcp->bits, 
modnm);
*dcp->bits = inrep;
break;
case DD_CLASS_TYPE_LEVEL_NUM:
@@ -769,7 +760,7 @@ int param_set_dyndbg_classes(const char *instr, const 
struct kernel_param *kp)
old_bits = CLASSMAP_BITMASK(*dcp->lvl);
new_bits = CLASSMAP_BITMASK(inrep);
v2pr_info("lvl:%ld bits:0x%lx > %s\n", inrep, new_bits, 
KP_NAME(kp));
-   totct += ddebug_apply_class_bitmap(dcp, _bits, _bits, 
NULL);
+   totct += ddebug_apply_class_bitmap(dcp, _bits, _bits, 
modnm);
*dcp->lvl = inrep;
break;
default:
@@ -778,6 +769,21 @@ int param_set_dyndbg_classes(const char *instr, const 
struct kernel_param *kp)
vpr_info("%s: total matches: %d\n", KP_NAME(kp), totct);
return 0;
 }
+/**
+ * param_set_dyndbg_classes - class FOO >control
+ * @instr: string echo>d to sysfs, input depends on map_type
+ * @kp:kp->arg has state: bits/lvl, map, map_type
+ *
+ * Enable/disable prdbgs by their class, as given in the arguments to
+ * DECLARE_DYNDBG_CLASSMAP.  For LEVEL map-types, enforce relative
+ * levels by bitpos.
+ *
+ * Returns: 0 or <0 if error.
+ */
+int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp)
+{
+   return param_set_dyndbg_module_classes(instr, kp, NULL);
+}
 EXPORT_SYMBOL(param_set_dyndbg_classes);
 
 /**
-- 
2.39.1



[PATCH v3 04/19] dyndbg: make ddebug_apply_class_bitmap more selective

2023-01-25 Thread Jim Cromie
Add query_module param to ddebug_apply_class_bitmap().  This allows
its caller to update just one module, or all (as currently).  We'll
use this later to propagate drm.debug to each USEr as they're
modprobed.

No functional change.

Signed-off-by: Jim Cromie 
---

after `modprobe i915`, heres the module dependencies,
though not all on drm.debug.

bash-5.2# lsmod
Module  Size  Used by
i915 3133440  0
drm_buddy  20480  1 i915
ttm90112  1 i915
i2c_algo_bit   16384  1 i915
video  61440  1 i915
wmi32768  1 video
drm_display_helper200704  1 i915
drm_kms_helper208896  2 drm_display_helper,i915
drm   606208  5 
drm_kms_helper,drm_display_helper,drm_buddy,i915,ttm
cec57344  2 drm_display_helper,i915
---
 lib/dynamic_debug.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 823190094350..943e0597ecd4 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -600,7 +600,8 @@ static int ddebug_exec_queries(char *query, const char 
*modname)
 
 /* apply a new bitmap to the sys-knob's current bit-state */
 static int ddebug_apply_class_bitmap(const struct ddebug_class_param *dcp,
-unsigned long *new_bits, unsigned long 
*old_bits)
+unsigned long *new_bits, unsigned long 
*old_bits,
+const char *query_modname)
 {
 #define QUERY_SIZE 128
char query[QUERY_SIZE];
@@ -608,7 +609,8 @@ static int ddebug_apply_class_bitmap(const struct 
ddebug_class_param *dcp,
int matches = 0;
int bi, ct;
 
-   v2pr_info("apply: 0x%lx to: 0x%lx\n", *new_bits, *old_bits);
+   v2pr_info("apply bitmap: 0x%lx to: 0x%lx for %s\n", *new_bits, 
*old_bits,
+ query_modname ?: "");
 
for (bi = 0; bi < map->length; bi++) {
if (test_bit(bi, new_bits) == test_bit(bi, old_bits))
@@ -617,12 +619,15 @@ static int ddebug_apply_class_bitmap(const struct 
ddebug_class_param *dcp,
snprintf(query, QUERY_SIZE, "class %s %c%s", 
map->class_names[bi],
 test_bit(bi, new_bits) ? '+' : '-', dcp->flags);
 
-   ct = ddebug_exec_queries(query, NULL);
+   ct = ddebug_exec_queries(query, query_modname);
matches += ct;
 
v2pr_info("bit_%d: %d matches on class: %s -> 0x%lx\n", bi,
  ct, map->class_names[bi], *new_bits);
}
+   v2pr_info("applied bitmap: 0x%lx to: 0x%lx for %s\n", *new_bits, 
*old_bits,
+ query_modname ?: "");
+
return matches;
 }
 
@@ -678,7 +683,7 @@ static int param_set_dyndbg_classnames(const char *instr, 
const struct kernel_pa
continue;
}
curr_bits ^= BIT(cls_id);
-   totct += ddebug_apply_class_bitmap(dcp, _bits, 
dcp->bits);
+   totct += ddebug_apply_class_bitmap(dcp, _bits, 
dcp->bits, NULL);
*dcp->bits = curr_bits;
v2pr_info("%s: changed bit %d:%s\n", KP_NAME(kp), 
cls_id,
  map->class_names[cls_id]);
@@ -688,7 +693,7 @@ static int param_set_dyndbg_classnames(const char *instr, 
const struct kernel_pa
old_bits = CLASSMAP_BITMASK(*dcp->lvl);
curr_bits = CLASSMAP_BITMASK(cls_id + (wanted ? 1 : 0 
));
 
-   totct += ddebug_apply_class_bitmap(dcp, _bits, 
_bits);
+   totct += ddebug_apply_class_bitmap(dcp, _bits, 
_bits, NULL);
*dcp->lvl = (cls_id + (wanted ? 1 : 0));
v2pr_info("%s: changed bit-%d: \"%s\" %lx->%lx\n", 
KP_NAME(kp), cls_id,
  map->class_names[cls_id], old_bits, 
curr_bits);
@@ -751,7 +756,7 @@ int param_set_dyndbg_classes(const char *instr, const 
struct kernel_param *kp)
inrep &= CLASSMAP_BITMASK(map->length);
}
v2pr_info("bits:%lx > %s\n", inrep, KP_NAME(kp));
-   totct += ddebug_apply_class_bitmap(dcp, , dcp->bits);
+   totct += ddebug_apply_class_bitmap(dcp, , dcp->bits, 
NULL);
*dcp->bits = inrep;
break;
case DD_CLASS_TYPE_LEVEL_NUM:
@@ -764,7 +769,7 @@ int param_set_dyndbg_classes(const char *instr, const 
struct kernel_param *kp)
old_bits = CLASSMAP_BITMASK(*dcp->lvl);
new_bits = CLASSMAP_BITMASK(inrep);
v2pr_info("lvl:%ld bits:0x%lx > %s\n", inrep, new_bits, 
KP_NAME(kp));
-   totct += ddebug_apply_class_bitmap(dcp, _bits, _bits);
+   totct += ddebug_apply_class_bitmap(dcp, _bits, _bits, 
NULL);

[PATCH v3 02/19] test-dyndbg: show that DEBUG enables prdbgs at compiletime

2023-01-25 Thread Jim Cromie
Dyndbg is required to enable prdbgs at compile-time if DEBUG is
defined.  Show this works; add the defn to test_dynamic_debug.c,
and manually inspect/verify its effect at module load:

[   15.292810] dyndbg: module:test_dynamic_debug attached 4 classes
[   15.293189] dyndbg:  32 debug prints in module test_dynamic_debug
[   15.293715] test_dd: init start
[   15.293716] test_dd: doing categories
[   15.293716] test_dd: LOW msg
...
[   15.293733] test_dd: L6 msg
[   15.293733] test_dd: L7 msg
[   15.293733] test_dd: init done

NOTES:

As is observable above, define DEBUG enables all prdbgs, including
those in mod_init-fn, and more notably, the class'd ones (callsites
with non-default class_ids).

This differs from the >control interface, which in order to properly
protect a client's class'd prdbgs, requires a "class FOO" in queries
to change them.  If this sounds wrong, note that the DEBUG is in the
module source file, and is thus privileged.

This yields an occaisional surprise; the following disables all the
compile-time enabled plain prdbgs, but leaves the class'd ones
enabled.

 :#> modprobe test_dynamic_debug dyndbg==_

Signed-off-by: Jim Cromie 
---
 lib/test_dynamic_debug.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index a01f0193a419..89dd7f285e31 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -8,6 +8,8 @@
 
 #define pr_fmt(fmt) "test_dd: " fmt
 
+#define DEBUG /* enable all prdbgs (plain & class'd) at compiletime */
+
 #include 
 
 /* run tests by reading or writing sysfs node: do_prints */
-- 
2.39.1



[PATCH v3 03/19] dyndbg: replace classmap list with a vector

2023-01-25 Thread Jim Cromie
Classmaps are stored/linked in a section/array, but are each added to
the module's ddebug_table.maps list-head.

This is unnecessary; even when ddebug_attach_classmap() is handling
the builtin section (with classmaps for multiple builtin modules), its
contents are ordered, so a module's possibly multiple classmaps will
be consecutive in the section, and could be treated as a vector/block,
since both start-addy and subrange length are in the ddebug_info arg.

So this changes:

struct ddebug_class_map drops list-head link.

struct ddebug_table drops the list-head maps, and gets: classes &
num_classes for the start-addy and num_classes, placed to improve
struct packing.

The loading: in ddebug_attach_module_classes(), replace the
for-the-modname list-add loop, with a forloop that finds the module's
subrange (start,length) of matching classmaps within the possibly
builtin classmaps vector, and saves those to the ddebug_table.

The reading/using: change list-foreach loops in ddebug_class_name() &
ddebug_find_valid_class() to walk the array from start to length.

Also:
Move #define __outvar up, above an added use in a fn-prototype.
Simplify ddebug_attach_module_classes args, ref has both addy,len.

This isn't technically a bugfix, but IMO simplifies later fixes for
the chicken-egg post-init enablement regression.

Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h |  1 -
 lib/dynamic_debug.c   | 61 ++-
 2 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 41682278d2e8..bf47bcfad8e6 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -81,7 +81,6 @@ enum class_map_type {
 };
 
 struct ddebug_class_map {
-   struct list_head link;
struct module *mod;
const char *mod_name;   /* needed for builtins */
const char **class_names;
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 009f2ead09c1..823190094350 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -45,10 +45,11 @@ extern struct ddebug_class_map __start___dyndbg_classes[];
 extern struct ddebug_class_map __stop___dyndbg_classes[];
 
 struct ddebug_table {
-   struct list_head link, maps;
+   struct list_head link;
const char *mod_name;
-   unsigned int num_ddebugs;
struct _ddebug *ddebugs;
+   struct ddebug_class_map *classes;
+   unsigned int num_ddebugs, num_classes;
 };
 
 struct ddebug_query {
@@ -146,13 +147,15 @@ static void vpr_info_dq(const struct ddebug_query *query, 
const char *msg)
  query->first_lineno, query->last_lineno, query->class_string);
 }
 
+#define __outvar /* filled by callee */
 static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table 
const *dt,
- const char 
*class_string, int *class_id)
+   const char 
*class_string,
+   __outvar int *class_id)
 {
struct ddebug_class_map *map;
-   int idx;
+   int i, idx;
 
-   list_for_each_entry(map, >maps, link) {
+   for (map = dt->classes, i = 0; i < dt->num_classes; i++, map++) {
idx = match_string(map->class_names, map->length, class_string);
if (idx >= 0) {
*class_id = idx + map->base;
@@ -163,7 +166,6 @@ static struct ddebug_class_map 
*ddebug_find_valid_class(struct ddebug_table cons
return NULL;
 }
 
-#define __outvar /* filled by callee */
 /*
  * Search the tables for _ddebug's which match the given `query' and
  * apply the `flags' and `mask' to them.  Returns number of matching
@@ -1107,9 +1109,10 @@ static void *ddebug_proc_next(struct seq_file *m, void 
*p, loff_t *pos)
 
 static const char *ddebug_class_name(struct ddebug_iter *iter, struct _ddebug 
*dp)
 {
-   struct ddebug_class_map *map;
+   struct ddebug_class_map *map = iter->table->classes;
+   int i, nc = iter->table->num_classes;
 
-   list_for_each_entry(map, >table->maps, link)
+   for (i = 0; i < nc; i++, map++)
if (class_in_range(dp->class_id, map))
return map->class_names[dp->class_id - map->base];
 
@@ -1193,30 +1196,31 @@ static const struct proc_ops proc_fops = {
.proc_write = ddebug_proc_write
 };
 
-static void ddebug_attach_module_classes(struct ddebug_table *dt,
-struct ddebug_class_map *classes,
-int num_classes)
+static void ddebug_attach_module_classes(struct ddebug_table *dt, struct 
_ddebug_info *di)
 {
struct ddebug_class_map *cm;
-   int i, j, ct = 0;
+   int i, nc = 0;
 
-   for (cm = classes, i = 0; i < num_classes; i++, cm++) {
+   /*
+* Find this module's classmaps in a subrange/wholerange of
+* the 

[PATCH v3 01/19] test-dyndbg: fixup CLASSMAP usage error

2023-01-25 Thread Jim Cromie
more careful reading of test output reveals:

lib/test_dynamic_debug.c:103 [test_dynamic_debug]do_cats =pmf "doing 
categories\n"
lib/test_dynamic_debug.c:105 [test_dynamic_debug]do_cats =p "LOW msg\n" 
class:MID
lib/test_dynamic_debug.c:106 [test_dynamic_debug]do_cats =p "MID msg\n" class:HI
lib/test_dynamic_debug.c:107 [test_dynamic_debug]do_cats =_ "HI msg\n" class 
unknown, _id:13

That last line is wrong, the HI class is declared.

But the enum's 1st val (explicitly initialized) was wrong; it must be
_base, not _base+1 (a DECLARE_DYNDBG_CLASSMAP param).  So the last
enumeration exceeded the range of mapped class-id's, which triggered
the "class unknown" report.  Basically, I coded in an error, and
forgot to verify it and remove it.

RFC:

This patch fixes a bad usage of DECLARE_DYNDBG_CLASSMAP([1]), showing that
it is too error-prone.  As noted in test-dynamic-debug.c comments:

 * Using the CLASSMAP api:
 * - classmaps must have corresponding enum
 * - enum symbols must match/correlate with class-name strings in the map.
 * - base must equal enum's 1st value
 * - multiple maps must set their base to share the 0-62 class_id space !!
 *   (build-bug-on tips welcome)

Those shortcomings could largely be fixed with a __stringify_list
(which doesn't exist) used in DEFINE_DYNAMIC_DEBUG_CLASSMAP(), on
__VA_ARGS__ a 2nd time.  Then, DRM would pass DRM_UT_* ; all the
categories, in order, and not their stringifications, which created
all the usage complications above.

[1] name changed later to DYNDBG_CLASSMAP_DEFINE

Signed-off-by: Jim Cromie 
---
 lib/test_dynamic_debug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index 8dd250ad022b..a01f0193a419 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -75,7 +75,7 @@ DD_SYS_WRAP(disjoint_bits, p);
 DD_SYS_WRAP(disjoint_bits, T);
 
 /* symbolic input, independent bits */
-enum cat_disjoint_names { LOW = 11, MID, HI };
+enum cat_disjoint_names { LOW = 10, MID, HI };
 DECLARE_DYNDBG_CLASSMAP(map_disjoint_names, DD_CLASS_TYPE_DISJOINT_NAMES, 10,
"LOW", "MID", "HI");
 DD_SYS_WRAP(disjoint_names, p);
-- 
2.39.1



[PATCH v3 00/19] fix DRM_USE_DYNAMIC_DEBUG regression

2023-01-25 Thread Jim Cromie
Hi everyone,

In v6.1 DRM_USE_DYNAMIC_DEBUG=y has a regression enabling drm.debug in
drivers at modprobe.

It is due to a chicken-egg problem loading modules; on `modprobe
i915`, drm is loaded 1st, and drm/parameters/debug is set.  When
drm_debug_enabled() tested __drm_debug at runtime, this just worked.

But with DRM_USE_DYNAMIC_DEBUG=y, the runtime test is replaced with a
static_key for each drm_dbg/dyndbg callsite, enabled by dyndbg's
kparam callback on __drm_debug.  So with drm.ko loaded and initialized
before the dependent modules, their debug callsites aren't yet present
to be enabled.

STATUS - v3

not quite ready.
rebased on -rc5, hopefully applies to patchwork head 
still has RFC patch -> CI_ONLY temporary, to avoid panics
boots on my amdgpu box, drm.debug=0x3ff works at boot-time
the "toggled" warning is repeatable with test_dynamic_debug*.ko
it also occurs on amdgpu, so not just artificial.
v2 is https://lore.kernel.org/lkml/20230113193016.749791-1-jim.cro...@gmail.com/

OVERVIEW

As Jani Nikula noted rather more gently, DECLARE_DYNDBG_CLASSMAP is
error-prone enough to call broken: sharing of a common classmap
required identical classmap definitions in all modules using DRM_UT_*,
which is inherently error-prone.  IOW, it muddled the K distinction
between a (single) definition, and multiple references.

So patches 10-13 split it into:

DYNDBG_CLASSMAP_DEFINE  used once per subsystem to define each classmap.
DYNDBG_CLASSMAP_USE declare dependence on a DEFINEd classmap.

DYNDBG_CLASSMAP_DEFINE initializes the classmap, stores it into the
(existing) __dyndbg_classes section, and exports the struct var
(unlike DECLARE_DYNDBG_CLASSMAP).

DYNDBG_CLASSMAP_USE initializes a class-ref struct, containing the
user-module-name, and a ref to the exported classmap var.

The distinction allows separate treatment of classmaps and
classmap-refs, the latter getting additional behavior to propagate
parent's kparam settings to USEr. (forex: drm.debug to drm-drivers) 

. lookup the classmap defn being referenced, and its module
. find the module's kernel-params using the classmap
. propagate kparam vals into the prdgs in module being added.

It also makes the weird coordinated-changes-by-identical-classmaps
"feature" unnecessary.

Patch-10 splits the DECLARE macro into DEFINE & USE, and updates uses.

Patch-11 is the core of it; the separate treatment begins in
ddebug_add_module().  It calls ddebug_attach_module_classes(1) to
handle class-defns; this adds ddebug_attach_client_module_classes(2)
to handle class-refs, as they are found while modprobing drm
drivers. (2) calls ddebug_apply_parents_params(3) on each USEr's
referred classmap definition.

(3) scans kernel-params owned by the module DEFINEing the classmap,
either builtin or loadable, calls ddebug_match_apply_kparam(4) on each.

(4) looks for kparams which are wired to dyndbg's param-ops.  Those
params have a struct ddebug_class_param attached, which has a classmap
and a ref to a state-var (__drm_debug for DRM case).  If the kparam's
classmap is the same as from (2), then apply its state-var to the
client module by calling ddebug_apply_class_bitmap().

Patch-12 cleans up DYNDBG_CLASSMAP_USE, dropping now unneeded args.

Patch-13 improves DYNDBG_CLASSMAP_DEFINE, by accepting DRM_UT_*
symbols directly, not "DRM_UT_*" (their strings).  It adds new
include/linux/map.h to support this.

Patches 1-9 are prep, refactor, cleanup, tighten interfaces

Patches 15-18 extend test_dynamic_debug to recreate DRM's multi-module
regression; it builds both test_dynamic_debug.ko and _submod.ko, with
an ifdef to _DEFINE in the main module, and _USE in the submod.  This
gives both modules identical set of prdbgs, which is helpful for
comparing results.

here it is, working properly:

doing class DRM_UT_CORE -p
[ 9904.961750] dyndbg: read 21 bytes from userspace
[ 9904.962286] dyndbg: query 0: "class DRM_UT_CORE -p" mod:*
[ 9904.962848] dyndbg: split into words: "class" "DRM_UT_CORE" "-p"
[ 9904.963444] dyndbg: op='-' flags=0x0 maskp=0xfffe
[ 9904.963945] dyndbg: parsed: func="" file="" module="" format="" lineno=0-0 
class=DRM_UT_CORE
[ 9904.964781] dyndbg: good-class: drm.DRM_UT_CORE  module:drm nd:302 nc:1 nu:0
[ 9904.966411] dyndbg: class-ref: drm_kms_helper.DRM_UT_CORE  
module:drm_kms_helper nd:95 nc:0 nu:1
[ 9904.967265] dyndbg: class-ref: drm_display_helper.DRM_UT_CORE  
module:drm_display_helper nd:150 nc:0 nu:1
[ 9904.968349] dyndbg: class-ref: i915.DRM_UT_CORE  module:i915 nd:1659 nc:0 
nu:1
[ 9904.969801] dyndbg: class-ref: amdgpu.DRM_UT_CORE  module:amdgpu nd:4425 
nc:0 nu:1
[ 9904.977079] dyndbg: class-ref: nouveau.DRM_UT_CORE  module:nouveau nd:103 
nc:0 nu:1
[ 9904.977830] dyndbg: processed 1 queries, with 507 matches, 0 errs
doing class DRM_UT_DRIVER +p
[ 9906.151761] dyndbg: read 23 bytes from userspace
[ 9906.152241] dyndbg: query 0: "class DRM_UT_DRIVER +p" mod:*
[ 9906.152793] dyndbg: split into words: "class" "DRM_UT_DRIVER" "+p"
[ 9906.153388] dyndbg: 

Re: [PATCH] drm/nouveau/disp: Fix nvif_outp_acquire_dp() argument size

2023-01-25 Thread Kees Cook
Ping. I'll take this via my tree unless someone else wants to take it...

On Sun, Nov 27, 2022 at 10:30:41AM -0800, Kees Cook wrote:
> Both Coverity and GCC with -Wstringop-overflow noticed that
> nvif_outp_acquire_dp() accidentally defined its second argument with 1
> additional element:
> 
> drivers/gpu/drm/nouveau/dispnv50/disp.c: In function 
> 'nv50_pior_atomic_enable':
> drivers/gpu/drm/nouveau/dispnv50/disp.c:1813:17: error: 
> 'nvif_outp_acquire_dp' accessing 16 bytes in a region of size 15 
> [-Werror=stringop-overflow=]
>  1813 | nvif_outp_acquire_dp(_encoder->outp, 
> nv_encoder->dp.dpcd, 0, 0, false, false);
>   | 
> ^~~
> drivers/gpu/drm/nouveau/dispnv50/disp.c:1813:17: note: referencing argument 2 
> of type 'u8[16]' {aka 'unsigned char[16]'}
> drivers/gpu/drm/nouveau/include/nvif/outp.h:24:5: note: in a call to function 
> 'nvif_outp_acquire_dp'
>24 | int nvif_outp_acquire_dp(struct nvif_outp *, u8 dpcd[16],
>   | ^~~~
> 
> Avoid these warnings by defining the argument size using the matching
> define (DP_RECEIVER_CAP_SIZE, 15) instead of having it be a literal
> (and incorrect) value (16).
> 
> Reported-by: coverity-bot 
> Addresses-Coverity-ID: 1527269 ("Memory - corruptions")
> Addresses-Coverity-ID: 1527268 ("Memory - corruptions")
> Link: https://lore.kernel.org/lkml/202211100848.FFBA2432@keescook/
> Link: https://lore.kernel.org/lkml/202211100848.F4C2819BB@keescook/
> Fixes: 813443721331 ("drm/nouveau/disp: move DP link config into acquire")
> Cc: Ben Skeggs 
> Cc: Karol Herbst 
> Cc: Lyude Paul 
> Cc: David Airlie 
> Cc: Daniel Vetter 
> Cc: Dave Airlie 
> Cc: "Gustavo A. R. Silva" 
> Cc: dri-devel@lists.freedesktop.org
> Cc: nouv...@lists.freedesktop.org
> Signed-off-by: Kees Cook 
> ---
>  drivers/gpu/drm/nouveau/include/nvif/outp.h | 3 ++-
>  drivers/gpu/drm/nouveau/nvif/outp.c | 2 +-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h 
> b/drivers/gpu/drm/nouveau/include/nvif/outp.h
> index 45daadec3c0c..fa76a7b5e4b3 100644
> --- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
> +++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
> @@ -3,6 +3,7 @@
>  #define __NVIF_OUTP_H__
>  #include 
>  #include 
> +#include 
>  struct nvif_disp;
>  
>  struct nvif_outp {
> @@ -21,7 +22,7 @@ int nvif_outp_acquire_rgb_crt(struct nvif_outp *);
>  int nvif_outp_acquire_tmds(struct nvif_outp *, int head,
>  bool hdmi, u8 max_ac_packet, u8 rekey, u8 scdc, bool 
> hda);
>  int nvif_outp_acquire_lvds(struct nvif_outp *, bool dual, bool bpc8);
> -int nvif_outp_acquire_dp(struct nvif_outp *, u8 dpcd[16],
> +int nvif_outp_acquire_dp(struct nvif_outp *outp, u8 
> dpcd[DP_RECEIVER_CAP_SIZE],
>int link_nr, int link_bw, bool hda, bool mst);
>  void nvif_outp_release(struct nvif_outp *);
>  int nvif_outp_infoframe(struct nvif_outp *, u8 type, struct 
> nvif_outp_infoframe_v0 *, u32 size);
> diff --git a/drivers/gpu/drm/nouveau/nvif/outp.c 
> b/drivers/gpu/drm/nouveau/nvif/outp.c
> index 7da39f1eae9f..c24bc5eae3ec 100644
> --- a/drivers/gpu/drm/nouveau/nvif/outp.c
> +++ b/drivers/gpu/drm/nouveau/nvif/outp.c
> @@ -127,7 +127,7 @@ nvif_outp_acquire(struct nvif_outp *outp, u8 proto, 
> struct nvif_outp_acquire_v0
>  }
>  
>  int
> -nvif_outp_acquire_dp(struct nvif_outp *outp, u8 dpcd[16],
> +nvif_outp_acquire_dp(struct nvif_outp *outp, u8 dpcd[DP_RECEIVER_CAP_SIZE],
>int link_nr, int link_bw, bool hda, bool mst)
>  {
>   struct nvif_outp_acquire_v0 args;
> -- 
> 2.34.1
> 

-- 
Kees Cook


[PATCH 09/32] drm/amdgpu: add gfx9.4.2 hw debug mode enable and disable calls

2023-01-25 Thread Jonathan Kim
GFX9.4.2 now supports per-VMID debug mode controls registers
(SPI_GDBG_PER_VMID_CNTL).

Because the KFD lets the HWS handle PASID-VMID mapping, the KFD will
forward all debug mode setting register writes to the HWS scheduler
using a new MAP_PROCESS API, so instead of writing to registers, return
the required register values that the HWS needs to write on debug enable
and disable.

v2: add commentary on unused restore_dbg_registers for debug enable.

Signed-off-by: Jonathan Kim 
---
 .../drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c  | 43 ++-
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
index 4485bb29bec9..89868f9927ae 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
@@ -23,6 +23,44 @@
 #include "amdgpu_amdkfd.h"
 #include "amdgpu_amdkfd_arcturus.h"
 #include "amdgpu_amdkfd_gfx_v9.h"
+#include "gc/gc_9_4_2_offset.h"
+#include "gc/gc_9_4_2_sh_mask.h"
+
+/**
+ * Returns TRAP_EN, EXCP_EN and EXCP_REPLACE.
+ *
+ * restore_dbg_reisters is ignored here but is a general interface requirement
+ * for devices that support GFXOFF and where the RLC save/restore list
+ * does not support hw registers for debugging i.e. the driver has to manually
+ * initialize the debug mode registers after it has disabled GFX off during the
+ * debug session.
+ */
+static uint32_t kgd_aldebaran_enable_debug_trap(struct amdgpu_device *adev,
+   bool restore_dbg_registers,
+   uint32_t vmid)
+{
+   uint32_t data = 0;
+
+   data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 1);
+   data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_EN, 0);
+   data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_REPLACE, 0);
+
+   return data;
+}
+
+/* returns TRAP_EN, EXCP_EN and EXCP_REPLACE. */
+static uint32_t kgd_aldebaran_disable_debug_trap(struct amdgpu_device *adev,
+   bool keep_trap_enabled,
+   uint32_t vmid)
+{
+   uint32_t data = 0;
+
+   data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 
keep_trap_enabled);
+   data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_EN, 0);
+   data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_REPLACE, 0);
+
+   return data;
+}
 
 const struct kfd2kgd_calls aldebaran_kfd2kgd = {
.program_sh_mem_settings = kgd_gfx_v9_program_sh_mem_settings,
@@ -41,6 +79,7 @@ const struct kfd2kgd_calls aldebaran_kfd2kgd = {
.get_atc_vmid_pasid_mapping_info =
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
.set_vm_context_page_table_base = 
kgd_gfx_v9_set_vm_context_page_table_base,
-   .get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy,
-   .program_trap_handler_settings = 
kgd_gfx_v9_program_trap_handler_settings
+   .enable_debug_trap = kgd_aldebaran_enable_debug_trap,
+   .disable_debug_trap = kgd_aldebaran_disable_debug_trap,
+   .program_trap_handler_settings = 
kgd_gfx_v9_program_trap_handler_settings,
 };
-- 
2.25.1



Re: [PATCH v2 1/4] memcg: Track exported dma-buffers

2023-01-25 Thread T.J. Mercier
On Wed, Jan 25, 2023 at 4:05 AM Michal Hocko  wrote:
>
> On Tue 24-01-23 10:55:21, T.J. Mercier wrote:
> > On Tue, Jan 24, 2023 at 7:00 AM Michal Hocko  wrote:
> > >
> > > On Mon 23-01-23 19:17:23, T.J. Mercier wrote:
> > > > When a buffer is exported to userspace, use memcg to attribute the
> > > > buffer to the allocating cgroup until all buffer references are
> > > > released.
> > >
> > > Is there any reason why this memory cannot be charged during the
> > > allocation (__GFP_ACCOUNT used)?
> >
> > My main motivation was to keep code changes away from exporters and
> > implement the accounting in one common spot for all of them. This is a
> > bit of a carryover from a previous approach [1] where there was some
> > objection to pushing off this work onto exporters and forcing them to
> > adapt, but __GFP_ACCOUNT does seem like a smaller burden than before
> > at least initially. However in order to support charge transfer
> > between cgroups with __GFP_ACCOUNT we'd need to be able to get at the
> > pages backing dmabuf objects, and the exporters are the ones with that
> > access. Meaning I think we'd have to add some additional dma_buf_ops
> > to achieve that, which was the objection from [1].
> >
> > [1] 
> > https://lore.kernel.org/lkml/5cc27a05-8131-ce9b-dea1-5c75e9942...@amd.com/
> >
> > >
> > > Also you do charge and account the memory but underlying pages do not
> > > know about their memcg (this is normally done with commit_charge for
> > > user mapped pages). This would become a problem if the memory is
> > > migrated for example.
> >
> > Hmm, what problem do you see in this situation? If the backing pages
> > are to be migrated that requires the cooperation of the exporter,
> > which currently has no influence on how the cgroup charging is done
> > and that seems fine. (Unless you mean migrating the charge across
> > cgroups? In which case that's the next patch.)
>
> My main concern was that page migration could lose the external tracking
> without some additional steps on the dmabuf front.
>
I see, yes that would be true if an exporter moves data around between
system memory and VRAM for example. (I think TTM does this sort of
thing, but not sure if that's actually within a single dma buffer.)
VRAM feels like it maybe doesn't belong in memcg, yet it would still
be charged there under this series right now. I don't really see a way
around this except to involve the exporters directly in the accounting
(or don't attempt to distinguish between types of memory).

> > > This also means that you have to maintain memcg
> > > reference outside of the memcg proper which is not really nice either.
> > > This mimicks tcp kmem limit implementation which I really have to say I
> > > am not a great fan of and this pattern shouldn't be coppied.
> > >
> > Ah, what can I say. This way looked simple to me. I think otherwise
> > we're back to making all exporters do more stuff for the accounting.
> >
> > > Also you are not really saying anything about the oom behavior. With
> > > this implementation the kernel will try to reclaim the memory and even
> > > trigger the memcg oom killer if the request size is <= 8 pages. Is this
> > > a desirable behavior?
> >
> > It will try to reclaim some memory, but not the dmabuf pages right?
> > Not *yet* anyway. This behavior sounds expected to me.
>
> Yes, we have discussed that shrinkers will follow up later which is
> fine. The question is how much reclaim actually makes sense at this
> stage. Charging interface usually copes with sizes resulting from
> allocation requests (so usually 1< batch charge like implemented here could easily be 100s of MBs and it is
> much harder to define reclaim targets for. At least that is something
> the memcg charging hasn't really considered yet.  Maybe the existing
> try_charge implementation can cope with that just fine but it would be
> really great to have the expected behavior described.
>
> E.g. should be memcg OOM killer be invoked? Should reclaim really target
> regular memory at all costs or just a lightweight memory reclaim is
> preferred (is the dmabuf charge failure an expensive operation wrt.
> memory refault due to reclaim).

Ah, in my experience very large individual buffers like that are rare.
Cumulative system-wide usage might reach 100s of megs or more spread
across many buffers. On my phone the majority of buffer sizes are 4
pages or less, but there are a few that reach into the tens of megs.
But now I see your point. I still think that where a memcg limit is
exceeded and we can't reclaim enough as a result of a new dmabuf
allocation, we should see a memcg OOM kill. Sounds like you are
looking for that to be written down, so I'll try to find a place for
that.

Part of the motivation for this accounting is to eventually have a
well defined limit for applications to know how much more they can
allocate. So where buffer size or number of buffers is a flexible
variable, I'd like to see an application checking this limit 

Re: [PATCH v2 1/4] memcg: Track exported dma-buffers

2023-01-25 Thread T.J. Mercier
On Wed, Jan 25, 2023 at 9:31 AM Tvrtko Ursulin
 wrote:
>
>
> Hi,
>
> On 25/01/2023 11:52, Michal Hocko wrote:
> > On Tue 24-01-23 19:46:28, Shakeel Butt wrote:
> >> On Tue, Jan 24, 2023 at 03:59:58PM +0100, Michal Hocko wrote:
> >>> On Mon 23-01-23 19:17:23, T.J. Mercier wrote:
>  When a buffer is exported to userspace, use memcg to attribute the
>  buffer to the allocating cgroup until all buffer references are
>  released.
> >>>
> >>> Is there any reason why this memory cannot be charged during the
> >>> allocation (__GFP_ACCOUNT used)?
> >>> Also you do charge and account the memory but underlying pages do not
> >>> know about their memcg (this is normally done with commit_charge for
> >>> user mapped pages). This would become a problem if the memory is
> >>> migrated for example.
> >>
> >> I don't think this is movable memory.
> >>
> >>> This also means that you have to maintain memcg
> >>> reference outside of the memcg proper which is not really nice either.
> >>> This mimicks tcp kmem limit implementation which I really have to say I
> >>> am not a great fan of and this pattern shouldn't be coppied.
> >>>
> >>
> >> I think we should keep the discussion on technical merits instead of
> >> personal perference. To me using skmem like interface is totally fine
> >> but the pros/cons need to be very explicit and the clear reasons to
> >> select that option should be included.
> >
> > I do agree with that. I didn't want sound to be personal wrt tcp kmem
> > accounting but the overall code maintenance cost is higher because
> > of how tcp take on accounting differs from anything else in the memcg
> > proper. I would prefer to not grow another example like that.
> >
> >> To me there are two options:
> >>
> >> 1. Using skmem like interface as this patch series:
> >>
> >> The main pros of this option is that it is very simple. Let me list down
> >> the cons of this approach:
> >>
> >> a. There is time window between the actual memory allocation/free and
> >> the charge and uncharge and [un]charge happen when the whole memory is
> >> allocated or freed. I think for the charge path that might not be a big
> >> issue but on the uncharge, this can cause issues. The application and
> >> the potential shrinkers have freed some of this dmabuf memory but until
> >> the whole dmabuf is freed, the memcg uncharge will not happen. This can
> >> consequences on reclaim and oom behavior of the application.
> >>
> >> b. Due to the usage model i.e. a central daemon allocating the dmabuf
> >> memory upfront, there is a requirement to have a memcg charge transfer
> >> functionality to transfer the charge from the central daemon to the
> >> client applications. This does introduce complexity and avenues of weird
> >> reclaim and oom behavior.
> >>
> >>
> >> 2. Allocate and charge the memory on page fault by actual user
> >>
> >> In this approach, the memory is not allocated upfront by the central
> >> daemon but rather on the page fault by the client application and the
> >> memcg charge happen at the same time.
> >>
> >> The only cons I can think of is this approach is more involved and may
> >> need some clever tricks to track the page on the free patch i.e. we to
> >> decrement the dmabuf memcg stat on free path. Maybe a page flag.
> >>
> >> The pros of this approach is there is no need have a charge transfer
> >> functionality and the charge/uncharge being closely tied to the actual
> >> memory allocation and free.
> >>
> >> Personally I would prefer the second approach but I don't want to just
> >> block this work if the dmabuf folks are ok with the cons mentioned of
> >> the first approach.
> >
> > I am not familiar with dmabuf internals to judge complexity on their end
> > but I fully agree that charge-when-used is much more easier to reason
> > about and it should have less subtle surprises.
>
> Disclaimer that I don't seem to see patches 3&4 on dri-devel so maybe I
> am missing something, but in principle yes, I agree that the 2nd option
> (charge the user, not exporter) should be preferred. Thing being that at
> export time there may not be any backing store allocated, plus if the
> series is restricting the charge transfer to just Android clients then
> it seems it has the potential to miss many other use cases. At least
> needs to outline a description on how the feature will be useful outside
> Android.
>
There is no restriction like that. It's available to anybody who wants
to call dma_buf_charge_transfer if they actually have a need for that,
which I don't really expect to be common since most users/owners of
the buffers will be the ones causing the export in the first place.
It's just not like that on Android with the extra allocator process in
the middle most of the time.

> Also stepping back for a moment - is a new memory category really
> needed, versus perhaps attempting to charge the actual backing store
> memory to the correct client? (There might have been many past
> discussions on this so 

[PATCH v3 08/10] drm/fbdev-generic: Minimize client unregistering

2023-01-25 Thread Thomas Zimmermann
For uninitialized framebuffers, only release the DRM client and
free the fbdev memory. Do not attempt to clean up the framebuffer.

DRM fbdev clients have a two-step initialization: first create
the DRM client; then create the framebuffer device on the first
successful hotplug event. In cases where the client never creates
the framebuffer, only the client state needs to be released. We
can detect which case it is, full or client-only cleanup, by
looking at the presence of fb_helper's info field.

v3:
* fix typo in commit message (Javier)
* release client before unpreparing fbdev
v2:
* remove test for (fbi != NULL) in drm_fbdev_cleanup() (Sam)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/drm_fbdev_generic.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_fbdev_generic.c 
b/drivers/gpu/drm/drm_fbdev_generic.c
index dd8be5e0f271..a9c519001019 100644
--- a/drivers/gpu/drm/drm_fbdev_generic.c
+++ b/drivers/gpu/drm/drm_fbdev_generic.c
@@ -51,12 +51,10 @@ static void drm_fbdev_cleanup(struct drm_fb_helper 
*fb_helper)
if (!fb_helper->dev)
return;
 
-   if (fbi) {
-   if (fbi->fbdefio)
-   fb_deferred_io_cleanup(fbi);
-   if (drm_fbdev_use_shadow_fb(fb_helper))
-   shadow = fbi->screen_buffer;
-   }
+   if (fbi->fbdefio)
+   fb_deferred_io_cleanup(fbi);
+   if (drm_fbdev_use_shadow_fb(fb_helper))
+   shadow = fbi->screen_buffer;
 
drm_fb_helper_fini(fb_helper);
 
@@ -362,11 +360,13 @@ static void drm_fbdev_client_unregister(struct 
drm_client_dev *client)
 {
struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
 
-   if (fb_helper->info)
-   /* drm_fbdev_fb_destroy() takes care of cleanup */
+   if (fb_helper->info) {
drm_fb_helper_unregister_info(fb_helper);
-   else
-   drm_fbdev_release(fb_helper);
+   } else {
+   drm_client_release(_helper->client);
+   drm_fb_helper_unprepare(fb_helper);
+   kfree(fb_helper);
+   }
 }
 
 static int drm_fbdev_client_restore(struct drm_client_dev *client)
-- 
2.39.0



[PATCH v3 07/10] drm/fbdev-generic: Minimize hotplug error handling

2023-01-25 Thread Thomas Zimmermann
Call drm_fb_helper_fini() in the generic-fbdev hotplug helper
to revert the effects of drm_fb_helper_init(). No full cleanup
is required.

v3:
* fix error in commit message (Javier)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/drm_fbdev_generic.c | 14 +-
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_fbdev_generic.c 
b/drivers/gpu/drm/drm_fbdev_generic.c
index 6ae014040df3..dd8be5e0f271 100644
--- a/drivers/gpu/drm/drm_fbdev_generic.c
+++ b/drivers/gpu/drm/drm_fbdev_generic.c
@@ -387,25 +387,21 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev 
*client)
 
ret = drm_fb_helper_init(dev, fb_helper);
if (ret)
-   goto err;
+   goto err_drm_err;
 
if (!drm_drv_uses_atomic_modeset(dev))
drm_helper_disable_unused_functions(dev);
 
ret = drm_fb_helper_initial_config(fb_helper);
if (ret)
-   goto err_cleanup;
+   goto err_drm_fb_helper_fini;
 
return 0;
 
-err_cleanup:
-   drm_fbdev_cleanup(fb_helper);
-err:
-   fb_helper->dev = NULL;
-   fb_helper->info = NULL;
-
+err_drm_fb_helper_fini:
+   drm_fb_helper_fini(fb_helper);
+err_drm_err:
drm_err(dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", 
ret);
-
return ret;
 }
 
-- 
2.39.0



[PATCH v3 09/10] drm/fbdev-generic: Inline clean-up helpers into drm_fbdev_fb_destroy()

2023-01-25 Thread Thomas Zimmermann
The fbdev framebuffer cleanup in drm_fbdev_fb_destroy() calls
drm_fbdev_release() and drm_fbdev_cleanup(). Inline both into the
caller. No functional changes.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/drm_fbdev_generic.c | 17 ++---
 1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/drm_fbdev_generic.c 
b/drivers/gpu/drm/drm_fbdev_generic.c
index a9c519001019..68ce652e3a14 100644
--- a/drivers/gpu/drm/drm_fbdev_generic.c
+++ b/drivers/gpu/drm/drm_fbdev_generic.c
@@ -43,8 +43,9 @@ static int drm_fbdev_fb_release(struct fb_info *info, int 
user)
return 0;
 }
 
-static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper)
+static void drm_fbdev_fb_destroy(struct fb_info *info)
 {
+   struct drm_fb_helper *fb_helper = info->par;
struct fb_info *fbi = fb_helper->info;
void *shadow = NULL;
 
@@ -64,24 +65,10 @@ static void drm_fbdev_cleanup(struct drm_fb_helper 
*fb_helper)
drm_client_buffer_vunmap(fb_helper->buffer);
 
drm_client_framebuffer_delete(fb_helper->buffer);
-}
-
-static void drm_fbdev_release(struct drm_fb_helper *fb_helper)
-{
-   drm_fbdev_cleanup(fb_helper);
drm_client_release(_helper->client);
kfree(fb_helper);
 }
 
-/*
- * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of
- * unregister_framebuffer() or fb_release().
- */
-static void drm_fbdev_fb_destroy(struct fb_info *info)
-{
-   drm_fbdev_release(info->par);
-}
-
 static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
struct drm_fb_helper *fb_helper = info->par;
-- 
2.39.0



[PATCH v3 06/10] drm/fb-helper: Initialize fb-helper's preferred BPP in prepare function

2023-01-25 Thread Thomas Zimmermann
Initialize the fb-helper's preferred_bpp field early from within
drm_fb_helper_prepare(); instead of the later client hot-plugging
callback. This simplifies the generic fbdev setup function.

No real changes, but all drivers' fbdev code has to be adapted.

v3:
* build with CONFIG_DRM_FBDEV_EMULATION unset (kernel test bot)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/armada/armada_fbdev.c  |  4 ++--
 drivers/gpu/drm/drm_fb_helper.c| 22 ++
 drivers/gpu/drm/drm_fbdev_generic.c| 19 ++-
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c  |  4 ++--
 drivers/gpu/drm/gma500/framebuffer.c   |  4 ++--
 drivers/gpu/drm/i915/display/intel_fbdev.c | 11 ++-
 drivers/gpu/drm/msm/msm_fbdev.c|  4 ++--
 drivers/gpu/drm/omapdrm/omap_fbdev.c   |  4 ++--
 drivers/gpu/drm/radeon/radeon_fb.c |  4 ++--
 drivers/gpu/drm/tegra/fb.c |  7 +++
 include/drm/drm_fb_helper.h| 11 ++-
 11 files changed, 47 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_fbdev.c 
b/drivers/gpu/drm/armada/armada_fbdev.c
index 584cee123bd8..07e410c62b7a 100644
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -129,7 +129,7 @@ int armada_fbdev_init(struct drm_device *dev)
 
priv->fbdev = fbh;
 
-   drm_fb_helper_prepare(dev, fbh, _fb_helper_funcs);
+   drm_fb_helper_prepare(dev, fbh, 32, _fb_helper_funcs);
 
ret = drm_fb_helper_init(dev, fbh);
if (ret) {
@@ -137,7 +137,7 @@ int armada_fbdev_init(struct drm_device *dev)
goto err_fb_helper;
}
 
-   ret = drm_fb_helper_initial_config(fbh, 32);
+   ret = drm_fb_helper_initial_config(fbh);
if (ret) {
DRM_ERROR("failed to set initial config\n");
goto err_fb_setup;
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 258103d317ac..28c428e9c530 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -416,14 +416,30 @@ static void drm_fb_helper_damage_work(struct work_struct 
*work)
  * drm_fb_helper_prepare - setup a drm_fb_helper structure
  * @dev: DRM device
  * @helper: driver-allocated fbdev helper structure to set up
+ * @preferred_bpp: Preferred bits per pixel for the device.
  * @funcs: pointer to structure of functions associate with this helper
  *
  * Sets up the bare minimum to make the framebuffer helper usable. This is
  * useful to implement race-free initialization of the polling helpers.
  */
 void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper 
*helper,
+  unsigned int preferred_bpp,
   const struct drm_fb_helper_funcs *funcs)
 {
+   /*
+* Pick a preferred bpp of 32 if no value has been given. This
+* will select XRGB for the framebuffer formats. All drivers
+* have to support XRGB for backwards compatibility with legacy
+* userspace, so it's the safe choice here.
+*
+* TODO: Replace struct drm_mode_config.preferred_depth and this
+*   bpp value with a preferred format that is given as struct
+*   drm_format_info. Then derive all other values from the
+*   format.
+*/
+   if (!preferred_bpp)
+   preferred_bpp = 32;
+
INIT_LIST_HEAD(>kernel_fb_list);
spin_lock_init(>damage_lock);
INIT_WORK(>resume_work, drm_fb_helper_resume_worker);
@@ -432,6 +448,7 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct 
drm_fb_helper *helper,
mutex_init(>lock);
helper->funcs = funcs;
helper->dev = dev;
+   helper->preferred_bpp = preferred_bpp;
 }
 EXPORT_SYMBOL(drm_fb_helper_prepare);
 
@@ -2183,7 +2200,6 @@ __drm_fb_helper_initial_config_and_unlock(struct 
drm_fb_helper *fb_helper)
 /**
  * drm_fb_helper_initial_config - setup a sane initial connector configuration
  * @fb_helper: fb_helper device struct
- * @bpp_sel: bpp value to use for the framebuffer configuration
  *
  * Scans the CRTCs and connectors and tries to put together an initial setup.
  * At the moment, this is a cloned configuration across all heads with
@@ -2221,15 +2237,13 @@ __drm_fb_helper_initial_config_and_unlock(struct 
drm_fb_helper *fb_helper)
  * RETURNS:
  * Zero if everything went ok, nonzero otherwise.
  */
-int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
+int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)
 {
int ret;
 
if (!drm_fbdev_emulation)
return 0;
 
-   fb_helper->preferred_bpp = bpp_sel;
-
mutex_lock(_helper->lock);
ret = __drm_fb_helper_initial_config_and_unlock(fb_helper);
 
diff --git a/drivers/gpu/drm/drm_fbdev_generic.c 
b/drivers/gpu/drm/drm_fbdev_generic.c
index 

[PATCH v3 10/10] drm/fbdev-generic: Rename struct fb_info 'fbi' to 'info'

2023-01-25 Thread Thomas Zimmermann
The generic fbdev emulation names variables of type struct fb_info
both 'fbi' and 'info'. The latter seems to be more common in fbdev
code, so name fbi accordingly.

Also replace the duplicate variable in drm_fbdev_fb_destroy().

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/drm_fbdev_generic.c | 47 ++---
 1 file changed, 23 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_fbdev_generic.c 
b/drivers/gpu/drm/drm_fbdev_generic.c
index 68ce652e3a14..43f94aa9e015 100644
--- a/drivers/gpu/drm/drm_fbdev_generic.c
+++ b/drivers/gpu/drm/drm_fbdev_generic.c
@@ -46,16 +46,15 @@ static int drm_fbdev_fb_release(struct fb_info *info, int 
user)
 static void drm_fbdev_fb_destroy(struct fb_info *info)
 {
struct drm_fb_helper *fb_helper = info->par;
-   struct fb_info *fbi = fb_helper->info;
void *shadow = NULL;
 
if (!fb_helper->dev)
return;
 
-   if (fbi->fbdefio)
-   fb_deferred_io_cleanup(fbi);
+   if (info->fbdefio)
+   fb_deferred_io_cleanup(info);
if (drm_fbdev_use_shadow_fb(fb_helper))
-   shadow = fbi->screen_buffer;
+   shadow = info->screen_buffer;
 
drm_fb_helper_fini(fb_helper);
 
@@ -171,7 +170,7 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper 
*fb_helper,
struct drm_device *dev = fb_helper->dev;
struct drm_client_buffer *buffer;
struct drm_framebuffer *fb;
-   struct fb_info *fbi;
+   struct fb_info *info;
u32 format;
struct iosys_map map;
int ret;
@@ -190,35 +189,35 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper 
*fb_helper,
fb_helper->fb = buffer->fb;
fb = buffer->fb;
 
-   fbi = drm_fb_helper_alloc_info(fb_helper);
-   if (IS_ERR(fbi))
-   return PTR_ERR(fbi);
+   info = drm_fb_helper_alloc_info(fb_helper);
+   if (IS_ERR(info))
+   return PTR_ERR(info);
 
-   fbi->fbops = _fbdev_fb_ops;
-   fbi->screen_size = sizes->surface_height * fb->pitches[0];
-   fbi->fix.smem_len = fbi->screen_size;
-   fbi->flags = FBINFO_DEFAULT;
+   info->fbops = _fbdev_fb_ops;
+   info->screen_size = sizes->surface_height * fb->pitches[0];
+   info->fix.smem_len = info->screen_size;
+   info->flags = FBINFO_DEFAULT;
 
-   drm_fb_helper_fill_info(fbi, fb_helper, sizes);
+   drm_fb_helper_fill_info(info, fb_helper, sizes);
 
if (drm_fbdev_use_shadow_fb(fb_helper)) {
-   fbi->screen_buffer = vzalloc(fbi->screen_size);
-   if (!fbi->screen_buffer)
+   info->screen_buffer = vzalloc(info->screen_size);
+   if (!info->screen_buffer)
return -ENOMEM;
-   fbi->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;
+   info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;
 
-   fbi->fbdefio = _fbdev_defio;
-   fb_deferred_io_init(fbi);
+   info->fbdefio = _fbdev_defio;
+   fb_deferred_io_init(info);
} else {
/* buffer is mapped for HW framebuffer */
ret = drm_client_buffer_vmap(fb_helper->buffer, );
if (ret)
return ret;
if (map.is_iomem) {
-   fbi->screen_base = map.vaddr_iomem;
+   info->screen_base = map.vaddr_iomem;
} else {
-   fbi->screen_buffer = map.vaddr;
-   fbi->flags |= FBINFO_VIRTFB;
+   info->screen_buffer = map.vaddr;
+   info->flags |= FBINFO_VIRTFB;
}
 
/*
@@ -227,10 +226,10 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper 
*fb_helper,
 * case.
 */
 #if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM)
-   if (fb_helper->hint_leak_smem_start && fbi->fix.smem_start == 0 
&&
+   if (fb_helper->hint_leak_smem_start && info->fix.smem_start == 
0 &&
!drm_WARN_ON_ONCE(dev, map.is_iomem))
-   fbi->fix.smem_start =
-   page_to_phys(virt_to_page(fbi->screen_buffer));
+   info->fix.smem_start =
+   page_to_phys(virt_to_page(info->screen_buffer));
 #endif
}
 
-- 
2.39.0



[PATCH v3 03/10] drm/fb-helper: Introduce drm_fb_helper_unprepare()

2023-01-25 Thread Thomas Zimmermann
Move the fb-helper clean-up code into drm_fb_helper_unprepare(). No
functional changes.

v2:
* declare as static inline (kernel test robot)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/drm_fb_helper.c | 14 +-
 include/drm/drm_fb_helper.h |  5 +
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index c5c13e192b64..4379bcd7718b 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -435,6 +435,18 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct 
drm_fb_helper *helper,
 }
 EXPORT_SYMBOL(drm_fb_helper_prepare);
 
+/**
+ * drm_fb_helper_unprepare - clean up a drm_fb_helper structure
+ * @fb_helper: driver-allocated fbdev helper structure to set up
+ *
+ * Cleans up the framebuffer helper. Inverse of drm_fb_helper_prepare().
+ */
+void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper)
+{
+   mutex_destroy(_helper->lock);
+}
+EXPORT_SYMBOL(drm_fb_helper_unprepare);
+
 /**
  * drm_fb_helper_init - initialize a  drm_fb_helper
  * @dev: drm device
@@ -561,7 +573,7 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
}
mutex_unlock(_fb_helper_lock);
 
-   mutex_destroy(_helper->lock);
+   drm_fb_helper_unprepare(fb_helper);
 
if (!fb_helper->client.funcs)
drm_client_release(_helper->client);
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index f443e1f11654..39710c570a04 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -230,6 +230,7 @@ drm_fb_helper_from_client(struct drm_client_dev *client)
 #ifdef CONFIG_DRM_FBDEV_EMULATION
 void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper 
*helper,
   const struct drm_fb_helper_funcs *funcs);
+void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper);
 int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *helper);
 void drm_fb_helper_fini(struct drm_fb_helper *helper);
 int drm_fb_helper_blank(int blank, struct fb_info *info);
@@ -296,6 +297,10 @@ static inline void drm_fb_helper_prepare(struct drm_device 
*dev,
 {
 }
 
+static inline void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper)
+{
+}
+
 static inline int drm_fb_helper_init(struct drm_device *dev,
   struct drm_fb_helper *helper)
 {
-- 
2.39.0



[PATCH v3 00/10] drm/fb-helper: Various cleanups

2023-01-25 Thread Thomas Zimmermann
Add various cleanups and changes to DRM's fbdev helpers and the
generic fbdev emulation. There's no clear theme here, just lots
of small things that need to be updated.
 
In the end, the code will better reflect which parts are in the 
DRM client, which is fbdev emulation, and which are shared fbdev
helpers.

v3:
* various minor fixes (Javier))
* build with CONFIG_DRM_FBDEV_EMULATION unset (kernel test robot)
v2:
* cleanups in drm_fbdev_fb_destroy() (Sam)
* fix declaration of drm_fb_helper_unprepare()

Thomas Zimmermann (10):
  drm/client: Test for connectors before sending hotplug event
  drm/client: Add hotplug_failed flag
  drm/fb-helper: Introduce drm_fb_helper_unprepare()
  drm/fbdev-generic: Initialize fb-helper structure in generic setup
  drm/fb-helper: Remove preferred_bpp parameter from fbdev internals
  drm/fb-helper: Initialize fb-helper's preferred BPP in prepare
function
  drm/fbdev-generic: Minimize hotplug error handling
  drm/fbdev-generic: Minimize client unregistering
  drm/fbdev-generic: Inline clean-up helpers into drm_fbdev_fb_destroy()
  drm/fbdev-generic: Rename struct fb_info 'fbi' to 'info'

 drivers/gpu/drm/armada/armada_fbdev.c  |   4 +-
 drivers/gpu/drm/drm_client.c   |  10 ++
 drivers/gpu/drm/drm_fb_helper.c|  58 ++---
 drivers/gpu/drm/drm_fbdev_generic.c| 131 -
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c  |   4 +-
 drivers/gpu/drm/gma500/framebuffer.c   |   4 +-
 drivers/gpu/drm/i915/display/intel_fbdev.c |  11 +-
 drivers/gpu/drm/msm/msm_fbdev.c|   4 +-
 drivers/gpu/drm/omapdrm/omap_fbdev.c   |   4 +-
 drivers/gpu/drm/radeon/radeon_fb.c |   4 +-
 drivers/gpu/drm/tegra/fb.c |   7 +-
 include/drm/drm_client.h   |   8 ++
 include/drm/drm_fb_helper.h|  16 ++-
 13 files changed, 138 insertions(+), 127 deletions(-)


base-commit: 7d3e7f64a42d66ba8da6e7b66a8d85457ef84570
-- 
2.39.0



  1   2   3   >