[Intel-gfx] ✓ Fi.CI.IGT: success for Update AUX invalidation sequence (rev2)

2023-06-27 Thread Patchwork
== Series Details ==

Series: Update AUX invalidation sequence (rev2)
URL   : https://patchwork.freedesktop.org/series/119798/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_13328_full -> Patchwork_119798v2_full


Summary
---

  **SUCCESS**

  No regressions found.

  

Participating hosts (9 -> 9)
--

  No changes in participating hosts

New tests
-

  New tests have been introduced between CI_DRM_13328_full and 
Patchwork_119798v2_full:

### New IGT tests (29) ###

  * igt@kms_cursor_crc@cursor-alpha-opaque@pipe-a-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_cursor_crc@cursor-alpha-opaque@pipe-d-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_cursor_crc@cursor-alpha-transparent@pipe-a-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_cursor_crc@cursor-alpha-transparent@pipe-d-hdmi-a-1:
- Statuses : 2 pass(s)
- Exec time: [0.0] s

  * igt@kms_cursor_crc@cursor-alpha-transparent@pipe-d-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_cursor_crc@cursor-dpms@pipe-d-hdmi-a-1:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_cursor_crc@cursor-size-change@pipe-a-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_cursor_crc@cursor-size-change@pipe-d-hdmi-a-1:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_cursor_crc@cursor-size-change@pipe-d-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_cursor_crc@cursor-suspend@pipe-d-hdmi-a-1:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@disable-crc-after-crtc@pipe-a-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@disable-crc-after-crtc@pipe-b-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@disable-crc-after-crtc@pipe-c-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@disable-crc-after-crtc@pipe-d-hdmi-a-1:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@disable-crc-after-crtc@pipe-d-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@hang-read-crc@pipe-a-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@hang-read-crc@pipe-b-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@hang-read-crc@pipe-c-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-hdmi-a-1:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@hang-read-crc@pipe-d-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@nonblocking-crc-frame-sequence@pipe-d-hdmi-a-1:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@nonblocking-crc@pipe-d-hdmi-a-1:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-d-hdmi-a-1:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@read-crc@pipe-d-hdmi-a-1:
- Statuses : 2 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@suspend-read-crc@pipe-a-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@suspend-read-crc@pipe-b-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@suspend-read-crc@pipe-c-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@suspend-read-crc@pipe-d-hdmi-a-1:
- Statuses : 2 pass(s)
- Exec time: [0.0] s

  * igt@kms_pipe_crc_basic@suspend-read-crc@pipe-d-hdmi-a-3:
- Statuses : 1 pass(s)
- Exec time: [0.0] s

  

Known issues


  Here are the changes found in Patchwork_119798v2_full that come from known 
issues:

### IGT changes ###

 Issues hit 

  * igt@gem_create@create-ext-set-pat:
- shard-glk:  NOTRUN -> [FAIL][1] ([i915#8621])
   [1]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/shard-glk4/igt@gem_cre...@create-ext-set-pat.html

  * igt@gem_exec_fair@basic-flow@rcs0:
- shard-tglu: [PASS][2] -> [FAIL][3] ([i915#2842])
   [2]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/shard-tglu-2/igt@gem_exec_fair@basic-f...@rcs0.html
   [3]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/shard-tglu-5/igt@gem_exec_fair@basic-f...@rcs0.html

  * igt@gem_exec_fair@basic-none@vecs0:
- shard-rkl:  [PASS][4] -> [FAIL][5] ([i915#2842]) +1 similar issue
   [4]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/shard-rkl-2/igt@gem_exec_fair@basic-n...@vecs0.html
   [5]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/shard-rkl-2/igt@gem_exec_fair@basic-n...@vecs0.html

  * 

Re: [Intel-gfx] [PATCH v2 6/6] drm/i915/gt: Remove bogus comment on IVB_FBC_RT_BASE_UPPER

2023-06-27 Thread Lucas De Marchi

On Tue, Jun 27, 2023 at 11:30:26AM -0700, Kenneth Graunke wrote:

On Saturday, June 24, 2023 10:17:57 AM PDT Lucas De Marchi wrote:

The comment on the parameter being 0 to avoid the read back doesn't
apply as this is not a call to wa_mcr_add(), but rather to
wa_mcr_clr_set(). So, this register is actually checked and it's
according to the Bspec that the register is RW, not RO.


I think you mean wa_add and wa_write_clr_set here (not mcr).

One thing I've been confused about while reading this code:

static void
wa_write_clr_set(struct i915_wa_list *wal, i915_reg_t reg, u32 clear, u32 set)
{
   wa_add(wal, reg, clear, set, clear, false);
}

The second to last parameter is read_mask aka wa->read.  We're
initializing it to the...bits to clear.  (I would think it should be
(clear | set) to pick up all modified bits.)

wa_verify seems to balk at ((cur ^ wa->set) & wa->read).  But...if
wa->read is just the clear mask, that wouldn't actually verify that
any bits were set at all.  Or am I misunderstanding something?

If not, we may be failing to verify the majority of our workarounds :(


I can see it failing in some cases, but it should pass in the majority.
I think there's an issue when the clr bits are not a super set of the
set bits. For example, this works:

clr=0xf, set=1

This is what happens when we are setting a field. However it would fail
to verify for cases in which we have, .e.g

clr=0x1, set=0, i.e. we are just clearing one bit. Since wa->read in
this case would be 0, it wouldn't matter if cur is 0 or 1. It seems like
commit eeec73f8a4a4 ("drm/i915/gt: Skip rmw for masked registers")
is the one who broke it. Setting read_mask to set | clr seems to
suffice as then we would get any inconsistencies between what was read
from the bits that should be set.

thanks
Lucas De Marchi




Signed-off-by: Lucas De Marchi 
---
 drivers/gpu/drm/i915/gt/intel_workarounds.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c 
b/drivers/gpu/drm/i915/gt/intel_workarounds.c
index 848519b58e45..5fe85fad91c1 100644
--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
@@ -666,7 +666,7 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs 
*engine,
/* Wa_1604278689:icl,ehl */
wa_write(wal, IVB_FBC_RT_BASE, 0x & ~ILK_FBC_RT_VALID);
wa_write_clr_set(wal, IVB_FBC_RT_BASE_UPPER,
-0, /* write-only register; skip validation */
+0,
 0x);

/* Wa_1406306137:icl,ehl */


In this particular example, since clear bits are 0, I don't think any
verification is happening at all.

--Ken





Re: [Intel-gfx] [PATCH v13 22/22] docs: vfio: Add vfio device cdev description

2023-06-27 Thread Liu, Yi L
> From: Alex Williamson 
> Sent: Wednesday, June 28, 2023 1:35 AM

[The Cc list gets broken in the reply from Alex to Jason, here I reply to
Alex's email with the Cc list fixed. @Alex, seems like the same symptom
with last time, do you have any idea on it?]

> On Tue, 27 Jun 2023 13:12:14 -0300
> Jason Gunthorpe  wrote:
> 
> > On Tue, Jun 27, 2023 at 08:54:33AM +, Liu, Yi L wrote:
> > > > From: Alex Williamson 
> > > > Sent: Thursday, June 22, 2023 5:54 AM
> > > >
> > > > On Fri, 16 Jun 2023 02:39:46 -0700
> > > > Yi Liu  wrote:
> > >
> > > > > +VFIO device cdev doesn't rely on VFIO group/container/iommu drivers.
> > > > > +Hence those modules can be fully compiled out in an environment
> > > > > +where no legacy VFIO application exists.
> > > > > +
> > > > > +So far SPAPR does not support IOMMUFD yet.  So it cannot support 
> > > > > device
> > > > > +cdev either.
> > > >
> > > > Why isn´t this enforced via Kconfig?  At the vfio level we could simply
> > > > add the following in patch 17/:
> > > >
> > > > config VFIO_DEVICE_CDEV
> > > > bool "Support for the VFIO cdev /dev/vfio/devices/vfioX"
> > > > depends on IOMMUFD && !SPAPR_TCE_IOMMU
> > > >^^^
> > > >
> > > > Or if Jason wants, IOMMUFD could depend on !SPAPR_TCE_IOMMU for now and
> > > > the existing Kconfig options would exclude it.  If we know it doesn't
> > > > work, let's not put the burden on the user to figure that out.  A
> > > > follow-up patch for this would be fine if there's no other reason to
> > > > respin the series.
> > >
> > > @Jason,
> > > How about your opinion? Seems reasonable to make IOMMUFD
> > > depend on !SPAPR_TCE_IOMMU. Is it?
> >
> > The right kconfig would be to list all the iommu drivers that can
> > support iommufd and allow it to be selected if any of them are
> > enabled.
> >
> > This seems too complex to bother with, so I like Alex's version above..
> >
> > > > Otherwise the series is looking pretty good to me.  It still requires
> > > > some reviews/acks in the iommufd space and it would be good to see more
> > > > reviews for the remainder given the amount of collaboration here.
> > > >
> > > > I'm out for the rest of the week, but I'll leave open accepting this
> > > > and the hot-reset series next week for the merge window.  Thanks,
> > >
> > > @Alex,
> > > Given Jason's remarks on cdev v12, I've already got a new version as 
> > > below.
> > > I can post it once the above kconfig open is closed.
> >
> > I think we don't need to bend the rules, Linus would not be happy to
> > see 30 major patches that never hit linux-next at all.
> >
> > I'm happy if we put it on a branch at RC1 and merge it to the vfio &
> > iommufd trees, it is functionally the same outcome in the same time
> > frame.
> 
> Not sure I'm clear on the plan.  My intention would have been to apply
> v14 to my next branch, make sure it did see linux-next exposure,
> and send a pull request for rc1 next week.
> 
> Are you suggesting a post-merge-window pull request for v6.5 (also
> frowned on) or are you suggesting that it simmers in both our next
> branches until v6.6?  Thanks,

It appears to me the latter one. When 6.5-rc1 is released, we immediately
apply the hot-reset and cdev series onto it and put it in a shared tree to
assist the other iommufd feature development (e.g. nesting). Jason, is it?

Regards,
Yi Liu


Re: [Intel-gfx] [PATCH v13 22/22] docs: vfio: Add vfio device cdev description

2023-06-27 Thread Liu, Yi L
> From: Jason Gunthorpe 
> Sent: Wednesday, June 28, 2023 12:12 AM
> 
> On Tue, Jun 27, 2023 at 08:54:33AM +, Liu, Yi L wrote:
> > > From: Alex Williamson 
> > > Sent: Thursday, June 22, 2023 5:54 AM
> > >
> > > On Fri, 16 Jun 2023 02:39:46 -0700
> > > Yi Liu  wrote:
> >
> > > > +VFIO device cdev doesn't rely on VFIO group/container/iommu drivers.
> > > > +Hence those modules can be fully compiled out in an environment
> > > > +where no legacy VFIO application exists.
> > > > +
> > > > +So far SPAPR does not support IOMMUFD yet.  So it cannot support device
> > > > +cdev either.
> > >
> > > Why isn´t this enforced via Kconfig?  At the vfio level we could simply
> > > add the following in patch 17/:
> > >
> > > config VFIO_DEVICE_CDEV
> > > bool "Support for the VFIO cdev /dev/vfio/devices/vfioX"
> > > depends on IOMMUFD && !SPAPR_TCE_IOMMU
> > >^^^
> > >

Proposal A.

> > > Or if Jason wants, IOMMUFD could depend on !SPAPR_TCE_IOMMU for now and
> > > the existing Kconfig options would exclude it.  If we know it doesn't
> > > work, let's not put the burden on the user to figure that out.  A
> > > follow-up patch for this would be fine if there's no other reason to
> > > respin the series.

Proposal B.

> >
> > @Jason,
> > How about your opinion? Seems reasonable to make IOMMUFD
> > depend on !SPAPR_TCE_IOMMU. Is it?
> 
> The right kconfig would be to list all the iommu drivers that can
> support iommufd and allow it to be selected if any of them are
> enabled.
> 
> This seems too complex to bother with, so I like Alex's version above..

Sorry, I'm not quite clear. Alex has two proposals above (A and B). Which
one do you mean? It looks like you prefer A. is it? :-)

Regards,
Yi Liu


[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915/guc: Dump perf_limit_reasons for debug (rev2)

2023-06-27 Thread Patchwork
== Series Details ==

Series: drm/i915/guc: Dump perf_limit_reasons for debug (rev2)
URL   : https://patchwork.freedesktop.org/series/119893/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_13328 -> Patchwork_119893v2


Summary
---

  **SUCCESS**

  No regressions found.

  External URL: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/index.html

Participating hosts (40 -> 39)
--

  Additional (1): fi-apl-guc 
  Missing(2): fi-kbl-soraka fi-snb-2520m 

Known issues


  Here are the changes found in Patchwork_119893v2 that come from known issues:

### IGT changes ###

 Issues hit 

  * igt@core_auth@basic-auth:
- bat-adlp-11:[PASS][1] -> [ABORT][2] ([i915#4423] / [i915#8011])
   [1]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-adlp-11/igt@core_a...@basic-auth.html
   [2]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/bat-adlp-11/igt@core_a...@basic-auth.html

  * igt@gem_lmem_swapping@basic:
- fi-apl-guc: NOTRUN -> [SKIP][3] ([fdo#109271] / [i915#4613]) +3 
similar issues
   [3]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/fi-apl-guc/igt@gem_lmem_swapp...@basic.html

  * igt@i915_module_load@load:
- bat-adlp-11:[PASS][4] -> [DMESG-WARN][5] ([i915#4423])
   [4]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-adlp-11/igt@i915_module_l...@load.html
   [5]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/bat-adlp-11/igt@i915_module_l...@load.html

  * igt@i915_pm_rpm@basic-pci-d3-state:
- bat-mtlp-8: [PASS][6] -> [ABORT][7] ([i915#7077] / [i915#7977])
   [6]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-8/igt@i915_pm_...@basic-pci-d3-state.html
   [7]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/bat-mtlp-8/igt@i915_pm_...@basic-pci-d3-state.html

  * igt@i915_selftest@live@migrate:
- bat-mtlp-6: [PASS][8] -> [DMESG-FAIL][9] ([i915#7699])
   [8]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-6/igt@i915_selftest@l...@migrate.html
   [9]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/bat-mtlp-6/igt@i915_selftest@l...@migrate.html

  * igt@i915_selftest@live@reset:
- bat-rpls-1: [PASS][10] -> [ABORT][11] ([i915#4983] / [i915#7461] 
/ [i915#8347] / [i915#8384])
   [10]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-rpls-1/igt@i915_selftest@l...@reset.html
   [11]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/bat-rpls-1/igt@i915_selftest@l...@reset.html
- bat-rpls-2: NOTRUN -> [ABORT][12] ([i915#4983] / [i915#7461] / 
[i915#7913] / [i915#8347])
   [12]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/bat-rpls-2/igt@i915_selftest@l...@reset.html

  * igt@kms_chamelium_hpd@vga-hpd-fast:
- fi-apl-guc: NOTRUN -> [SKIP][13] ([fdo#109271]) +21 similar issues
   [13]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/fi-apl-guc/igt@kms_chamelium_...@vga-hpd-fast.html

  * igt@kms_pipe_crc_basic@nonblocking-crc-frame-sequence:
- bat-dg2-11: NOTRUN -> [SKIP][14] ([i915#1845] / [i915#5354]) +3 
similar issues
   [14]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/bat-dg2-11/igt@kms_pipe_crc_ba...@nonblocking-crc-frame-sequence.html

  * igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-d-edp-1:
- bat-rplp-1: [PASS][15] -> [ABORT][16] ([i915#8442])
   [15]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-rplp-1/igt@kms_pipe_crc_basic@read-crc-frame-seque...@pipe-d-edp-1.html
   [16]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/bat-rplp-1/igt@kms_pipe_crc_basic@read-crc-frame-seque...@pipe-d-edp-1.html

  * igt@kms_setmode@basic-clone-single-crtc:
- fi-apl-guc: NOTRUN -> [SKIP][17] ([fdo#109271] / [i915#4579])
   [17]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/fi-apl-guc/igt@kms_setm...@basic-clone-single-crtc.html

  
 Possible fixes 

  * igt@i915_selftest@live@gt_pm:
- bat-rpls-2: [DMESG-FAIL][18] ([i915#4258] / [i915#7913]) -> 
[PASS][19]
   [18]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-rpls-2/igt@i915_selftest@live@gt_pm.html
   [19]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/bat-rpls-2/igt@i915_selftest@live@gt_pm.html

  * igt@i915_selftest@live@migrate:
- bat-dg2-11: [DMESG-WARN][20] ([i915#7699]) -> [PASS][21]
   [20]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-dg2-11/igt@i915_selftest@l...@migrate.html
   [21]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119893v2/bat-dg2-11/igt@i915_selftest@l...@migrate.html

  * igt@i915_selftest@live@mman:
- bat-rpls-2: [TIMEOUT][22] ([i915#6794] / [i915#7392]) -> 
[PASS][23]
   [22]: 

[Intel-gfx] ✗ Fi.CI.BAT: failure for drm: Replace drm_framebuffer plane size functions with its equivalents

2023-06-27 Thread Patchwork
== Series Details ==

Series: drm: Replace drm_framebuffer plane size functions with its equivalents
URL   : https://patchwork.freedesktop.org/series/119943/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_13328 -> Patchwork_119943v1


Summary
---

  **FAILURE**

  Serious unknown changes coming with Patchwork_119943v1 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_119943v1, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119943v1/index.html

Participating hosts (40 -> 41)
--

  Additional (2): fi-apl-guc fi-pnv-d510 
  Missing(1): fi-snb-2520m 

Possible new issues
---

  Here are the unknown changes that may have been introduced in 
Patchwork_119943v1:

### IGT changes ###

 Possible regressions 

  * igt@i915_module_load@load:
- bat-dg1-7:  [PASS][1] -> [ABORT][2]
   [1]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-dg1-7/igt@i915_module_l...@load.html
   [2]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119943v1/bat-dg1-7/igt@i915_module_l...@load.html

  
 Warnings 

  * igt@kms_psr@primary_page_flip:
- bat-rplp-1: [SKIP][3] ([i915#1072]) -> [ABORT][4]
   [3]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-rplp-1/igt@kms_psr@primary_page_flip.html
   [4]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119943v1/bat-rplp-1/igt@kms_psr@primary_page_flip.html

  
Known issues


  Here are the changes found in Patchwork_119943v1 that come from known issues:

### IGT changes ###

 Issues hit 

  * igt@gem_lmem_swapping@basic:
- fi-apl-guc: NOTRUN -> [SKIP][5] ([fdo#109271] / [i915#4613]) +3 
similar issues
   [5]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119943v1/fi-apl-guc/igt@gem_lmem_swapp...@basic.html

  * igt@i915_module_load@load:
- bat-adlp-11:[PASS][6] -> [ABORT][7] ([i915#4423])
   [6]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-adlp-11/igt@i915_module_l...@load.html
   [7]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119943v1/bat-adlp-11/igt@i915_module_l...@load.html

  * igt@i915_pm_rpm@basic-pci-d3-state:
- bat-mtlp-8: [PASS][8] -> [ABORT][9] ([i915#7077] / [i915#7977])
   [8]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-8/igt@i915_pm_...@basic-pci-d3-state.html
   [9]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119943v1/bat-mtlp-8/igt@i915_pm_...@basic-pci-d3-state.html

  * igt@kms_chamelium_hpd@vga-hpd-fast:
- fi-apl-guc: NOTRUN -> [SKIP][10] ([fdo#109271]) +21 similar issues
   [10]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119943v1/fi-apl-guc/igt@kms_chamelium_...@vga-hpd-fast.html

  * igt@kms_pipe_crc_basic@nonblocking-crc-frame-sequence:
- bat-dg2-11: NOTRUN -> [SKIP][11] ([i915#1845] / [i915#5354]) +3 
similar issues
   [11]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119943v1/bat-dg2-11/igt@kms_pipe_crc_ba...@nonblocking-crc-frame-sequence.html

  * igt@kms_psr@primary_page_flip:
- fi-pnv-d510:NOTRUN -> [SKIP][12] ([fdo#109271]) +37 similar issues
   [12]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119943v1/fi-pnv-d510/igt@kms_psr@primary_page_flip.html

  * igt@kms_setmode@basic-clone-single-crtc:
- fi-apl-guc: NOTRUN -> [SKIP][13] ([fdo#109271] / [i915#4579])
   [13]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119943v1/fi-apl-guc/igt@kms_setm...@basic-clone-single-crtc.html
- fi-pnv-d510:NOTRUN -> [SKIP][14] ([fdo#109271] / [i915#4579])
   [14]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119943v1/fi-pnv-d510/igt@kms_setm...@basic-clone-single-crtc.html

  
 Possible fixes 

  * igt@i915_selftest@live@migrate:
- bat-dg2-11: [DMESG-WARN][15] ([i915#7699]) -> [PASS][16]
   [15]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-dg2-11/igt@i915_selftest@l...@migrate.html
   [16]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119943v1/bat-dg2-11/igt@i915_selftest@l...@migrate.html

  * igt@i915_selftest@live@workarounds:
- bat-mtlp-6: [DMESG-FAIL][17] ([i915#6763]) -> [PASS][18]
   [17]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-6/igt@i915_selftest@l...@workarounds.html
   [18]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119943v1/bat-mtlp-6/igt@i915_selftest@l...@workarounds.html

  
  {name}: This element is suppressed. This means it is ignored when computing
  the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [i915#1072]: 

[Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm: Replace drm_framebuffer plane size functions with its equivalents

2023-06-27 Thread Patchwork
== Series Details ==

Series: drm: Replace drm_framebuffer plane size functions with its equivalents
URL   : https://patchwork.freedesktop.org/series/119943/
State : warning

== Summary ==

Error: dim sparse failed
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.




[Intel-gfx] ✓ Fi.CI.BAT: success for HDMI 2.0/DP1p62Gbps skew violation when there is skew between DL PCLK

2023-06-27 Thread Patchwork
== Series Details ==

Series: HDMI 2.0/DP1p62Gbps skew violation when there is skew between DL PCLK
URL   : https://patchwork.freedesktop.org/series/119934/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_13328 -> Patchwork_119934v1


Summary
---

  **SUCCESS**

  No regressions found.

  External URL: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119934v1/index.html

Participating hosts (40 -> 41)
--

  Additional (2): fi-apl-guc fi-pnv-d510 
  Missing(1): fi-snb-2520m 

Known issues


  Here are the changes found in Patchwork_119934v1 that come from known issues:

### IGT changes ###

 Issues hit 

  * igt@gem_lmem_swapping@basic:
- fi-apl-guc: NOTRUN -> [SKIP][1] ([fdo#109271] / [i915#4613]) +3 
similar issues
   [1]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119934v1/fi-apl-guc/igt@gem_lmem_swapp...@basic.html

  * igt@i915_module_load@load:
- bat-adlp-11:[PASS][2] -> [ABORT][3] ([i915#4423])
   [2]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-adlp-11/igt@i915_module_l...@load.html
   [3]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119934v1/bat-adlp-11/igt@i915_module_l...@load.html

  * igt@i915_selftest@live@requests:
- bat-mtlp-8: [PASS][4] -> [ABORT][5] ([i915#7982])
   [4]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-8/igt@i915_selftest@l...@requests.html
   [5]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119934v1/bat-mtlp-8/igt@i915_selftest@l...@requests.html

  * igt@kms_chamelium_hpd@vga-hpd-fast:
- fi-apl-guc: NOTRUN -> [SKIP][6] ([fdo#109271]) +21 similar issues
   [6]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119934v1/fi-apl-guc/igt@kms_chamelium_...@vga-hpd-fast.html

  * igt@kms_psr@primary_mmap_gtt:
- bat-rplp-1: NOTRUN -> [ABORT][7] ([i915#8442])
   [7]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119934v1/bat-rplp-1/igt@kms_psr@primary_mmap_gtt.html

  * igt@kms_psr@primary_page_flip:
- fi-pnv-d510:NOTRUN -> [SKIP][8] ([fdo#109271]) +37 similar issues
   [8]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119934v1/fi-pnv-d510/igt@kms_psr@primary_page_flip.html

  * igt@kms_setmode@basic-clone-single-crtc:
- fi-apl-guc: NOTRUN -> [SKIP][9] ([fdo#109271] / [i915#4579])
   [9]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119934v1/fi-apl-guc/igt@kms_setm...@basic-clone-single-crtc.html
- fi-pnv-d510:NOTRUN -> [SKIP][10] ([fdo#109271] / [i915#4579])
   [10]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119934v1/fi-pnv-d510/igt@kms_setm...@basic-clone-single-crtc.html

  
 Possible fixes 

  * igt@i915_selftest@live@gt_pm:
- bat-rpls-2: [DMESG-FAIL][11] ([i915#4258] / [i915#7913]) -> 
[PASS][12]
   [11]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-rpls-2/igt@i915_selftest@live@gt_pm.html
   [12]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119934v1/bat-rpls-2/igt@i915_selftest@live@gt_pm.html

  
 Warnings 

  * igt@kms_psr@sprite_plane_onoff:
- bat-rplp-1: [ABORT][13] ([i915#8712]) -> [SKIP][14] ([i915#1072])
   [13]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-rplp-1/igt@kms_psr@sprite_plane_onoff.html
   [14]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119934v1/bat-rplp-1/igt@kms_psr@sprite_plane_onoff.html

  
  {name}: This element is suppressed. This means it is ignored when computing
  the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
  [i915#4258]: https://gitlab.freedesktop.org/drm/intel/issues/4258
  [i915#4423]: https://gitlab.freedesktop.org/drm/intel/issues/4423
  [i915#4579]: https://gitlab.freedesktop.org/drm/intel/issues/4579
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#7913]: https://gitlab.freedesktop.org/drm/intel/issues/7913
  [i915#7982]: https://gitlab.freedesktop.org/drm/intel/issues/7982
  [i915#8442]: https://gitlab.freedesktop.org/drm/intel/issues/8442
  [i915#8712]: https://gitlab.freedesktop.org/drm/intel/issues/8712


Build changes
-

  * Linux: CI_DRM_13328 -> Patchwork_119934v1

  CI-20190529: 20190529
  CI_DRM_13328: 12cd6b2d321d9c034f3d4ba14788d68cb8da4eac @ 
git://anongit.freedesktop.org/gfx-ci/linux
  IGT_7351: d8dc96b95c60e4737fdfa1664ce9b1dcebfdef60 @ 
https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_119934v1: 12cd6b2d321d9c034f3d4ba14788d68cb8da4eac @ 
git://anongit.freedesktop.org/gfx-ci/linux


### Linux commits

1aed4bc699f2 drm/i915/display: HDMI2.0/DP1p62Gbps skew violation when there is 
skew between DL PCLK

== Logs ==

For more details see: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119934v1/index.html


[Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for HDMI 2.0/DP1p62Gbps skew violation when there is skew between DL PCLK

2023-06-27 Thread Patchwork
== Series Details ==

Series: HDMI 2.0/DP1p62Gbps skew violation when there is skew between DL PCLK
URL   : https://patchwork.freedesktop.org/series/119934/
State : warning

== Summary ==

Error: dim checkpatch failed
9bc5743dec81 drm/i915/display: HDMI2.0/DP1p62Gbps skew violation when there is 
skew between DL PCLK
-:28: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#28: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:1367:
+   if ((crtc_state->port_clock == 594000 &&
+   intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 
||

total: 0 errors, 0 warnings, 1 checks, 29 lines checked




Re: [Intel-gfx] [PATCH v2] drm/i915/guc: Dump perf_limit_reasons for debug

2023-06-27 Thread Dixit, Ashutosh
On Tue, 27 Jun 2023 12:13:36 -0700, Vinay Belgaumkar wrote:
>
> GuC load takes longer sometimes due to GT frequency not ramping up.
> Add perf_limit_reasons to the existing warn print to see if frequency
> is being throttled.
>
> v2: Review comments (Ashutosh)

Reviewed-by: Ashutosh Dixit 

>
> Signed-off-by: Vinay Belgaumkar 
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 8 +---
>  1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c 
> b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
> index 364d0d546ec8..0f79cb658518 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
> @@ -251,9 +251,11 @@ static int guc_wait_ucode(struct intel_guc *guc)
>   if (ret == 0)
>   ret = -ENXIO;
>   } else if (delta_ms > 200) {
> - guc_warn(guc, "excessive init time: %lldms! [freq = %dMHz, 
> before = %dMHz, status = 0x%08X, count = %d, ret = %d]\n",
> -  delta_ms, 
> intel_rps_read_actual_frequency(>gt->rps),
> -  before_freq, status, count, ret);
> + guc_warn(guc, "excessive init time: %lldms! [status = 0x%08X, 
> count = %d, ret = %d]\n",
> +  delta_ms, status, count, ret);
> + guc_warn(guc, "excessive init time: [freq = %dMHz, before = 
> %dMHz, perf_limit_reasons = 0x%08X]\n",
> +  intel_rps_read_actual_frequency(>gt->rps), 
> before_freq,
> +  intel_uncore_read(uncore, 
> intel_gt_perf_limit_reasons_reg(gt)));
>   } else {
>   guc_dbg(guc, "init took %lldms, freq = %dMHz, before = %dMHz, 
> status = 0x%08X, count = %d, ret = %d\n",
>   delta_ms, 
> intel_rps_read_actual_frequency(>gt->rps),
> --
> 2.38.1
>


[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: further device info fixes and cleanups

2023-06-27 Thread Patchwork
== Series Details ==

Series: drm/i915: further device info fixes and cleanups
URL   : https://patchwork.freedesktop.org/series/119933/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_13328 -> Patchwork_119933v1


Summary
---

  **SUCCESS**

  No regressions found.

  External URL: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/index.html

Participating hosts (40 -> 40)
--

  Additional (2): fi-apl-guc fi-pnv-d510 
  Missing(2): fi-kbl-soraka fi-snb-2520m 

Known issues


  Here are the changes found in Patchwork_119933v1 that come from known issues:

### IGT changes ###

 Issues hit 

  * igt@core_auth@basic-auth:
- bat-adlp-11:[PASS][1] -> [ABORT][2] ([i915#8011])
   [1]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-adlp-11/igt@core_a...@basic-auth.html
   [2]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/bat-adlp-11/igt@core_a...@basic-auth.html

  * igt@gem_lmem_swapping@basic:
- fi-apl-guc: NOTRUN -> [SKIP][3] ([fdo#109271] / [i915#4613]) +3 
similar issues
   [3]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/fi-apl-guc/igt@gem_lmem_swapp...@basic.html

  * igt@i915_module_load@load:
- bat-adlp-11:[PASS][4] -> [DMESG-WARN][5] ([i915#4423])
   [4]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-adlp-11/igt@i915_module_l...@load.html
   [5]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/bat-adlp-11/igt@i915_module_l...@load.html

  * igt@i915_pm_rpm@basic-pci-d3-state:
- bat-mtlp-8: [PASS][6] -> [ABORT][7] ([i915#7077] / [i915#7977])
   [6]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-8/igt@i915_pm_...@basic-pci-d3-state.html
   [7]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/bat-mtlp-8/igt@i915_pm_...@basic-pci-d3-state.html

  * igt@i915_selftest@live@gt_lrc:
- bat-dg2-11: [PASS][8] -> [INCOMPLETE][9] ([i915#7609] / 
[i915#7913])
   [8]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-dg2-11/igt@i915_selftest@live@gt_lrc.html
   [9]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/bat-dg2-11/igt@i915_selftest@live@gt_lrc.html

  * igt@i915_selftest@live@requests:
- bat-adlp-9: [PASS][10] -> [ABORT][11] ([i915#7913] / [i915#7982])
   [10]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-adlp-9/igt@i915_selftest@l...@requests.html
   [11]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/bat-adlp-9/igt@i915_selftest@l...@requests.html
- bat-rpls-2: [PASS][12] -> [ABORT][13] ([i915#7913] / [i915#7982])
   [12]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-rpls-2/igt@i915_selftest@l...@requests.html
   [13]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/bat-rpls-2/igt@i915_selftest@l...@requests.html

  * igt@kms_chamelium_hpd@vga-hpd-fast:
- fi-apl-guc: NOTRUN -> [SKIP][14] ([fdo#109271]) +21 similar issues
   [14]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/fi-apl-guc/igt@kms_chamelium_...@vga-hpd-fast.html

  * igt@kms_pipe_crc_basic@nonblocking-crc:
- bat-adlp-9: NOTRUN -> [SKIP][15] ([i915#3546]) +3 similar issues
   [15]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/bat-adlp-9/igt@kms_pipe_crc_ba...@nonblocking-crc.html

  * igt@kms_pipe_crc_basic@nonblocking-crc-frame-sequence:
- bat-dg2-11: NOTRUN -> [SKIP][16] ([i915#1845] / [i915#5354]) +3 
similar issues
   [16]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/bat-dg2-11/igt@kms_pipe_crc_ba...@nonblocking-crc-frame-sequence.html

  * igt@kms_psr@primary_mmap_gtt:
- bat-rplp-1: NOTRUN -> [ABORT][17] ([i915#8442])
   [17]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/bat-rplp-1/igt@kms_psr@primary_mmap_gtt.html

  * igt@kms_psr@primary_page_flip:
- fi-pnv-d510:NOTRUN -> [SKIP][18] ([fdo#109271]) +37 similar issues
   [18]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/fi-pnv-d510/igt@kms_psr@primary_page_flip.html

  * igt@kms_setmode@basic-clone-single-crtc:
- fi-apl-guc: NOTRUN -> [SKIP][19] ([fdo#109271] / [i915#4579])
   [19]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/fi-apl-guc/igt@kms_setm...@basic-clone-single-crtc.html
- fi-pnv-d510:NOTRUN -> [SKIP][20] ([fdo#109271] / [i915#4579])
   [20]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119933v1/fi-pnv-d510/igt@kms_setm...@basic-clone-single-crtc.html

  
 Possible fixes 

  * igt@i915_selftest@live@gt_mocs:
- bat-mtlp-6: [DMESG-FAIL][21] ([i915#7059]) -> [PASS][22]
   [21]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-6/igt@i915_selftest@live@gt_mocs.html
   [22]: 

[Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/i915: further device info fixes and cleanups

2023-06-27 Thread Patchwork
== Series Details ==

Series: drm/i915: further device info fixes and cleanups
URL   : https://patchwork.freedesktop.org/series/119933/
State : warning

== Summary ==

Error: dim sparse failed
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.




[Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: further device info fixes and cleanups

2023-06-27 Thread Patchwork
== Series Details ==

Series: drm/i915: further device info fixes and cleanups
URL   : https://patchwork.freedesktop.org/series/119933/
State : warning

== Summary ==

Error: dim checkpatch failed
b9423c209dc0 drm/i915: use mock device info for creating mock device
93df845dfc05 drm/i915: move platform_engine_mask and memory_regions to device 
info
74e0bd21bc35 drm/i915: separate display info printing from the rest
-:37: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'name' may be better as 
'(name)' to avoid precedence issues
#37: FILE: drivers/gpu/drm/i915/display/intel_display_device.c:997:
+#define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, 
str_yes_no(info->name))

total: 0 errors, 0 warnings, 1 checks, 125 lines checked
baa649ba6f62 drm/i915: fix display info usage
9dc8f7006e55 drm/i915: move display device and runtime info to struct 
intel_display
6543bcf56ae9 drm/i915: make device info a const pointer to rodata




[Intel-gfx] [linux-next:master] BUILD REGRESSION 53cdf865f90ba922a854c65ed05b519f9d728424

2023-06-27 Thread kernel test robot
tree/branch: 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
branch HEAD: 53cdf865f90ba922a854c65ed05b519f9d728424  Add linux-next specific 
files for 20230627

Error/Warning reports:

https://lore.kernel.org/oe-kbuild-all/20230613.hher4zoo-...@intel.com
https://lore.kernel.org/oe-kbuild-all/202306212119.fbnbyiyn-...@intel.com
https://lore.kernel.org/oe-kbuild-all/202306260401.qzlyqpv2-...@intel.com

Error/Warning: (recently discovered and may have been fixed)

arch/parisc/kernel/pdt.c:66:6: warning: no previous prototype for 
'arch_report_meminfo' [-Wmissing-prototypes]
drivers/char/mem.c:164:25: error: implicit declaration of function 
'unxlate_dev_mem_ptr'; did you mean 'xlate_dev_mem_ptr'? 
[-Werror=implicit-function-declaration]
drivers/gpu/drm/i915/soc/intel_gmch.c:41:13: warning: variable 'mchbar_addr' 
set but not used [-Wunused-but-set-variable]
drivers/mfd/max77541.c:176:18: warning: cast to smaller integer type 'enum 
max7754x_ids' from 'const void *' [-Wvoid-pointer-to-enum-cast]
lib/kunit/executor_test.c:138:4: warning: cast from 'void (*)(const void *)' to 
'kunit_action_t *' (aka 'void (*)(void *)') converts to incompatible function 
type [-Wcast-function-type-strict]
lib/kunit/test.c:775:38: warning: cast from 'void (*)(const void *)' to 
'kunit_action_t *' (aka 'void (*)(void *)') converts to incompatible function 
type [-Wcast-function-type-strict]

Unverified Error/Warning (likely false positive, please contact us if 
interested):

drivers/usb/cdns3/cdns3-starfive.c:23: warning: expecting prototype for 
cdns3(). Prototype was for USB_STRAP_HOST() instead
net/wireless/scan.c:373 cfg80211_gen_new_ie() warn: potential spectre issue 
'sub->data' [r]
net/wireless/scan.c:397 cfg80211_gen_new_ie() warn: possible spectre second 
half.  'ext_id'
{standard input}: Error: local label `"2" (instance number 9 of a fb label)' is 
not defined
{standard input}:1097: Error: pcrel too far
{standard input}:13: Error: symbol `__export_symbol_alpha_mv' is already defined

Error/Warning ids grouped by kconfigs:

gcc_recent_errors
|-- alpha-randconfig-r024-20230627
|   `-- standard-input:Error:symbol-__export_symbol_alpha_mv-is-already-defined
|-- i386-randconfig-m021-20230627
|   |-- 
net-wireless-scan.c-cfg80211_gen_new_ie()-warn:possible-spectre-second-half.-ext_id
|   `-- 
net-wireless-scan.c-cfg80211_gen_new_ie()-warn:potential-spectre-issue-sub-data-r
|-- parisc-allnoconfig
|   `-- 
arch-parisc-kernel-pdt.c:warning:no-previous-prototype-for-arch_report_meminfo
|-- parisc-allyesconfig
|   `-- 
arch-parisc-kernel-pdt.c:warning:no-previous-prototype-for-arch_report_meminfo
|-- parisc-defconfig
|   `-- 
arch-parisc-kernel-pdt.c:warning:no-previous-prototype-for-arch_report_meminfo
|-- parisc-randconfig-r012-20230627
|   `-- 
arch-parisc-kernel-pdt.c:warning:no-previous-prototype-for-arch_report_meminfo
|-- parisc-randconfig-r013-20230627
|   `-- 
arch-parisc-kernel-pdt.c:warning:no-previous-prototype-for-arch_report_meminfo
|-- parisc-randconfig-r052-20230627
|   `-- 
arch-parisc-kernel-pdt.c:warning:no-previous-prototype-for-arch_report_meminfo
|-- parisc64-defconfig
|   `-- 
arch-parisc-kernel-pdt.c:warning:no-previous-prototype-for-arch_report_meminfo
|-- riscv-allmodconfig
|   `-- 
drivers-usb-cdns3-cdns3-starfive.c:warning:expecting-prototype-for-cdns3().-Prototype-was-for-USB_STRAP_HOST()-instead
|-- riscv-allyesconfig
|   `-- 
drivers-usb-cdns3-cdns3-starfive.c:warning:expecting-prototype-for-cdns3().-Prototype-was-for-USB_STRAP_HOST()-instead
|-- sh-allmodconfig
|   |-- 
drivers-char-mem.c:error:implicit-declaration-of-function-unxlate_dev_mem_ptr
|   |-- 
standard-input:Error:local-label-(instance-number-of-a-fb-label)-is-not-defined
|   `-- standard-input:Error:pcrel-too-far
|-- sh-j2_defconfig
|   `-- 
drivers-char-mem.c:error:implicit-declaration-of-function-unxlate_dev_mem_ptr
|-- sh-randconfig-r015-20230627
|   `-- 
drivers-char-mem.c:error:implicit-declaration-of-function-unxlate_dev_mem_ptr
|-- sh-rsk7203_defconfig
|   `-- 
drivers-char-mem.c:error:implicit-declaration-of-function-unxlate_dev_mem_ptr
`-- x86_64-buildonly-randconfig-r001-20230627
`-- 
drivers-gpu-drm-i915-soc-intel_gmch.c:warning:variable-mchbar_addr-set-but-not-used
clang_recent_errors
|-- arm-randconfig-r031-20230627
|   `-- 
lib-kunit-test.c:warning:cast-from-void-(-)(const-void-)-to-kunit_action_t-(aka-void-(-)(void-)-)-converts-to-incompatible-function-type
|-- hexagon-randconfig-r041-20230627
|   |-- 
lib-kunit-executor_test.c:warning:cast-from-void-(-)(const-void-)-to-kunit_action_t-(aka-void-(-)(void-)-)-converts-to-incompatible-function-type
|   `-- 
lib-kunit-test.c:warning:cast-from-void-(-)(const-void-)-to-kunit_action_t-(aka-void-(-)(void-)-)-converts-to-incompatible-function-type
|-- powerpc-randconfig-r023-20230627
|   |-- 
lib-kunit-executor_test.c:warning:cast-from-void-(-)(const-void-)-to-kunit_action_t-(aka-void-(-)(void-)-)-converts-to-incompatible-

[Intel-gfx] ✗ Fi.CI.BUILD: failure for use refcount+RCU method to implement lockless slab shrink

2023-06-27 Thread Patchwork
== Series Details ==

Series: use refcount+RCU method to implement lockless slab shrink
URL   : https://patchwork.freedesktop.org/series/119926/
State : failure

== Summary ==

Error: patch 
https://patchwork.freedesktop.org/api/1.0/series/119926/revisions/1/mbox/ not 
applied
Applying: mm: shrinker: add shrinker::private_data field
Applying: mm: vmscan: introduce some helpers for dynamically allocating shrinker
Applying: drm/i915: dynamically allocate the i915_gem_mm shrinker
Applying: drm/msm: dynamically allocate the drm-msm_gem shrinker
Applying: drm/panfrost: dynamically allocate the drm-panfrost shrinker
Applying: dm: dynamically allocate the dm-bufio shrinker
Applying: dm zoned: dynamically allocate the dm-zoned-meta shrinker
Applying: md/raid5: dynamically allocate the md-raid5 shrinker
Applying: bcache: dynamically allocate the md-bcache shrinker
Applying: vmw_balloon: dynamically allocate the vmw-balloon shrinker
Applying: virtio_balloon: dynamically allocate the virtio-balloon shrinker
Applying: mbcache: dynamically allocate the mbcache shrinker
Applying: ext4: dynamically allocate the ext4-es shrinker
Applying: jbd2, ext4: dynamically allocate the jbd2-journal shrinker
Applying: NFSD: dynamically allocate the nfsd-client shrinker
Applying: NFSD: dynamically allocate the nfsd-reply shrinker
Applying: xfs: dynamically allocate the xfs-buf shrinker
Applying: xfs: dynamically allocate the xfs-inodegc shrinker
Applying: xfs: dynamically allocate the xfs-qm shrinker
Applying: zsmalloc: dynamically allocate the mm-zspool shrinker
Using index info to reconstruct a base tree...
M   mm/zsmalloc.c
Falling back to patching base and 3-way merge...
Auto-merging mm/zsmalloc.c
Applying: fs: super: dynamically allocate the s_shrink
Using index info to reconstruct a base tree...
M   fs/btrfs/super.c
M   fs/super.c
M   include/linux/fs.h
Falling back to patching base and 3-way merge...
Auto-merging include/linux/fs.h
Auto-merging fs/super.c
Auto-merging fs/btrfs/super.c
Applying: drm/ttm: introduce pool_shrink_rwsem
error: sha1 information is lacking or useless (mm/vmscan.c).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0022 drm/ttm: introduce pool_shrink_rwsem
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Build failed, no error log produced




[Intel-gfx] ✗ Fi.CI.BUILD: failure for Fixed-width mask/bit helpers (rev2)

2023-06-27 Thread Patchwork
== Series Details ==

Series: Fixed-width mask/bit helpers (rev2)
URL   : https://patchwork.freedesktop.org/series/117490/
State : failure

== Summary ==

Error: patch 
https://patchwork.freedesktop.org/api/1.0/series/117490/revisions/2/mbox/ not 
applied
Applying: drm/amd: Remove wrapper macros over get_u{32, 16, 8}
Patch is empty.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To record the empty patch as an empty commit, run "git am --allow-empty".
To restore the original branch and stop patching, run "git am --abort".
Build failed, no error log produced




[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915/dram: replace __raw_uncore_read32() with intel_uncore_read_fw()

2023-06-27 Thread Patchwork
== Series Details ==

Series: drm/i915/dram: replace __raw_uncore_read32() with intel_uncore_read_fw()
URL   : https://patchwork.freedesktop.org/series/119913/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_13328 -> Patchwork_119913v1


Summary
---

  **SUCCESS**

  No regressions found.

  External URL: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/index.html

Participating hosts (40 -> 40)
--

  Additional (2): fi-apl-guc fi-pnv-d510 
  Missing(2): fi-kbl-soraka fi-snb-2520m 

Known issues


  Here are the changes found in Patchwork_119913v1 that come from known issues:

### IGT changes ###

 Issues hit 

  * igt@core_auth@basic-auth:
- bat-adlp-11:[PASS][1] -> [ABORT][2] ([i915#8011])
   [1]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-adlp-11/igt@core_a...@basic-auth.html
   [2]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/bat-adlp-11/igt@core_a...@basic-auth.html

  * igt@gem_lmem_swapping@basic:
- fi-apl-guc: NOTRUN -> [SKIP][3] ([fdo#109271] / [i915#4613]) +3 
similar issues
   [3]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/fi-apl-guc/igt@gem_lmem_swapp...@basic.html

  * igt@i915_module_load@load:
- bat-adlp-11:[PASS][4] -> [DMESG-WARN][5] ([i915#4423])
   [4]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-adlp-11/igt@i915_module_l...@load.html
   [5]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/bat-adlp-11/igt@i915_module_l...@load.html

  * igt@i915_selftest@live@gt_heartbeat:
- fi-apl-guc: NOTRUN -> [DMESG-FAIL][6] ([i915#5334])
   [6]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/fi-apl-guc/igt@i915_selftest@live@gt_heartbeat.html

  * igt@i915_selftest@live@gt_mocs:
- bat-mtlp-8: [PASS][7] -> [DMESG-FAIL][8] ([i915#7059])
   [7]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-8/igt@i915_selftest@live@gt_mocs.html
   [8]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/bat-mtlp-8/igt@i915_selftest@live@gt_mocs.html

  * igt@i915_selftest@live@requests:
- bat-mtlp-6: [PASS][9] -> [DMESG-FAIL][10] ([i915#7269])
   [9]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-6/igt@i915_selftest@l...@requests.html
   [10]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/bat-mtlp-6/igt@i915_selftest@l...@requests.html

  * igt@i915_selftest@live@slpc:
- bat-rpls-2: NOTRUN -> [DMESG-WARN][11] ([i915#6367])
   [11]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/bat-rpls-2/igt@i915_selftest@l...@slpc.html

  * igt@kms_chamelium_hpd@vga-hpd-fast:
- fi-apl-guc: NOTRUN -> [SKIP][12] ([fdo#109271]) +21 similar issues
   [12]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/fi-apl-guc/igt@kms_chamelium_...@vga-hpd-fast.html

  * igt@kms_psr@primary_mmap_gtt:
- bat-rplp-1: NOTRUN -> [ABORT][13] ([i915#8442])
   [13]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/bat-rplp-1/igt@kms_psr@primary_mmap_gtt.html

  * igt@kms_psr@primary_page_flip:
- fi-pnv-d510:NOTRUN -> [SKIP][14] ([fdo#109271]) +37 similar issues
   [14]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/fi-pnv-d510/igt@kms_psr@primary_page_flip.html

  * igt@kms_setmode@basic-clone-single-crtc:
- fi-apl-guc: NOTRUN -> [SKIP][15] ([fdo#109271] / [i915#4579])
   [15]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/fi-apl-guc/igt@kms_setm...@basic-clone-single-crtc.html
- fi-pnv-d510:NOTRUN -> [SKIP][16] ([fdo#109271] / [i915#4579])
   [16]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/fi-pnv-d510/igt@kms_setm...@basic-clone-single-crtc.html

  
 Possible fixes 

  * igt@i915_selftest@live@migrate:
- bat-dg2-11: [DMESG-WARN][17] ([i915#7699]) -> [PASS][18]
   [17]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-dg2-11/igt@i915_selftest@l...@migrate.html
   [18]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/bat-dg2-11/igt@i915_selftest@l...@migrate.html
- bat-mtlp-8: [DMESG-FAIL][19] ([i915#7699]) -> [PASS][20]
   [19]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-8/igt@i915_selftest@l...@migrate.html
   [20]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/bat-mtlp-8/igt@i915_selftest@l...@migrate.html

  * igt@i915_selftest@live@mman:
- bat-rpls-2: [TIMEOUT][21] ([i915#6794] / [i915#7392]) -> 
[PASS][22]
   [21]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-rpls-2/igt@i915_selftest@l...@mman.html
   [22]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119913v1/bat-rpls-2/igt@i915_selftest@l...@mman.html

  
 Warnings 

  * igt@kms_psr@sprite_plane_onoff:
- bat-rplp-1: [ABORT][23] ([i915#8712]) -> 

[Intel-gfx] [PATCH v2] drm/i915/guc: Dump perf_limit_reasons for debug

2023-06-27 Thread Vinay Belgaumkar
GuC load takes longer sometimes due to GT frequency not ramping up.
Add perf_limit_reasons to the existing warn print to see if frequency
is being throttled.

v2: Review comments (Ashutosh)

Signed-off-by: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 364d0d546ec8..0f79cb658518 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -251,9 +251,11 @@ static int guc_wait_ucode(struct intel_guc *guc)
if (ret == 0)
ret = -ENXIO;
} else if (delta_ms > 200) {
-   guc_warn(guc, "excessive init time: %lldms! [freq = %dMHz, 
before = %dMHz, status = 0x%08X, count = %d, ret = %d]\n",
-delta_ms, 
intel_rps_read_actual_frequency(>gt->rps),
-before_freq, status, count, ret);
+   guc_warn(guc, "excessive init time: %lldms! [status = 0x%08X, 
count = %d, ret = %d]\n",
+delta_ms, status, count, ret);
+   guc_warn(guc, "excessive init time: [freq = %dMHz, before = 
%dMHz, perf_limit_reasons = 0x%08X]\n",
+intel_rps_read_actual_frequency(>gt->rps), 
before_freq,
+intel_uncore_read(uncore, 
intel_gt_perf_limit_reasons_reg(gt)));
} else {
guc_dbg(guc, "init took %lldms, freq = %dMHz, before = %dMHz, 
status = 0x%08X, count = %d, ret = %d\n",
delta_ms, 
intel_rps_read_actual_frequency(>gt->rps),
-- 
2.38.1



Re: [Intel-gfx] [PATCH] drm/i915/guc: Dump perf_limit_reasons for debug

2023-06-27 Thread Belgaumkar, Vinay



On 6/26/2023 11:43 PM, Dixit, Ashutosh wrote:

On Mon, 26 Jun 2023 21:02:14 -0700, Belgaumkar, Vinay wrote:


On 6/26/2023 8:17 PM, Dixit, Ashutosh wrote:

On Mon, 26 Jun 2023 19:12:18 -0700, Vinay Belgaumkar wrote:

GuC load takes longer sometimes due to GT frequency not ramping up.
Add perf_limit_reasons to the existing warn print to see if frequency
is being throttled.

Signed-off-by: Vinay Belgaumkar 
---
   drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 2 ++
   1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 364d0d546ec8..73911536a8e7 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -254,6 +254,8 @@ static int guc_wait_ucode(struct intel_guc *guc)
guc_warn(guc, "excessive init time: %lldms! [freq = %dMHz, before = 
%dMHz, status = 0x%08X, count = %d, ret = %d]\n",
 delta_ms, 
intel_rps_read_actual_frequency(>gt->rps),
 before_freq, status, count, ret);
+   guc_warn(guc, "perf limit reasons = 0x%08X\n",
+intel_uncore_read(uncore, 
intel_gt_perf_limit_reasons_reg(gt)));

Maybe just add at the end of the previous guc_warn?

Its already too long a line. If I try adding on the next line checkpatch
complains about splitting double quotes.

In these cases of long quoted lines we generally ignore checkpatch. Because
perf limit reasons is part of the "excessive init time" message it should
be on the same line within the square brackets. So should not be
splitting double quotes.

Another idea would be something like this:

guc_warn(guc, "excessive init time: %lldms! [freq = %dMHz, before = 
%dMHz, status = 0x%08X]\n",
 delta_ms, 
intel_rps_read_actual_frequency(>gt->rps),
 before_freq, status);
guc_warn(guc, "excessive init time: [count = %d, ret = %d, perf 
limit reasons = 0x%08X]\n",
 count, ret, intel_uncore_read(uncore, 
intel_gt_perf_limit_reasons_reg(gt)));


ok, I will split iut based on freq and non-freq based debug.

Thanks,

Vinay.



Thanks.
--
Ashutosh


Re: [Intel-gfx] [PATCH v2 3/6] drm/i915/gt: Fix context workarounds with non-masked regs

2023-06-27 Thread Kenneth Graunke
On Saturday, June 24, 2023 10:17:54 AM PDT Lucas De Marchi wrote:
> Most of the context workarounds tweak masked registers, but not all. For
> masked registers, when writing the value it's sufficient to just write
> the wa->set_bits since that will take care of both the clr and set bits
> as well as not overwriting other bits.
> 
> However there are some workarounds, the registers are non-masked. Up
> until now the driver was simply emitting a MI_LOAD_REGISTER_IMM with the
> set_bits to program the register via the GPU in the WA bb. This has the
> side effect of overwriting the content of the register outside of bits
> that should be set and also doesn't handle the bits that should be
> cleared.
> 
> Kenneth reported that on DG2, mesa was seeing a weird behavior due to
> the kernel programming of L3SQCREG5 in dg2_ctx_gt_tuning_init(). With
> the GPU idle, that register could be read via intel_reg as 0x00e001ff,
> but during a 3D workload it would change to 0x007f. So the
> programming of that tuning was affecting more than the bits in
> L3_PWM_TIMER_INIT_VAL_MASK. Matt Roper noticed the lack of rmw for the
> context workarounds due to the use of MI_LOAD_REGISTER_IMM.
> 
> So, for registers that are not masked, read its value via mmio, modify
> and then set it in the buffer to be written by the GPU. This should take
> care in a simple way of programming just the bits required by the
> tuning/workaround. If in future there are registers that involved that
> can't be read by the CPU, a more complex approach may be required like
> a) issuing additional instructions to read and modify; or b) scan the
> golden context and patch it in place before saving it; or something
> else. But for now this should suffice.
> 
> Scanning the context workarounds for all platforms, these are the
> impacted ones with the respective registers
> 
>   mtl: DRAW_WATERMARK
>   mtl/dg2: XEHP_L3SQCREG5, XEHP_FF_MODE2
> 
> ICL has some non-masked registers in the context workarounds:
> GEN8_L3CNTLREG, IVB_FBC_RT_BASE and VB_FBC_RT_BASE_UPPER, but there
> shouldn't be an impact. The first is already being manually read and the
> other 2 are intentionally overwriting the entire register. Same
> reasoning applies to GEN12_FF_MODE2: the WA is intentionally
> overwriting all the bits to avoid a read-modify-write.
> 
> v2:  Reword commit message wrt GEN12_FF_MODE2 and the changed behavior
> on preparatory patches.
> 
> Cc: Kenneth Graunke 
> Cc: Matt Roper 
> Link: 
> https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23783#note_1968971
> Signed-off-by: Lucas De Marchi 
> ---
>  drivers/gpu/drm/i915/gt/intel_workarounds.c | 27 -
>  1 file changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c 
> b/drivers/gpu/drm/i915/gt/intel_workarounds.c
> index 7d48bd57b6ef..9291c2b4ca0e 100644
> --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
> +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
> @@ -986,6 +986,9 @@ void intel_engine_init_ctx_wa(struct intel_engine_cs 
> *engine)
>  int intel_engine_emit_ctx_wa(struct i915_request *rq)
>  {
>   struct i915_wa_list *wal = >engine->ctx_wa_list;
> + struct intel_uncore *uncore = rq->engine->uncore;
> + enum forcewake_domains fw;
> + unsigned long flags;
>   struct i915_wa *wa;
>   unsigned int i;
>   u32 *cs;
> @@ -1002,13 +1005,35 @@ int intel_engine_emit_ctx_wa(struct i915_request *rq)
>   if (IS_ERR(cs))
>   return PTR_ERR(cs);
>  
> + fw = wal_get_fw_for_rmw(uncore, wal);
> +
> + intel_gt_mcr_lock(wal->gt, );
> + spin_lock(>lock);
> + intel_uncore_forcewake_get__locked(uncore, fw);
> +
>   *cs++ = MI_LOAD_REGISTER_IMM(wal->count);
>   for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {
> + u32 val;
> +
> + if (wa->masked_reg || wa->set == U32_MAX) {

I think you still want:

if (wa->masked_reg || wa->set == U32_MAX || wa->clr == U32_MAX) 
{

since there's no point to doing a read just to mask off 100% of the
values.  Harmless, of course, but unnecessary.

Either way, patches 1-5 are:
Reviewed-by: Kenneth Graunke 

> + val = wa->set;
> + } else {
> + val = wa->is_mcr ?
> + intel_gt_mcr_read_any_fw(wal->gt, wa->mcr_reg) :
> + intel_uncore_read_fw(uncore, wa->reg);
> + val &= ~wa->clr;
> + val |= wa->set;
> + }
> +
>   *cs++ = i915_mmio_reg_offset(wa->reg);
> - *cs++ = wa->set;
> + *cs++ = val;
>   }
>   *cs++ = MI_NOOP;
>  
> + intel_uncore_forcewake_put__locked(uncore, fw);
> + spin_unlock(>lock);
> + intel_gt_mcr_unlock(wal->gt, flags);
> +
>   intel_ring_advance(rq, cs);
>  
>   ret = rq->engine->emit_flush(rq, EMIT_BARRIER);
> 



signature.asc
Description: This is a digitally signed 

Re: [Intel-gfx] [PATCH v2 6/6] drm/i915/gt: Remove bogus comment on IVB_FBC_RT_BASE_UPPER

2023-06-27 Thread Kenneth Graunke
On Saturday, June 24, 2023 10:17:57 AM PDT Lucas De Marchi wrote:
> The comment on the parameter being 0 to avoid the read back doesn't
> apply as this is not a call to wa_mcr_add(), but rather to
> wa_mcr_clr_set(). So, this register is actually checked and it's
> according to the Bspec that the register is RW, not RO.

I think you mean wa_add and wa_write_clr_set here (not mcr).

One thing I've been confused about while reading this code:

static void
wa_write_clr_set(struct i915_wa_list *wal, i915_reg_t reg, u32 clear, u32 set)
{
wa_add(wal, reg, clear, set, clear, false);
}

The second to last parameter is read_mask aka wa->read.  We're
initializing it to the...bits to clear.  (I would think it should be
(clear | set) to pick up all modified bits.)

wa_verify seems to balk at ((cur ^ wa->set) & wa->read).  But...if
wa->read is just the clear mask, that wouldn't actually verify that
any bits were set at all.  Or am I misunderstanding something?

If not, we may be failing to verify the majority of our workarounds :(

> Signed-off-by: Lucas De Marchi 
> ---
>  drivers/gpu/drm/i915/gt/intel_workarounds.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c 
> b/drivers/gpu/drm/i915/gt/intel_workarounds.c
> index 848519b58e45..5fe85fad91c1 100644
> --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
> +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
> @@ -666,7 +666,7 @@ static void icl_ctx_workarounds_init(struct 
> intel_engine_cs *engine,
>   /* Wa_1604278689:icl,ehl */
>   wa_write(wal, IVB_FBC_RT_BASE, 0x & ~ILK_FBC_RT_VALID);
>   wa_write_clr_set(wal, IVB_FBC_RT_BASE_UPPER,
> -  0, /* write-only register; skip validation */
> +  0,
>0x);
>  
>   /* Wa_1406306137:icl,ehl */

In this particular example, since clear bits are 0, I don't think any
verification is happening at all.

--Ken


signature.asc
Description: This is a digitally signed message part.


[Intel-gfx] [PATCH] drm: Replace drm_framebuffer plane size functions with its equivalents

2023-06-27 Thread Carlos Eduardo Gallo Filho
The functions drm_framebuffer_plane{width,height} and
fb_plane_{width,height} do exactly the same job of its
equivalents drm_format_info_plane_{width,height} from drm_fourcc.

The only reason to have these functions on drm_framebuffer
would be if they would added a abstraction layer to call it just
passing a drm_framebuffer pointer and the desired plane index,
which is not the case, where these functions actually implements
just part of it. In the actual implementation, every call to both
drm_framebuffer_plane_{width,height} and fb_plane_{width,height} should
pass some drm_framebuffer attribute, which is the same as calling the
drm_format_info_plane_{width,height} functions.

The drm_format_info_pane_{width,height} functions are much more
consistent in both its implementation and its location on code. The
kind of calculation that they do is intrinsically derivated from the
drm_format_info struct and has not to do with drm_framebuffer, except
by the potential motivation described above, which is still not a good
justificative to have drm_framebuffer functions to calculate it.

So, replace each drm_framebuffer_plane_{width,height} and
fb_plane_{width,height} call to drm_format_info_plane_{width,height}
and remove them.

Signed-off-by: Carlos Eduardo Gallo Filho 
---
 drivers/gpu/drm/drm_framebuffer.c   | 64 ++---
 drivers/gpu/drm/i915/display/intel_fb.c |  2 +-
 include/drm/drm_framebuffer.h   |  5 --
 3 files changed, 5 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/drm_framebuffer.c 
b/drivers/gpu/drm/drm_framebuffer.c
index aff3746dedfb..efed4cd7965e 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -151,24 +151,6 @@ int drm_mode_addfb_ioctl(struct drm_device *dev,
return drm_mode_addfb(dev, data, file_priv);
 }
 
-static int fb_plane_width(int width,
- const struct drm_format_info *format, int plane)
-{
-   if (plane == 0)
-   return width;
-
-   return DIV_ROUND_UP(width, format->hsub);
-}
-
-static int fb_plane_height(int height,
-  const struct drm_format_info *format, int plane)
-{
-   if (plane == 0)
-   return height;
-
-   return DIV_ROUND_UP(height, format->vsub);
-}
-
 static int framebuffer_check(struct drm_device *dev,
 const struct drm_mode_fb_cmd2 *r)
 {
@@ -196,8 +178,8 @@ static int framebuffer_check(struct drm_device *dev,
info = drm_get_format_info(dev, r);
 
for (i = 0; i < info->num_planes; i++) {
-   unsigned int width = fb_plane_width(r->width, info, i);
-   unsigned int height = fb_plane_height(r->height, info, i);
+   unsigned int width = drm_format_info_plane_width(info, 
r->width, i);
+   unsigned int height = drm_format_info_plane_height(info, 
r->height, i);
unsigned int block_size = info->char_per_block[i];
u64 min_pitch = drm_format_info_min_pitch(info, i, width);
 
@@ -1136,44 +1118,6 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
 }
 EXPORT_SYMBOL(drm_framebuffer_remove);
 
-/**
- * drm_framebuffer_plane_width - width of the plane given the first plane
- * @width: width of the first plane
- * @fb: the framebuffer
- * @plane: plane index
- *
- * Returns:
- * The width of @plane, given that the width of the first plane is @width.
- */
-int drm_framebuffer_plane_width(int width,
-   const struct drm_framebuffer *fb, int plane)
-{
-   if (plane >= fb->format->num_planes)
-   return 0;
-
-   return fb_plane_width(width, fb->format, plane);
-}
-EXPORT_SYMBOL(drm_framebuffer_plane_width);
-
-/**
- * drm_framebuffer_plane_height - height of the plane given the first plane
- * @height: height of the first plane
- * @fb: the framebuffer
- * @plane: plane index
- *
- * Returns:
- * The height of @plane, given that the height of the first plane is @height.
- */
-int drm_framebuffer_plane_height(int height,
-const struct drm_framebuffer *fb, int plane)
-{
-   if (plane >= fb->format->num_planes)
-   return 0;
-
-   return fb_plane_height(height, fb->format, plane);
-}
-EXPORT_SYMBOL(drm_framebuffer_plane_height);
-
 void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
const struct drm_framebuffer *fb)
 {
@@ -1189,8 +1133,8 @@ void drm_framebuffer_print_info(struct drm_printer *p, 
unsigned int indent,
 
for (i = 0; i < fb->format->num_planes; i++) {
drm_printf_indent(p, indent + 1, "size[%u]=%dx%d\n", i,
- drm_framebuffer_plane_width(fb->width, fb, i),
- drm_framebuffer_plane_height(fb->height, fb, 
i));
+ drm_format_info_plane_width(fb->format, 
fb->width, i),
+ 

Re: [Intel-gfx] [PATCH 1/1] drm/i915/display: HDMI2.0/DP1p62Gbps skew violation when there is skew between DL PCLK

2023-06-27 Thread Imre Deak
On Tue, Jun 27, 2023 at 09:04:51PM +0530, Mitul Golani wrote:
> When doing type-C PHY voltage swing programming for HDMI and
> DP 1.62Gbps, program DKLP_PCS_GLUE_TX_DPCNTL2[loadgen_sharing_pmd_disable]
> to '1'. For other DP frequencies, program
> DKLP_PCS_GLUE_TX_DPCNTL2[loadgen_sharing_pmd_disable] to '0'.
> 
> This Workaround is specific to Display Version 13
> 
> Wa_15010727533
> 
> Signed-off-by: Mitul Golani 
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c | 13 +
>  drivers/gpu/drm/i915/i915_reg.h  |  6 ++
>  2 files changed, 19 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 61722556bb47..5a6f048f4f1c 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1362,6 +1362,19 @@ static void tgl_dkl_phy_set_signal_levels(struct 
> intel_encoder *encoder,
>   intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln),
> DKL_TX_DP20BITMODE, 0);
>  
> + if (DISPLAY_VER(dev_priv) == 13) {

The above check here is equivalent to IS_ALDERLAKE_P(), so the
programming should be done under that condition below, along with the
other bits in DKL_TX_DPCNTL2.

Also the WA is limited to STEP_A0 .. STEP_C0.

> + if ((crtc_state->port_clock == 594000 &&
> + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 
> ||
> + (crtc_state->port_clock == 162000 &&
> + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP))) {
> + intel_de_rmw(dev_priv, DKLP_TX_DPCNTL2(tc_port),
> +  LOADGEN_SHARING_PMD_DISABLE, 1);

Must use intel_dkl_phy_rmw() with DKL regs.

> + } else {
> + intel_de_rmw(dev_priv, DKLP_TX_DPCNTL2(tc_port),
> +  LOADGEN_SHARING_PMD_DISABLE, 0);
> + }
> + }
> +
>   if (IS_ALDERLAKE_P(dev_priv)) {
>   u32 val;
>  
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index dcf64e32cd54..5487301d4ad3 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -6663,4 +6663,10 @@ enum skl_power_gate {
>  
>  #define MTL_MEDIA_GSI_BASE   0x38
>  
> +#define _DKLP_PCS_GLUE_TX_DPCNTL20xB68

These registers are defined in intel_dkl_phy_regs.h.

Not sure about the above offset. There's been updates to the spec and I
think the last known good value is 0x02c8 defined at

Bspec 49295

That is just the already defined DKL_TX_DPCNTL2.

> +#define LOADGEN_SHARING_PMD_DISABLE  REG_BIT(2)

This doesn't seem to match either bspec 55359, where bit 2 is
cfg_dp20bitmode and bit 12 is loadgen_sharing_pmd_disable.

> +#define DKLP_TX_DPCNTL2(tc_port) _MMIO(_PORT(tc_port, \
> + _DKL_PHY1_BASE, \
> + _DKL_PHY2_BASE) + \
> + _DKLP_PCS_GLUE_TX_DPCNTL2)
>  #endif /* _I915_REG_H_ */
> -- 
> 2.25.1
> 


[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915/uncore: add intel_uncore_regs() helper

2023-06-27 Thread Patchwork
== Series Details ==

Series: drm/i915/uncore: add intel_uncore_regs() helper
URL   : https://patchwork.freedesktop.org/series/119907/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_13328 -> Patchwork_119907v1


Summary
---

  **SUCCESS**

  No regressions found.

  External URL: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/index.html

Participating hosts (40 -> 41)
--

  Additional (2): fi-apl-guc fi-pnv-d510 
  Missing(1): fi-snb-2520m 

Known issues


  Here are the changes found in Patchwork_119907v1 that come from known issues:

### IGT changes ###

 Issues hit 

  * igt@gem_exec_parallel@engines@basic:
- bat-mtlp-8: [PASS][1] -> [FAIL][2] ([i915#8386])
   [1]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-8/igt@gem_exec_parallel@engi...@basic.html
   [2]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/bat-mtlp-8/igt@gem_exec_parallel@engi...@basic.html

  * igt@gem_lmem_swapping@basic:
- fi-apl-guc: NOTRUN -> [SKIP][3] ([fdo#109271] / [i915#4613]) +3 
similar issues
   [3]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/fi-apl-guc/igt@gem_lmem_swapp...@basic.html

  * igt@i915_pm_rpm@basic-pci-d3-state:
- bat-mtlp-8: [PASS][4] -> [ABORT][5] ([i915#7077] / [i915#7977])
   [4]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-8/igt@i915_pm_...@basic-pci-d3-state.html
   [5]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/bat-mtlp-8/igt@i915_pm_...@basic-pci-d3-state.html

  * igt@i915_selftest@live@gt_heartbeat:
- fi-kbl-soraka:  [PASS][6] -> [DMESG-FAIL][7] ([i915#5334] / 
[i915#7872])
   [6]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/fi-kbl-soraka/igt@i915_selftest@live@gt_heartbeat.html
   [7]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/fi-kbl-soraka/igt@i915_selftest@live@gt_heartbeat.html

  * igt@i915_selftest@live@guc:
- bat-rpls-2: NOTRUN -> [DMESG-WARN][8] ([i915#7852])
   [8]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/bat-rpls-2/igt@i915_selftest@l...@guc.html

  * igt@i915_selftest@live@slpc:
- bat-rpls-2: NOTRUN -> [DMESG-WARN][9] ([i915#6367])
   [9]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/bat-rpls-2/igt@i915_selftest@l...@slpc.html

  * igt@kms_chamelium_hpd@vga-hpd-fast:
- fi-apl-guc: NOTRUN -> [SKIP][10] ([fdo#109271]) +21 similar issues
   [10]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/fi-apl-guc/igt@kms_chamelium_...@vga-hpd-fast.html

  * igt@kms_flip@basic-flip-vs-modeset@c-dp6:
- bat-adlp-11:[PASS][11] -> [FAIL][12] ([i915#6121]) +3 similar 
issues
   [11]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-adlp-11/igt@kms_flip@basic-flip-vs-mode...@c-dp6.html
   [12]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/bat-adlp-11/igt@kms_flip@basic-flip-vs-mode...@c-dp6.html

  * igt@kms_flip@basic-flip-vs-modeset@d-dp5:
- bat-adlp-11:[PASS][13] -> [DMESG-WARN][14] ([i915#6868])
   [13]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-adlp-11/igt@kms_flip@basic-flip-vs-mode...@d-dp5.html
   [14]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/bat-adlp-11/igt@kms_flip@basic-flip-vs-mode...@d-dp5.html

  * igt@kms_flip@basic-flip-vs-wf_vblank:
- bat-adlp-11:NOTRUN -> [SKIP][15] ([i915#3637])
   [15]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/bat-adlp-11/igt@kms_flip@basic-flip-vs-wf_vblank.html

  * igt@kms_psr@primary_page_flip:
- fi-pnv-d510:NOTRUN -> [SKIP][16] ([fdo#109271]) +37 similar issues
   [16]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/fi-pnv-d510/igt@kms_psr@primary_page_flip.html

  * igt@kms_setmode@basic-clone-single-crtc:
- fi-apl-guc: NOTRUN -> [SKIP][17] ([fdo#109271] / [i915#4579])
   [17]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/fi-apl-guc/igt@kms_setm...@basic-clone-single-crtc.html
- fi-pnv-d510:NOTRUN -> [SKIP][18] ([fdo#109271] / [i915#4579])
   [18]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/fi-pnv-d510/igt@kms_setm...@basic-clone-single-crtc.html

  
 Possible fixes 

  * igt@i915_selftest@live@gt_mocs:
- bat-mtlp-6: [DMESG-FAIL][19] ([i915#7059]) -> [PASS][20]
   [19]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-6/igt@i915_selftest@live@gt_mocs.html
   [20]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119907v1/bat-mtlp-6/igt@i915_selftest@live@gt_mocs.html

  * igt@i915_selftest@live@migrate:
- bat-dg2-11: [DMESG-WARN][21] ([i915#7699]) -> [PASS][22]
   [21]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-dg2-11/igt@i915_selftest@l...@migrate.html
   [22]: 

Re: [Intel-gfx] [PATCH v2 00/24] use vmalloc_array and vcalloc

2023-06-27 Thread patchwork-bot+netdevbpf
Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski :

On Tue, 27 Jun 2023 16:43:15 +0200 you wrote:
> The functions vmalloc_array and vcalloc were introduced in
> 
> commit a8749a35c399 ("mm: vmalloc: introduce array allocation functions")
> 
> but are not used much yet.  This series introduces uses of
> these functions, to protect against multiplication overflows.
> 
> [...]

Here is the summary with links:
  - [v2,02/24] octeon_ep: use vmalloc_array and vcalloc
https://git.kernel.org/netdev/net-next/c/32d462a5c3e5
  - [v2,04/24] gve: use vmalloc_array and vcalloc
https://git.kernel.org/netdev/net-next/c/a13de901e8d5
  - [v2,09/24] pds_core: use vmalloc_array and vcalloc
https://git.kernel.org/netdev/net-next/c/906a76cc7645
  - [v2,11/24] ionic: use vmalloc_array and vcalloc
https://git.kernel.org/netdev/net-next/c/f712c8297e0a
  - [v2,18/24] net: enetc: use vmalloc_array and vcalloc
https://git.kernel.org/netdev/net-next/c/fa87c54693ae
  - [v2,22/24] net: mana: use vmalloc_array and vcalloc
https://git.kernel.org/netdev/net-next/c/e9c74f8b8a31

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




Re: [Intel-gfx] [PATCH v13 22/22] docs: vfio: Add vfio device cdev description

2023-06-27 Thread Jason Gunthorpe
On Tue, Jun 27, 2023 at 08:54:33AM +, Liu, Yi L wrote:
> > From: Alex Williamson 
> > Sent: Thursday, June 22, 2023 5:54 AM
> > 
> > On Fri, 16 Jun 2023 02:39:46 -0700
> > Yi Liu  wrote:
> 
> > > +VFIO device cdev doesn't rely on VFIO group/container/iommu drivers.
> > > +Hence those modules can be fully compiled out in an environment
> > > +where no legacy VFIO application exists.
> > > +
> > > +So far SPAPR does not support IOMMUFD yet.  So it cannot support device
> > > +cdev either.
> > 
> > Why isn´t this enforced via Kconfig?  At the vfio level we could simply
> > add the following in patch 17/:
> > 
> > config VFIO_DEVICE_CDEV
> > bool "Support for the VFIO cdev /dev/vfio/devices/vfioX"
> > depends on IOMMUFD && !SPAPR_TCE_IOMMU
> >^^^
> > 
> > Or if Jason wants, IOMMUFD could depend on !SPAPR_TCE_IOMMU for now and
> > the existing Kconfig options would exclude it.  If we know it doesn't
> > work, let's not put the burden on the user to figure that out.  A
> > follow-up patch for this would be fine if there's no other reason to
> > respin the series.
> 
> @Jason,
> How about your opinion? Seems reasonable to make IOMMUFD
> depend on !SPAPR_TCE_IOMMU. Is it?

The right kconfig would be to list all the iommu drivers that can
support iommufd and allow it to be selected if any of them are
enabled.

This seems too complex to bother with, so I like Alex's version above..

> > Otherwise the series is looking pretty good to me.  It still requires
> > some reviews/acks in the iommufd space and it would be good to see more
> > reviews for the remainder given the amount of collaboration here.
> > 
> > I'm out for the rest of the week, but I'll leave open accepting this
> > and the hot-reset series next week for the merge window.  Thanks,
> 
> @Alex,
> Given Jason's remarks on cdev v12, I've already got a new version as below.
> I can post it once the above kconfig open is closed.

I think we don't need to bend the rules, Linus would not be happy to
see 30 major patches that never hit linux-next at all.

I'm happy if we put it on a branch at RC1 and merge it to the vfio &
iommufd trees, it is functionally the same outcome in the same time
frame.

Jason


[Intel-gfx] ✓ Fi.CI.BAT: success for Update AUX invalidation sequence (rev2)

2023-06-27 Thread Patchwork
== Series Details ==

Series: Update AUX invalidation sequence (rev2)
URL   : https://patchwork.freedesktop.org/series/119798/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_13328 -> Patchwork_119798v2


Summary
---

  **SUCCESS**

  No regressions found.

  External URL: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/index.html

Participating hosts (40 -> 41)
--

  Additional (2): fi-apl-guc fi-pnv-d510 
  Missing(1): fi-snb-2520m 

Known issues


  Here are the changes found in Patchwork_119798v2 that come from known issues:

### IGT changes ###

 Issues hit 

  * igt@gem_lmem_swapping@basic:
- fi-apl-guc: NOTRUN -> [SKIP][1] ([fdo#109271] / [i915#4613]) +3 
similar issues
   [1]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/fi-apl-guc/igt@gem_lmem_swapp...@basic.html

  * igt@i915_module_load@load:
- bat-mtlp-6: [PASS][2] -> [ABORT][3] ([i915#8141])
   [2]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-6/igt@i915_module_l...@load.html
   [3]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/bat-mtlp-6/igt@i915_module_l...@load.html
- bat-mtlp-8: [PASS][4] -> [ABORT][5] ([i915#8141])
   [4]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-mtlp-8/igt@i915_module_l...@load.html
   [5]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/bat-mtlp-8/igt@i915_module_l...@load.html

  * igt@i915_selftest@live@execlists:
- fi-bsw-nick:[PASS][6] -> [ABORT][7] ([i915#7911] / [i915#7913])
   [6]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/fi-bsw-nick/igt@i915_selftest@l...@execlists.html
   [7]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/fi-bsw-nick/igt@i915_selftest@l...@execlists.html

  * igt@i915_selftest@live@reset:
- bat-rpls-1: [PASS][8] -> [ABORT][9] ([i915#7461] / [i915#7981] / 
[i915#8347] / [i915#8384])
   [8]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-rpls-1/igt@i915_selftest@l...@reset.html
   [9]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/bat-rpls-1/igt@i915_selftest@l...@reset.html
- bat-rpls-2: NOTRUN -> [ABORT][10] ([i915#4983] / [i915#7461] / 
[i915#7913] / [i915#8347])
   [10]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/bat-rpls-2/igt@i915_selftest@l...@reset.html

  * igt@kms_chamelium_hpd@vga-hpd-fast:
- fi-apl-guc: NOTRUN -> [SKIP][11] ([fdo#109271]) +21 similar issues
   [11]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/fi-apl-guc/igt@kms_chamelium_...@vga-hpd-fast.html

  * igt@kms_cursor_legacy@basic-flip-before-cursor-atomic:
- bat-adlp-11:[PASS][12] -> [SKIP][13] ([i915#3546])
   [12]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-adlp-11/igt@kms_cursor_leg...@basic-flip-before-cursor-atomic.html
   [13]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/bat-adlp-11/igt@kms_cursor_leg...@basic-flip-before-cursor-atomic.html

  * igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-d-edp-1:
- bat-rplp-1: [PASS][14] -> [ABORT][15] ([i915#8442])
   [14]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-rplp-1/igt@kms_pipe_crc_basic@read-crc-frame-seque...@pipe-d-edp-1.html
   [15]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/bat-rplp-1/igt@kms_pipe_crc_basic@read-crc-frame-seque...@pipe-d-edp-1.html

  * igt@kms_psr@primary_page_flip:
- fi-pnv-d510:NOTRUN -> [SKIP][16] ([fdo#109271]) +37 similar issues
   [16]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/fi-pnv-d510/igt@kms_psr@primary_page_flip.html

  * igt@kms_setmode@basic-clone-single-crtc:
- fi-apl-guc: NOTRUN -> [SKIP][17] ([fdo#109271] / [i915#4579])
   [17]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/fi-apl-guc/igt@kms_setm...@basic-clone-single-crtc.html
- fi-pnv-d510:NOTRUN -> [SKIP][18] ([fdo#109271] / [i915#4579])
   [18]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/fi-pnv-d510/igt@kms_setm...@basic-clone-single-crtc.html

  
 Possible fixes 

  * igt@i915_selftest@live@migrate:
- bat-dg2-11: [DMESG-WARN][19] ([i915#7699]) -> [PASS][20]
   [19]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-dg2-11/igt@i915_selftest@l...@migrate.html
   [20]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/bat-dg2-11/igt@i915_selftest@l...@migrate.html

  * igt@i915_selftest@live@mman:
- bat-rpls-2: [TIMEOUT][21] ([i915#6794] / [i915#7392]) -> 
[PASS][22]
   [21]: 
https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13328/bat-rpls-2/igt@i915_selftest@l...@mman.html
   [22]: 
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_119798v2/bat-rpls-2/igt@i915_selftest@l...@mman.html

  * igt@kms_cursor_legacy@basic-flip-after-cursor-legacy:
- 

[Intel-gfx] ✗ Fi.CI.SPARSE: warning for Update AUX invalidation sequence (rev2)

2023-06-27 Thread Patchwork
== Series Details ==

Series: Update AUX invalidation sequence (rev2)
URL   : https://patchwork.freedesktop.org/series/119798/
State : warning

== Summary ==

Error: dim sparse failed
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'
+./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return'

Re: [Intel-gfx] [PATCH v8 1/2] drm/i915: preparation for using PAT index

2023-06-27 Thread Yang, Fei
> On 27/06/2023 14:28, Jani Nikula wrote:
>> On Tue, 09 May 2023, fei.y...@intel.com wrote:
>>> From: Fei Yang 
>>>
>>> This patch is a preparation for replacing enum i915_cache_level with
>>> PAT index. Caching policy for buffer objects is set through the PAT
>>> index in PTE, the old i915_cache_level is not sufficient to represent
>>> all caching modes supported by the hardware.
>>>
>>> Preparing the transition by adding some platform dependent data
>>> structures and helper functions to translate the cache_level to pat_index.
>>>
>>> cachelevel_to_pat: a platform dependent array mapping cache_level to
>>> pat_index.
>>>
>>> max_pat_index: the maximum PAT index recommended in hardware specification
>>> Needed for validating the PAT index passed in from user
>>> space.
>>>
>>> i915_gem_get_pat_index: function to convert cache_level to PAT index.
>>>
>>> obj_to_i915(obj): macro moved to header file for wider usage.
>>>
>>> I915_MAX_CACHE_LEVEL: upper bound of i915_cache_level for the
>>>convenience of coding.
>>>
>>> Cc: Chris Wilson 
>>> Cc: Matt Roper 
>>> Signed-off-by: Fei Yang 
>>> Reviewed-by: Andi Shyti 
>>> Reviewed-by: Andrzej Hajda 
>>
>> [snip]
>>
>>> diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
>>> b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
>>> index f6a7c0bd2955..0eda8b4ee17f 100644
>>> --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
>>> +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
>>> @@ -123,7 +123,9 @@ struct drm_i915_private *mock_gem_device(void)
>>> static struct dev_iommu fake_iommu = { .priv = (void *)-1 };
>>>   #endif
>>> struct drm_i915_private *i915;
>>> +   struct intel_device_info *i915_info;
>>> struct pci_dev *pdev;
>>> +   unsigned int i;
>>> int ret;
>>>
>>> pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); @@ -180,6 +182,13 @@
>>> struct drm_i915_private *mock_gem_device(void)
>>> I915_GTT_PAGE_SIZE_2M;
>>>
>>> RUNTIME_INFO(i915)->memory_regions = REGION_SMEM;
>>> +
>>> +   /* simply use legacy cache level for mock device */
>>> +   i915_info = (struct intel_device_info *)INTEL_INFO(i915);
>>
>> This is not okay. It's not okay to modify device info at runtime. This
>> is why we've separated runtime info from device info. This is why
>> we've made device info const, and localized the modifications to a
>> couple of places.
>>
>> If you need to modify it, it belongs in runtime info. Even if it's
>> only ever modified for mock devices.
>>
>> We were at the brink of being able to finally convert INTEL_INFO()
>> into a pointer to const rodata [1], where you are unable to modify it,
>> but this having been merged as commit 5e352e32aec2 ("drm/i915:
>> preparation for using PAT index") sets us back. (With [1] this oopses
>> trying to modify read-only data.)
>>
>> This has been posted to the public list 20+ times, and nobody noticed
>> or pointed this out?!
>>
>> Throwing away const should be a huge red flag to any developer or
>> reviewer. Hell, *any* cast should be.
>>
>> I've got a patch ready moving cachelevel_to_pat and max_pat_index to
>> runtime info. It's not great, since we'd be doing it only for the mock
>> device. Better ideas? I'm not waiting long.
>>
>>
>> BR,
>> Jani.
>>
>>
>> [1]
>> https://patchwork.freedesktop.org/patch/msgid/0badc36ce6dd6b030507bdfd
>> 8a42ab984fb38d12.1686236840.git.jani.nik...@intel.com
>>
>>
>>> +   i915_info->max_pat_index = 3;
>>> +   for (i = 0; i < I915_MAX_CACHE_LEVEL; i++)
>>> +   i915_info->cachelevel_to_pat[i] = i;
>>> +
>
> I'd simply suggest having a local static const table for the mock device.
> It should be trivial once i915->__info becomes a pointer so in that series
> I guess.
>
> While I am here - Fei - any plans to work on the promised cleanup?
> Abstracting the caching modes with a hw agnostic sw/driver representation,
> if you remember what we discussed.

Yes, I'm still working on that as a side task. Hopefully I would be able to
post something to the mailing list after the July 4th holiday.

> Regards,
>
> Tvrtko



[Intel-gfx] [PATCH 0/1] HDMI 2.0/DP1p62Gbps skew violation when there is skew between DL PCLK

2023-06-27 Thread Mitul Golani
When doing type-C PHY voltage swing programming for HDMI and DP 1.62Gbps,
program DKLP_PCS_GLUE_TX_DPCNTL2[loadgen_sharing_pmd_disable] to '1'.
For other DP frequencies, program 
DKLP_PCS_GLUE_TX_DPCNTL2[loadgen_sharing_pmd_disable]
to '0'.

This Workaround is specific to Display Version 13
Wa_15010727533

Signed-off-by: Mitul Golani 

Mitul Golani (1):
  drm/i915/display: HDMI2.0/DP1p62Gbps skew violation when there is skew
between DL PCLK

 drivers/gpu/drm/i915/display/intel_ddi.c | 13 +
 drivers/gpu/drm/i915/i915_reg.h  |  6 ++
 2 files changed, 19 insertions(+)

-- 
2.25.1



[Intel-gfx] [PATCH 1/1] drm/i915/display: HDMI2.0/DP1p62Gbps skew violation when there is skew between DL PCLK

2023-06-27 Thread Mitul Golani
When doing type-C PHY voltage swing programming for HDMI and
DP 1.62Gbps, program DKLP_PCS_GLUE_TX_DPCNTL2[loadgen_sharing_pmd_disable]
to '1'. For other DP frequencies, program
DKLP_PCS_GLUE_TX_DPCNTL2[loadgen_sharing_pmd_disable] to '0'.

This Workaround is specific to Display Version 13

Wa_15010727533

Signed-off-by: Mitul Golani 
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 13 +
 drivers/gpu/drm/i915/i915_reg.h  |  6 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 61722556bb47..5a6f048f4f1c 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1362,6 +1362,19 @@ static void tgl_dkl_phy_set_signal_levels(struct 
intel_encoder *encoder,
intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln),
  DKL_TX_DP20BITMODE, 0);
 
+   if (DISPLAY_VER(dev_priv) == 13) {
+   if ((crtc_state->port_clock == 594000 &&
+   intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 
||
+   (crtc_state->port_clock == 162000 &&
+   intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP))) {
+   intel_de_rmw(dev_priv, DKLP_TX_DPCNTL2(tc_port),
+LOADGEN_SHARING_PMD_DISABLE, 1);
+   } else {
+   intel_de_rmw(dev_priv, DKLP_TX_DPCNTL2(tc_port),
+LOADGEN_SHARING_PMD_DISABLE, 0);
+   }
+   }
+
if (IS_ALDERLAKE_P(dev_priv)) {
u32 val;
 
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index dcf64e32cd54..5487301d4ad3 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6663,4 +6663,10 @@ enum skl_power_gate {
 
 #define MTL_MEDIA_GSI_BASE 0x38
 
+#define _DKLP_PCS_GLUE_TX_DPCNTL2  0xB68
+#define LOADGEN_SHARING_PMD_DISABLEREG_BIT(2)
+#define DKLP_TX_DPCNTL2(tc_port)   _MMIO(_PORT(tc_port, \
+   _DKL_PHY1_BASE, \
+   _DKL_PHY2_BASE) + \
+   _DKLP_PCS_GLUE_TX_DPCNTL2)
 #endif /* _I915_REG_H_ */
-- 
2.25.1



Re: [Intel-gfx] [PATCH v8 1/2] drm/i915: preparation for using PAT index

2023-06-27 Thread Yang, Fei
> Hi Jani and Tvrtko,
>
 This patch is a preparation for replacing enum i915_cache_level with PAT
 index. Caching policy for buffer objects is set through the PAT index in
 PTE, the old i915_cache_level is not sufficient to represent all caching
 modes supported by the hardware.

 Preparing the transition by adding some platform dependent data structures
 and helper functions to translate the cache_level to pat_index.

 cachelevel_to_pat: a platform dependent array mapping cache_level to
 pat_index.

 max_pat_index: the maximum PAT index recommended in hardware specification
 Needed for validating the PAT index passed in from user
 space.

 i915_gem_get_pat_index: function to convert cache_level to PAT index.

 obj_to_i915(obj): macro moved to header file for wider usage.

 I915_MAX_CACHE_LEVEL: upper bound of i915_cache_level for the
convenience of coding.

 Cc: Chris Wilson 
 Cc: Matt Roper 
 Signed-off-by: Fei Yang 
 Reviewed-by: Andi Shyti 
 Reviewed-by: Andrzej Hajda 
>>>
>>> [snip]
>>>
 diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c 
 b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
 index f6a7c0bd2955..0eda8b4ee17f 100644
 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
 +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
 @@ -123,7 +123,9 @@ struct drm_i915_private *mock_gem_device(void)
static struct dev_iommu fake_iommu = { .priv = (void *)-1 };
   #endif
struct drm_i915_private *i915;
 + struct intel_device_info *i915_info;
struct pci_dev *pdev;
 + unsigned int i;
int ret;
pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
 @@ -180,6 +182,13 @@ struct drm_i915_private *mock_gem_device(void)
I915_GTT_PAGE_SIZE_2M;
RUNTIME_INFO(i915)->memory_regions = REGION_SMEM;
 +
 + /* simply use legacy cache level for mock device */
 + i915_info = (struct intel_device_info *)INTEL_INFO(i915);
>>>
>>> This is not okay. It's not okay to modify device info at runtime. This
>>> is why we've separated runtime info from device info. This is why we've
>>> made device info const, and localized the modifications to a couple of
>>> places.
>>>
>>> If you need to modify it, it belongs in runtime info. Even if it's only
>>> ever modified for mock devices.
>>>
>>> We were at the brink of being able to finally convert INTEL_INFO() into
>>> a pointer to const rodata [1], where you are unable to modify it, but
>>> this having been merged as commit 5e352e32aec2 ("drm/i915: preparation
>>> for using PAT index") sets us back. (With [1] this oopses trying to
>>> modify read-only data.)
>>>
>>> This has been posted to the public list 20+ times, and nobody noticed or
>>> pointed this out?!
>
> That's not cool, indeed.
>
>>> Throwing away const should be a huge red flag to any developer or
>>> reviewer. Hell, *any* cast should be.
>>>
>>> I've got a patch ready moving cachelevel_to_pat and max_pat_index to
>>> runtime info. It's not great, since we'd be doing it only for the mock
>>> device. Better ideas? I'm not waiting long.
>>>
>>>
>>> BR,
>>> Jani.
>>>
>>>
>>> [1] 
>>> https://patchwork.freedesktop.org/patch/msgid/0badc36ce6dd6b030507bdfd8a42ab984fb38d12.1686236840.git.jani.nik...@intel.com
>>>
>>>
 + i915_info->max_pat_index = 3;
 + for (i = 0; i < I915_MAX_CACHE_LEVEL; i++)
 + i915_info->cachelevel_to_pat[i] = i;
 +
>>
>> I'd simply suggest having a local static const table for the mock device. It
>> should be trivial once i915->__info becomes a pointer so in that series I
>> guess.
>
> Fei... do you have bandwidth to look into this or do you want me
> to try Tvrtko's suggestion out?

Please go ahead Andi if you have time to help on this.

> Thank you Jani for reporting it and thank you Tvrtko for
> proposing the fix.

Sorry for the trouble here.

> Andi



Re: [Intel-gfx] [PATCH v8 1/2] drm/i915: preparation for using PAT index

2023-06-27 Thread Jani Nikula
On Tue, 27 Jun 2023, Andi Shyti  wrote:
> Tvrtko wrote:
>> I'd simply suggest having a local static const table for the mock device. It
>> should be trivial once i915->__info becomes a pointer so in that series I
>> guess.

That's a great idea, thanks!

> Fei... do you have bandwidth to look into this or do you want me
> to try Tvrtko's suggestion out?

https://patchwork.freedesktop.org/patch/msgid/b0db62045a96a3fd4cf123685da88cc777f9b485.1687878757.git.jani.nik...@intel.com


BR,
Jani.

-- 
Jani Nikula, Intel Open Source Graphics Center


[Intel-gfx] [PATCH v2 6/6] drm/i915: make device info a const pointer to rodata

2023-06-27 Thread Jani Nikula
Finally we can get rid of the pseudo-const write-once device info, and
convert it into a const pointer to device info in rodata.

Cc: Matt Roper 
Cc: Lucas De Marchi 
Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/i915_drv.h  |  4 ++--
 drivers/gpu/drm/i915/intel_device_info.c | 17 -
 2 files changed, 6 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8947d1201298..682ef2b5c7d5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -203,7 +203,7 @@ struct drm_i915_private {
/* i915 device parameters */
struct i915_params params;
 
-   const struct intel_device_info __info; /* Use INTEL_INFO() to access. */
+   const struct intel_device_info *__info; /* Use INTEL_INFO() to access. 
*/
struct intel_runtime_info __runtime; /* Use RUNTIME_INFO() to access. */
struct intel_driver_caps caps;
 
@@ -415,7 +415,7 @@ static inline struct intel_gt *to_gt(struct 
drm_i915_private *i915)
 (engine__) && (engine__)->uabi_class == (class__); \
 (engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node)))
 
-#define INTEL_INFO(i915)   (&(i915)->__info)
+#define INTEL_INFO(i915)   ((i915)->__info)
 #define RUNTIME_INFO(i915) (&(i915)->__runtime)
 #define DISPLAY_INFO(i915) ((i915)->display.info.__device_info)
 #define DISPLAY_RUNTIME_INFO(i915) (&(i915)->display.info.__runtime_info)
diff --git a/drivers/gpu/drm/i915/intel_device_info.c 
b/drivers/gpu/drm/i915/intel_device_info.c
index 0740922cd71f..ea0ec6174ce5 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -364,13 +364,6 @@ void intel_device_info_runtime_init_early(struct 
drm_i915_private *i915)
intel_device_info_subplatform_init(i915);
 }
 
-/* FIXME: Remove this, and make device info a const pointer to rodata. */
-static struct intel_device_info *
-mkwrite_device_info(struct drm_i915_private *i915)
-{
-   return (struct intel_device_info *)INTEL_INFO(i915);
-}
-
 static const struct intel_display_device_info no_display = {};
 
 /**
@@ -430,26 +423,24 @@ void intel_device_info_driver_create(struct 
drm_i915_private *i915,
 u16 device_id,
 const struct intel_device_info *match_info)
 {
-   struct intel_device_info *info;
struct intel_runtime_info *runtime;
u16 ver, rel, step;
 
-   /* Setup the write-once "constant" device info */
-   info = mkwrite_device_info(i915);
-   memcpy(info, match_info, sizeof(*info));
+   /* Setup INTEL_INFO() */
+   i915->__info = match_info;
 
/* Initialize initial runtime info from static const data and pdev. */
runtime = RUNTIME_INFO(i915);
memcpy(runtime, _INFO(i915)->__runtime, sizeof(*runtime));
 
/* Probe display support */
-   i915->display.info.__device_info = intel_display_device_probe(i915, 
info->has_gmd_id,
+   i915->display.info.__device_info = intel_display_device_probe(i915, 
HAS_GMD_ID(i915),
  , 
, );
memcpy(DISPLAY_RUNTIME_INFO(i915),
   _INFO(i915)->__runtime_defaults,
   sizeof(*DISPLAY_RUNTIME_INFO(i915)));
 
-   if (info->has_gmd_id) {
+   if (HAS_GMD_ID(i915)) {
DISPLAY_RUNTIME_INFO(i915)->ip.ver = ver;
DISPLAY_RUNTIME_INFO(i915)->ip.rel = rel;
DISPLAY_RUNTIME_INFO(i915)->ip.step = step;
-- 
2.39.2



[Intel-gfx] [PATCH v2 4/6] drm/i915: fix display info usage

2023-06-27 Thread Jani Nikula
Prefer DISPLAY_INFO() over INTEL_INFO()->display.

Cc: Matt Roper 
Cc: Lucas De Marchi 
Reviewed-by: Matt Roper 
Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/display/intel_display.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.h 
b/drivers/gpu/drm/i915/display/intel_display.h
index 53ca0e4e2357..49ac8473b988 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -113,7 +113,7 @@ enum i9xx_plane_id {
 
 #define for_each_dbuf_slice(__dev_priv, __slice) \
for ((__slice) = DBUF_S1; (__slice) < I915_MAX_DBUF_SLICES; 
(__slice)++) \
-   for_each_if(INTEL_INFO(__dev_priv)->display->dbuf.slice_mask & 
BIT(__slice))
+   for_each_if(DISPLAY_INFO(__dev_priv)->dbuf.slice_mask & 
BIT(__slice))
 
 #define for_each_dbuf_slice_in_mask(__dev_priv, __slice, __mask) \
for_each_dbuf_slice((__dev_priv), (__slice)) \
-- 
2.39.2



[Intel-gfx] [PATCH v2 5/6] drm/i915: move display device and runtime info to struct intel_display

2023-06-27 Thread Jani Nikula
Continue moving all things display further into display files and
structures.

v2: Sort includes (Matt)

Cc: Matt Roper 
Cc: Lucas De Marchi 
Reviewed-by: Matt Roper 
Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/display/intel_display_core.h | 9 +
 drivers/gpu/drm/i915/i915_drv.h   | 5 ++---
 drivers/gpu/drm/i915/intel_device_info.c  | 7 +++
 drivers/gpu/drm/i915/intel_device_info.h  | 4 
 4 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h 
b/drivers/gpu/drm/i915/display/intel_display_core.h
index 8d2243c71dd8..c37d2c4bbf76 100644
--- a/drivers/gpu/drm/i915/display/intel_display_core.h
+++ b/drivers/gpu/drm/i915/display/intel_display_core.h
@@ -17,6 +17,7 @@
 #include 
 
 #include "intel_cdclk.h"
+#include "intel_display_device.h"
 #include "intel_display_limits.h"
 #include "intel_display_power.h"
 #include "intel_dpll_mgr.h"
@@ -429,6 +430,14 @@ struct intel_display {
u32 state;
} hti;
 
+   struct {
+   /* Access with DISPLAY_INFO() */
+   const struct intel_display_device_info *__device_info;
+
+   /* Access with DISPLAY_RUNTIME_INFO() */
+   struct intel_display_runtime_info __runtime_info;
+   } info;
+
struct {
bool false_color;
} ips;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 078720a52322..8947d1201298 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -205,7 +205,6 @@ struct drm_i915_private {
 
const struct intel_device_info __info; /* Use INTEL_INFO() to access. */
struct intel_runtime_info __runtime; /* Use RUNTIME_INFO() to access. */
-   struct intel_display_runtime_info __display_runtime; /* Access with 
DISPLAY_RUNTIME_INFO() */
struct intel_driver_caps caps;
 
struct i915_dsm dsm;
@@ -417,9 +416,9 @@ static inline struct intel_gt *to_gt(struct 
drm_i915_private *i915)
 (engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node)))
 
 #define INTEL_INFO(i915)   (&(i915)->__info)
-#define DISPLAY_INFO(i915) (INTEL_INFO(i915)->display)
 #define RUNTIME_INFO(i915) (&(i915)->__runtime)
-#define DISPLAY_RUNTIME_INFO(i915) (&(i915)->__display_runtime)
+#define DISPLAY_INFO(i915) ((i915)->display.info.__device_info)
+#define DISPLAY_RUNTIME_INFO(i915) (&(i915)->display.info.__runtime_info)
 #define DRIVER_CAPS(i915)  (&(i915)->caps)
 
 #define INTEL_DEVID(i915)  (RUNTIME_INFO(i915)->device_id)
diff --git a/drivers/gpu/drm/i915/intel_device_info.c 
b/drivers/gpu/drm/i915/intel_device_info.c
index b93ef5fc26f1..0740922cd71f 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -391,7 +391,6 @@ static const struct intel_display_device_info no_display = 
{};
  */
 void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
 {
-   struct intel_device_info *info = mkwrite_device_info(dev_priv);
struct intel_runtime_info *runtime = RUNTIME_INFO(dev_priv);
 
if (HAS_DISPLAY(dev_priv))
@@ -401,7 +400,7 @@ void intel_device_info_runtime_init(struct drm_i915_private 
*dev_priv)
if (!HAS_DISPLAY(dev_priv)) {
dev_priv->drm.driver_features &= ~(DRIVER_MODESET |
   DRIVER_ATOMIC);
-   info->display = _display;
+   dev_priv->display.info.__device_info = _display;
}
 
/* Disable nuclear pageflip by default on pre-g4x */
@@ -444,8 +443,8 @@ void intel_device_info_driver_create(struct 
drm_i915_private *i915,
memcpy(runtime, _INFO(i915)->__runtime, sizeof(*runtime));
 
/* Probe display support */
-   info->display = intel_display_device_probe(i915, info->has_gmd_id,
-  , , );
+   i915->display.info.__device_info = intel_display_device_probe(i915, 
info->has_gmd_id,
+ , 
, );
memcpy(DISPLAY_RUNTIME_INFO(i915),
   _INFO(i915)->__runtime_defaults,
   sizeof(*DISPLAY_RUNTIME_INFO(i915)));
diff --git a/drivers/gpu/drm/i915/intel_device_info.h 
b/drivers/gpu/drm/i915/intel_device_info.h
index 81bfd64717cf..dbfe6443457b 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -29,8 +29,6 @@
 
 #include "intel_step.h"
 
-#include "display/intel_display_device.h"
-
 #include "gt/intel_engine_types.h"
 #include "gt/intel_context_types.h"
 #include "gt/intel_sseu.h"
@@ -240,8 +238,6 @@ struct intel_device_info {
DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG);
 #undef DEFINE_FLAG
 
-   const struct intel_display_device_info *display;
-
/*
 * Initial runtime info. Do not access outside of i915_driver_create().
 */

[Intel-gfx] [PATCH v2 1/6] drm/i915: use mock device info for creating mock device

2023-06-27 Thread Jani Nikula
Instead of modifying the device info on the fly, use static const mock
device info.

It's not okay to modify device info at runtime; we've added separate
runtime info for info that needs to be modified at runtime. We've added
safeguards to device info to prevent it from being modified, but commit
5e352e32aec2 ("drm/i915: preparation for using PAT index") just cast the
const away and modified it anyway. This prevents device info from being
moved to rodata.

Fixes: 5e352e32aec2 ("drm/i915: preparation for using PAT index")
Suggested-by: Tvrtko Ursulin 
Cc: Fei Yang 
Cc: Andi Shyti 
Cc: Andrzej Hajda 
Cc: Matt Roper 
Signed-off-by: Jani Nikula 
---
 .../gpu/drm/i915/selftests/mock_gem_device.c  | 45 ++-
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c 
b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 09d4bbcdcdbf..4de6a4e8280d 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -118,15 +118,31 @@ static void mock_gt_probe(struct drm_i915_private *i915)
i915->gt[0]->name = "Mock GT";
 }
 
+static const struct intel_device_info mock_info = {
+   .__runtime.graphics.ip.ver = -1,
+   .__runtime.page_sizes = (I915_GTT_PAGE_SIZE_4K |
+I915_GTT_PAGE_SIZE_64K |
+I915_GTT_PAGE_SIZE_2M),
+   .__runtime.memory_regions = REGION_SMEM,
+   .__runtime.platform_engine_mask = BIT(0),
+
+   /* simply use legacy cache level for mock device */
+   .max_pat_index = 3,
+   .cachelevel_to_pat = {
+   [I915_CACHE_NONE]   = 0,
+   [I915_CACHE_LLC]= 1,
+   [I915_CACHE_L3_LLC] = 2,
+   [I915_CACHE_WT] = 3,
+   },
+};
+
 struct drm_i915_private *mock_gem_device(void)
 {
 #if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU)
static struct dev_iommu fake_iommu = { .priv = (void *)-1 };
 #endif
struct drm_i915_private *i915;
-   struct intel_device_info *i915_info;
struct pci_dev *pdev;
-   unsigned int i;
int ret;
 
pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
@@ -159,15 +175,18 @@ struct drm_i915_private *mock_gem_device(void)
 
pci_set_drvdata(pdev, i915);
 
+   /* Device parameters start as a copy of module parameters. */
+   i915_params_copy(>params, _modparams);
+
+   /* Set up device info and initial runtime info. */
+   intel_device_info_driver_create(i915, pdev->device, _info);
+
dev_pm_domain_set(>dev, _domain);
pm_runtime_enable(>dev);
pm_runtime_dont_use_autosuspend(>dev);
if (pm_runtime_enabled(>dev))
WARN_ON(pm_runtime_get_sync(>dev));
 
-
-   i915_params_copy(>params, _modparams);
-
intel_runtime_pm_init_early(>runtime_pm);
/* wakeref tracking has significant overhead */
i915->runtime_pm.no_wakeref_tracking = true;
@@ -175,21 +194,6 @@ struct drm_i915_private *mock_gem_device(void)
/* Using the global GTT may ask questions about KMS users, so prepare */
drm_mode_config_init(>drm);
 
-   RUNTIME_INFO(i915)->graphics.ip.ver = -1;
-
-   RUNTIME_INFO(i915)->page_sizes =
-   I915_GTT_PAGE_SIZE_4K |
-   I915_GTT_PAGE_SIZE_64K |
-   I915_GTT_PAGE_SIZE_2M;
-
-   RUNTIME_INFO(i915)->memory_regions = REGION_SMEM;
-
-   /* simply use legacy cache level for mock device */
-   i915_info = (struct intel_device_info *)INTEL_INFO(i915);
-   i915_info->max_pat_index = 3;
-   for (i = 0; i < I915_MAX_CACHE_LEVEL; i++)
-   i915_info->cachelevel_to_pat[i] = i;
-
intel_memory_regions_hw_probe(i915);
 
spin_lock_init(>gpu_error.lock);
@@ -223,7 +227,6 @@ struct drm_i915_private *mock_gem_device(void)
mock_init_ggtt(to_gt(i915));
to_gt(i915)->vm = i915_vm_get(_gt(i915)->ggtt->vm);
 
-   RUNTIME_INFO(i915)->platform_engine_mask = BIT(0);
to_gt(i915)->info.engine_mask = BIT(0);
 
to_gt(i915)->engine[RCS0] = mock_engine(i915, "mock", RCS0);
-- 
2.39.2



[Intel-gfx] [PATCH v2 3/6] drm/i915: separate display info printing from the rest

2023-06-27 Thread Jani Nikula
Add new function intel_display_device_info_print() and print the display
device info there instead of intel_device_info_print(). This also fixes
the display runtime info printing to use the actual runtime info instead
of the static defaults.

Cc: Matt Roper 
Cc: Lucas De Marchi 
Reviewed-by: Matt Roper 
Signed-off-by: Jani Nikula 
---
 .../drm/i915/display/intel_display_device.c   | 21 +++
 .../drm/i915/display/intel_display_device.h   |  5 +
 drivers/gpu/drm/i915/i915_debugfs.c   |  1 +
 drivers/gpu/drm/i915/i915_driver.c|  2 ++
 drivers/gpu/drm/i915/i915_gpu_error.c |  6 ++
 drivers/gpu/drm/i915/i915_gpu_error.h |  3 +++
 drivers/gpu/drm/i915/intel_device_info.c  | 20 --
 7 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c 
b/drivers/gpu/drm/i915/display/intel_display_device.c
index f87470da25d0..e4afa7334c82 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.c
+++ b/drivers/gpu/drm/i915/display/intel_display_device.c
@@ -981,3 +981,24 @@ void intel_display_device_info_runtime_init(struct 
drm_i915_private *i915)
 display_fused_off:
memset(display_runtime, 0, sizeof(*display_runtime));
 }
+
+void intel_display_device_info_print(const struct intel_display_device_info 
*info,
+const struct intel_display_runtime_info 
*runtime,
+struct drm_printer *p)
+{
+   if (runtime->ip.rel)
+   drm_printf(p, "display version: %u.%02u\n",
+  runtime->ip.ver,
+  runtime->ip.rel);
+   else
+   drm_printf(p, "display version: %u\n",
+  runtime->ip.ver);
+
+#define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, 
str_yes_no(info->name))
+   DEV_INFO_DISPLAY_FOR_EACH_FLAG(PRINT_FLAG);
+#undef PRINT_FLAG
+
+   drm_printf(p, "has_hdcp: %s\n", str_yes_no(runtime->has_hdcp));
+   drm_printf(p, "has_dmc: %s\n", str_yes_no(runtime->has_dmc));
+   drm_printf(p, "has_dsc: %s\n", str_yes_no(runtime->has_dsc));
+}
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h 
b/drivers/gpu/drm/i915/display/intel_display_device.h
index 5b8a46114439..3324bd453ca7 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -11,6 +11,7 @@
 #include "intel_display_limits.h"
 
 struct drm_i915_private;
+struct drm_printer;
 
 #define DEV_INFO_DISPLAY_FOR_EACH_FLAG(func) \
/* Keep in alphabetical order */ \
@@ -127,4 +128,8 @@ intel_display_device_probe(struct drm_i915_private *i915, 
bool has_gmdid,
   u16 *ver, u16 *rel, u16 *step);
 void intel_display_device_info_runtime_init(struct drm_i915_private *i915);
 
+void intel_display_device_info_print(const struct intel_display_device_info 
*info,
+const struct intel_display_runtime_info 
*runtime,
+struct drm_printer *p);
+
 #endif
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 76ccd4e03e31..4de44cf1026d 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -67,6 +67,7 @@ static int i915_capabilities(struct seq_file *m, void *data)
seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(i915));
 
intel_device_info_print(INTEL_INFO(i915), RUNTIME_INFO(i915), );
+   intel_display_device_info_print(DISPLAY_INFO(i915), 
DISPLAY_RUNTIME_INFO(i915), );
i915_print_iommu_status(i915, );
intel_gt_info_print(_gt(i915)->info, );
intel_driver_caps_print(>caps, );
diff --git a/drivers/gpu/drm/i915/i915_driver.c 
b/drivers/gpu/drm/i915/i915_driver.c
index 222d0a1f3b55..294b022de22b 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -711,6 +711,8 @@ static void i915_welcome_messages(struct drm_i915_private 
*dev_priv)
 
intel_device_info_print(INTEL_INFO(dev_priv),
RUNTIME_INFO(dev_priv), );
+   intel_display_device_info_print(DISPLAY_INFO(dev_priv),
+   DISPLAY_RUNTIME_INFO(dev_priv), 
);
i915_print_iommu_status(dev_priv, );
for_each_gt(gt, dev_priv, i)
intel_gt_info_print(>info, );
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index 4749f99e6320..92ca81f9feab 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -649,6 +649,8 @@ static void err_print_capabilities(struct 
drm_i915_error_state_buf *m,
struct drm_printer p = i915_error_printer(m);
 
intel_device_info_print(>device_info, >runtime_info, );
+   

[Intel-gfx] [PATCH v2 2/6] drm/i915: move platform_engine_mask and memory_regions to device info

2023-06-27 Thread Jani Nikula
The mock device creation was the only place that needed to modify
platform_engine_mask and memory_regions runtime. With mock_info in place
for mock devices, we can move them to device info.

Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/gt/intel_gt.c|  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c |  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc.c|  2 +-
 drivers/gpu/drm/i915/i915_drv.h   |  2 +-
 drivers/gpu/drm/i915/i915_pci.c   | 64 +--
 drivers/gpu/drm/i915/intel_device_info.c  |  2 +-
 drivers/gpu/drm/i915/intel_device_info.h  |  7 +-
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  4 +-
 8 files changed, 42 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index 7a008e829d4d..33a61046ba58 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -904,7 +904,7 @@ int intel_gt_probe_all(struct drm_i915_private *i915)
 */
gt->i915 = i915;
gt->name = "Primary GT";
-   gt->info.engine_mask = RUNTIME_INFO(i915)->platform_engine_mask;
+   gt->info.engine_mask = INTEL_INFO(i915)->platform_engine_mask;
 
gt_dbg(gt, "Setting up %s\n", gt->name);
ret = intel_gt_tile_setup(gt, phys_addr);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index 75a3a0790ef3..034b53a71541 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -99,7 +99,7 @@ static bool gsc_engine_supported(struct intel_gt *gt)
GEM_BUG_ON(!gt_is_root(gt) && !gt->info.engine_mask);
 
if (gt_is_root(gt))
-   mask = RUNTIME_INFO(gt->i915)->platform_engine_mask;
+   mask = INTEL_INFO(gt->i915)->platform_engine_mask;
else
mask = gt->info.engine_mask;
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 23aa1b0e0166..ba9e07fc2b57 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -267,7 +267,7 @@ static bool vcs_supported(struct intel_gt *gt)
GEM_BUG_ON(!gt_is_root(gt) && !gt->info.engine_mask);
 
if (gt_is_root(gt))
-   mask = RUNTIME_INFO(gt->i915)->platform_engine_mask;
+   mask = INTEL_INFO(gt->i915)->platform_engine_mask;
else
mask = gt->info.engine_mask;
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b4cf6f0f636d..078720a52322 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -839,7 +839,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
  */
 #define HAS_64K_PAGES(i915) (INTEL_INFO(i915)->has_64k_pages)
 
-#define HAS_REGION(i915, i) (RUNTIME_INFO(i915)->memory_regions & (i))
+#define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i))
 #define HAS_LMEM(i915) HAS_REGION(i915, REGION_LMEM)
 
 #define HAS_EXTRA_GT_LIST(i915)   (INTEL_INFO(i915)->extra_gt_list)
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 3d7a5db9833b..dea3609fc496 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -84,7 +84,7 @@ __diag_ignore_all("-Woverride-init", "Allow overriding 
inherited members");
.__runtime.page_sizes = I915_GTT_PAGE_SIZE_4K
 
 #define GEN_DEFAULT_REGIONS \
-   .__runtime.memory_regions = REGION_SMEM | REGION_STOLEN_SMEM
+   .memory_regions = REGION_SMEM | REGION_STOLEN_SMEM
 
 #define I830_FEATURES \
GEN(2), \
@@ -93,7 +93,7 @@ __diag_ignore_all("-Woverride-init", "Allow overriding 
inherited members");
.has_3d_pipeline = 1, \
.hws_needs_physical = 1, \
.unfenced_needs_alignment = 1, \
-   .__runtime.platform_engine_mask = BIT(RCS0), \
+   .platform_engine_mask = BIT(RCS0), \
.has_snoop = true, \
.has_coherent_ggtt = false, \
.dma_mask_size = 32, \
@@ -108,7 +108,7 @@ __diag_ignore_all("-Woverride-init", "Allow overriding 
inherited members");
.gpu_reset_clobbers_display = true, \
.hws_needs_physical = 1, \
.unfenced_needs_alignment = 1, \
-   .__runtime.platform_engine_mask = BIT(RCS0), \
+   .platform_engine_mask = BIT(RCS0), \
.has_snoop = true, \
.has_coherent_ggtt = false, \
.dma_mask_size = 32, \
@@ -140,7 +140,7 @@ static const struct intel_device_info i865g_info = {
 #define GEN3_FEATURES \
GEN(3), \
.gpu_reset_clobbers_display = true, \
-   .__runtime.platform_engine_mask = BIT(RCS0), \
+   .platform_engine_mask = BIT(RCS0), \
.has_3d_pipeline = 1, \
.has_snoop = true, \
.has_coherent_ggtt = true, \
@@ -203,7 +203,7 @@ static const struct intel_device_info pnv_m_info = {
 #define GEN4_FEATURES \
GEN(4), \
.gpu_reset_clobbers_display = true, \

[Intel-gfx] [PATCH v2 0/6] drm/i915: further device info fixes and cleanups

2023-06-27 Thread Jani Nikula
This is v2 of [1], fixing mock device init to not modify rodata.

BR,
Jani.


[1] https://patchwork.freedesktop.org/series/119086/


Jani Nikula (6):
  drm/i915: use mock device info for creating mock device
  drm/i915: move platform_engine_mask and memory_regions to device info
  drm/i915: separate display info printing from the rest
  drm/i915: fix display info usage
  drm/i915: move display device and runtime info to struct intel_display
  drm/i915: make device info a const pointer to rodata

 drivers/gpu/drm/i915/display/intel_display.h  |  2 +-
 .../gpu/drm/i915/display/intel_display_core.h |  9 +++
 .../drm/i915/display/intel_display_device.c   | 21 ++
 .../drm/i915/display/intel_display_device.h   |  5 ++
 drivers/gpu/drm/i915/gt/intel_gt.c|  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c |  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc.c|  2 +-
 drivers/gpu/drm/i915/i915_debugfs.c   |  1 +
 drivers/gpu/drm/i915/i915_driver.c|  2 +
 drivers/gpu/drm/i915/i915_drv.h   | 11 ++--
 drivers/gpu/drm/i915/i915_gpu_error.c |  6 ++
 drivers/gpu/drm/i915/i915_gpu_error.h |  3 +
 drivers/gpu/drm/i915/i915_pci.c   | 64 +--
 drivers/gpu/drm/i915/intel_device_info.c  | 44 ++---
 drivers/gpu/drm/i915/intel_device_info.h  | 11 +---
 .../gpu/drm/i915/selftests/mock_gem_device.c  | 45 +++--
 16 files changed, 122 insertions(+), 108 deletions(-)

-- 
2.39.2



Re: [Intel-gfx] [PATCH v8 1/2] drm/i915: preparation for using PAT index

2023-06-27 Thread Andi Shyti
Hi Jani and Tvrtko,

> > > This patch is a preparation for replacing enum i915_cache_level with PAT
> > > index. Caching policy for buffer objects is set through the PAT index in
> > > PTE, the old i915_cache_level is not sufficient to represent all caching
> > > modes supported by the hardware.
> > > 
> > > Preparing the transition by adding some platform dependent data structures
> > > and helper functions to translate the cache_level to pat_index.
> > > 
> > > cachelevel_to_pat: a platform dependent array mapping cache_level to
> > > pat_index.
> > > 
> > > max_pat_index: the maximum PAT index recommended in hardware specification
> > > Needed for validating the PAT index passed in from user
> > > space.
> > > 
> > > i915_gem_get_pat_index: function to convert cache_level to PAT index.
> > > 
> > > obj_to_i915(obj): macro moved to header file for wider usage.
> > > 
> > > I915_MAX_CACHE_LEVEL: upper bound of i915_cache_level for the
> > >convenience of coding.
> > > 
> > > Cc: Chris Wilson 
> > > Cc: Matt Roper 
> > > Signed-off-by: Fei Yang 
> > > Reviewed-by: Andi Shyti 
> > > Reviewed-by: Andrzej Hajda 
> > 
> > [snip]
> > 
> > > diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c 
> > > b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> > > index f6a7c0bd2955..0eda8b4ee17f 100644
> > > --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> > > +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> > > @@ -123,7 +123,9 @@ struct drm_i915_private *mock_gem_device(void)
> > >   static struct dev_iommu fake_iommu = { .priv = (void *)-1 };
> > >   #endif
> > >   struct drm_i915_private *i915;
> > > + struct intel_device_info *i915_info;
> > >   struct pci_dev *pdev;
> > > + unsigned int i;
> > >   int ret;
> > >   pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
> > > @@ -180,6 +182,13 @@ struct drm_i915_private *mock_gem_device(void)
> > >   I915_GTT_PAGE_SIZE_2M;
> > >   RUNTIME_INFO(i915)->memory_regions = REGION_SMEM;
> > > +
> > > + /* simply use legacy cache level for mock device */
> > > + i915_info = (struct intel_device_info *)INTEL_INFO(i915);
> > 
> > This is not okay. It's not okay to modify device info at runtime. This
> > is why we've separated runtime info from device info. This is why we've
> > made device info const, and localized the modifications to a couple of
> > places.
> > 
> > If you need to modify it, it belongs in runtime info. Even if it's only
> > ever modified for mock devices.
> > 
> > We were at the brink of being able to finally convert INTEL_INFO() into
> > a pointer to const rodata [1], where you are unable to modify it, but
> > this having been merged as commit 5e352e32aec2 ("drm/i915: preparation
> > for using PAT index") sets us back. (With [1] this oopses trying to
> > modify read-only data.)
> > 
> > This has been posted to the public list 20+ times, and nobody noticed or
> > pointed this out?!

That's not cool, indeed.

> > Throwing away const should be a huge red flag to any developer or
> > reviewer. Hell, *any* cast should be.
> > 
> > I've got a patch ready moving cachelevel_to_pat and max_pat_index to
> > runtime info. It's not great, since we'd be doing it only for the mock
> > device. Better ideas? I'm not waiting long.
> > 
> > 
> > BR,
> > Jani.
> > 
> > 
> > [1] 
> > https://patchwork.freedesktop.org/patch/msgid/0badc36ce6dd6b030507bdfd8a42ab984fb38d12.1686236840.git.jani.nik...@intel.com
> > 
> > 
> > > + i915_info->max_pat_index = 3;
> > > + for (i = 0; i < I915_MAX_CACHE_LEVEL; i++)
> > > + i915_info->cachelevel_to_pat[i] = i;
> > > +
> 
> I'd simply suggest having a local static const table for the mock device. It
> should be trivial once i915->__info becomes a pointer so in that series I
> guess.

Fei... do you have bandwidth to look into this or do you want me
to try Tvrtko's suggestion out?

Thank you Jani for reporting it and thank you Tvrtko for
proposing the fix.

Andi


[Intel-gfx] [PATCH v2 16/24] drm/i915/gvt: use vmalloc_array and vcalloc

2023-06-27 Thread Julia Lawall
Use vmalloc_array and vcalloc to protect against
multiplication overflows.

The changes were done using the following Coccinelle
semantic patch:

// 
@initialize:ocaml@
@@

let rename alloc =
  match alloc with
"vmalloc" -> "vmalloc_array"
  | "vzalloc" -> "vcalloc"
  | _ -> failwith "unknown"

@@
size_t e1,e2;
constant C1, C2;
expression E1, E2, COUNT, x1, x2, x3;
typedef u8;
typedef __u8;
type t = {u8,__u8,char,unsigned char};
identifier alloc = {vmalloc,vzalloc};
fresh identifier realloc = script:ocaml(alloc) { rename alloc };
@@

(
  alloc(x1*x2*x3)
|
  alloc(C1 * C2)
|
  alloc((sizeof(t)) * (COUNT), ...)
|
- alloc((e1) * (e2))
+ realloc(e1, e2)
|
- alloc((e1) * (COUNT))
+ realloc(COUNT, e1)
|
- alloc((E1) * (E2))
+ realloc(E1, E2)
)
// 

Signed-off-by: Julia Lawall 

---
v2: Use vmalloc_array and vcalloc instead of array_size.
This also leaves a multiplication of a constant by a sizeof
as is.  Two patches are thus dropped from the series.

 drivers/gpu/drm/i915/gvt/gtt.c |6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff -u -p a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -1969,14 +1969,16 @@ static struct intel_vgpu_mm *intel_vgpu_
return ERR_PTR(-ENOMEM);
}
 
-   mm->ggtt_mm.host_ggtt_aperture = vzalloc((vgpu_aperture_sz(vgpu) >> 
PAGE_SHIFT) * sizeof(u64));
+   mm->ggtt_mm.host_ggtt_aperture = vcalloc(vgpu_aperture_sz(vgpu) >> 
PAGE_SHIFT,
+sizeof(u64));
if (!mm->ggtt_mm.host_ggtt_aperture) {
vfree(mm->ggtt_mm.virtual_ggtt);
vgpu_free_mm(mm);
return ERR_PTR(-ENOMEM);
}
 
-   mm->ggtt_mm.host_ggtt_hidden = vzalloc((vgpu_hidden_sz(vgpu) >> 
PAGE_SHIFT) * sizeof(u64));
+   mm->ggtt_mm.host_ggtt_hidden = vcalloc(vgpu_hidden_sz(vgpu) >> 
PAGE_SHIFT,
+  sizeof(u64));
if (!mm->ggtt_mm.host_ggtt_hidden) {
vfree(mm->ggtt_mm.host_ggtt_aperture);
vfree(mm->ggtt_mm.virtual_ggtt);



[Intel-gfx] [PATCH v2 00/24] use vmalloc_array and vcalloc

2023-06-27 Thread Julia Lawall
The functions vmalloc_array and vcalloc were introduced in

commit a8749a35c399 ("mm: vmalloc: introduce array allocation functions")

but are not used much yet.  This series introduces uses of
these functions, to protect against multiplication overflows.

The changes were done using the following Coccinelle semantic
patch.

@initialize:ocaml@
@@

let rename alloc =
  match alloc with
"vmalloc" -> "vmalloc_array"
  | "vzalloc" -> "vcalloc"
  | _ -> failwith "unknown"

@@
size_t e1,e2;
constant C1, C2;
expression E1, E2, COUNT, x1, x2, x3;
typedef u8;
typedef __u8;
type t = {u8,__u8,char,unsigned char};
identifier alloc = {vmalloc,vzalloc};
fresh identifier realloc = script:ocaml(alloc) { rename alloc };
@@

(
  alloc(x1*x2*x3)
|
  alloc(C1 * C2)
|
  alloc((sizeof(t)) * (COUNT), ...)
|
- alloc((e1) * (e2))
+ realloc(e1, e2)
|
- alloc((e1) * (COUNT))
+ realloc(COUNT, e1)
|
- alloc((E1) * (E2))
+ realloc(E1, E2)
)

v2: This series uses vmalloc_array and vcalloc instead of
array_size.  It also leaves a multiplication of a constant by a
sizeof as is.  Two patches are thus dropped from the series.

---

 arch/x86/kernel/cpu/sgx/main.c|2 +-
 drivers/accel/habanalabs/common/device.c  |3 ++-
 drivers/accel/habanalabs/common/state_dump.c  |7 ---
 drivers/bus/mhi/host/init.c   |2 +-
 drivers/comedi/comedi_buf.c   |4 ++--
 drivers/dma-buf/heaps/system_heap.c   |2 +-
 drivers/gpu/drm/gud/gud_pipe.c|2 +-
 drivers/gpu/drm/i915/gvt/gtt.c|6 --
 drivers/infiniband/hw/bnxt_re/qplib_res.c |4 ++--
 drivers/infiniband/hw/erdma/erdma_verbs.c |4 ++--
 drivers/infiniband/sw/siw/siw_qp.c|4 ++--
 drivers/infiniband/sw/siw/siw_verbs.c |6 +++---
 drivers/iommu/tegra-gart.c|4 ++--
 drivers/net/ethernet/amd/pds_core/core.c  |4 ++--
 drivers/net/ethernet/freescale/enetc/enetc.c  |4 ++--
 drivers/net/ethernet/google/gve/gve_tx.c  |2 +-
 drivers/net/ethernet/marvell/octeon_ep/octep_rx.c |2 +-
 drivers/net/ethernet/microsoft/mana/hw_channel.c  |2 +-
 drivers/net/ethernet/pensando/ionic/ionic_lif.c   |4 ++--
 drivers/scsi/fnic/fnic_trace.c|2 +-
 drivers/scsi/qla2xxx/qla_init.c   |4 ++--
 drivers/vdpa/vdpa_user/iova_domain.c  |4 ++--
 drivers/virtio/virtio_mem.c   |6 +++---
 fs/btrfs/zoned.c  |4 ++--
 kernel/kcov.c |2 +-
 lib/test_vmalloc.c|9 +
 26 files changed, 52 insertions(+), 47 deletions(-)


Re: [Intel-gfx] [PATCH 24/29] mm: vmscan: make global slab shrink lockless

2023-06-27 Thread Qi Zheng




On 2023/6/24 19:08, Qi Zheng wrote:

Hi Dave,

On 2023/6/24 06:19, Dave Chinner wrote:

On Fri, Jun 23, 2023 at 09:10:57PM +0800, Qi Zheng wrote:

On 2023/6/23 14:29, Dave Chinner wrote:

On Thu, Jun 22, 2023 at 05:12:02PM +0200, Vlastimil Babka wrote:

On 6/22/23 10:53, Qi Zheng wrote:

Yes, I suggested the IDR route because radix tree lookups under RCU
with reference counted objects are a known safe pattern that we can
easily confirm is correct or not.  Hence I suggested the unification
+ IDR route because it makes the life of reviewers so, so much
easier...


In fact, I originally planned to try the unification + IDR method you
suggested at the beginning. But in the case of CONFIG_MEMCG disabled,
the struct mem_cgroup is not even defined, and root_mem_cgroup and
shrinker_info will not be allocated.  This required more code 
changes, so

I ended up keeping the shrinker_list and implementing the above pattern.


Yes. Go back and read what I originally said needed to be done
first. In the case of CONFIG_MEMCG=n, a dummy root memcg still needs
to exist that holds all of the global shrinkers. Then shrink_slab()
is only ever passed a memcg that should be iterated.

Yes, it needs changes external to the shrinker code itself to be
made to work. And even if memcg's are not enabled, we can still use
the memcg structures to ensure a common abstraction is used for the
shrinker tracking infrastructure


Yeah, what I imagined before was to define a more concise struct
mem_cgroup in the case of CONFIG_MEMCG=n, then allocate a dummy root
memcg on system boot:

#ifdef !CONFIG_MEMCG

struct shrinker_info {
 struct rcu_head rcu;
 atomic_long_t *nr_deferred;
 unsigned long *map;
 int map_nr_max;
};

struct mem_cgroup_per_node {
 struct shrinker_info __rcu    *shrinker_info;
};

struct mem_cgroup {
 struct mem_cgroup_per_node *nodeinfo[];
};

#endif

But I have a concern: if all global shrinkers are tracking with the
info->map of root memcg, a shrinker->id needs to be assigned to them,
which will cause info->map_nr_max to become larger than before, then
making the traversal of info->map slower.


But most of the system is 'sb-xxx' shrinker instances, they all have
the SHRINKER_MEMCG_AWARE flag, so it should have little impact on the
speed of traversing info->map. ;)






If the above pattern is not safe, I will go back to the unification +
IDR method.


And that is exactly how we got into this mess in the first place


I only found one similar pattern in the kernel:

fs/smb/server/oplock.c:find_same_lease_key/smb_break_all_levII_oplock/lookup_lease_in_table

But IIUC, the refcount here needs to be decremented after holding
rcu lock as I did above.

So regardless of whether we choose unification + IDR in the end, I still
want to confirm whether the pattern I implemented above is safe. :)


Also + RCU mailing list.



Thanks,
Qi



-Dave


[Intel-gfx] [PATCH 14/29] jbd2, ext4: dynamically allocate the jbd2-journal shrinker

2023-06-27 Thread Qi Zheng
From: Qi Zheng 

In preparation for implementing lockless slab shrink,
we need to dynamically allocate the jbd2-journal shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct journal_s.

Signed-off-by: Qi Zheng 
---
 fs/jbd2/journal.c| 32 +++-
 include/linux/jbd2.h |  2 +-
 2 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index eee3c0ae349a..92a2f4360b5f 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1301,7 +1301,7 @@ static int jbd2_min_tag_size(void)
 static unsigned long jbd2_journal_shrink_scan(struct shrinker *shrink,
  struct shrink_control *sc)
 {
-   journal_t *journal = container_of(shrink, journal_t, j_shrinker);
+   journal_t *journal = shrink->private_data;
unsigned long nr_to_scan = sc->nr_to_scan;
unsigned long nr_shrunk;
unsigned long count;
@@ -1327,7 +1327,7 @@ static unsigned long jbd2_journal_shrink_scan(struct 
shrinker *shrink,
 static unsigned long jbd2_journal_shrink_count(struct shrinker *shrink,
   struct shrink_control *sc)
 {
-   journal_t *journal = container_of(shrink, journal_t, j_shrinker);
+   journal_t *journal = shrink->private_data;
unsigned long count;
 
count = percpu_counter_read_positive(>j_checkpoint_jh_count);
@@ -1415,21 +1415,27 @@ static journal_t *journal_init_common(struct 
block_device *bdev,
journal->j_superblock = (journal_superblock_t *)bh->b_data;
 
journal->j_shrink_transaction = NULL;
-   journal->j_shrinker.scan_objects = jbd2_journal_shrink_scan;
-   journal->j_shrinker.count_objects = jbd2_journal_shrink_count;
-   journal->j_shrinker.seeks = DEFAULT_SEEKS;
-   journal->j_shrinker.batch = journal->j_max_transaction_buffers;
 
if (percpu_counter_init(>j_checkpoint_jh_count, 0, GFP_KERNEL))
goto err_cleanup;
 
-   if (register_shrinker(>j_shrinker, "jbd2-journal:(%u:%u)",
- MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev))) {
-   percpu_counter_destroy(>j_checkpoint_jh_count);
-   goto err_cleanup;
-   }
+   journal->j_shrinker = shrinker_alloc_and_init(jbd2_journal_shrink_count,
+ jbd2_journal_shrink_scan,
+ 
journal->j_max_transaction_buffers,
+ DEFAULT_SEEKS, 0, 
journal);
+   if (!journal->j_shrinker)
+   goto err_shrinker;
+
+   if (register_shrinker(journal->j_shrinker, "jbd2-journal:(%u:%u)",
+ MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)))
+   goto err_register;
+
return journal;
 
+err_register:
+   shrinker_free(journal->j_shrinker);
+err_shrinker:
+   percpu_counter_destroy(>j_checkpoint_jh_count);
 err_cleanup:
brelse(journal->j_sb_buffer);
kfree(journal->j_wbuf);
@@ -2190,9 +2196,9 @@ int jbd2_journal_destroy(journal_t *journal)
brelse(journal->j_sb_buffer);
}
 
-   if (journal->j_shrinker.flags & SHRINKER_REGISTERED) {
+   if (journal->j_shrinker->flags & SHRINKER_REGISTERED) {
percpu_counter_destroy(>j_checkpoint_jh_count);
-   unregister_shrinker(>j_shrinker);
+   unregister_and_free_shrinker(journal->j_shrinker);
}
if (journal->j_proc_entry)
jbd2_stats_proc_exit(journal);
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 44c298aa58d4..beb4c4586320 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -891,7 +891,7 @@ struct journal_s
 * Journal head shrinker, reclaim buffer's journal head which
 * has been written back.
 */
-   struct shrinker j_shrinker;
+   struct shrinker *j_shrinker;
 
/**
 * @j_checkpoint_jh_count:
-- 
2.30.2



Re: [Intel-gfx] [PATCH 29/29] mm: shrinker: move shrinker-related code into a separate file

2023-06-27 Thread Qi Zheng

Hi Sergey,

On 2023/6/23 13:25, Sergey Senozhatsky wrote:

On (23/06/22 16:53), Qi Zheng wrote:

+/*
+ * Remove one
+ */
+void unregister_shrinker(struct shrinker *shrinker)
+{
+   struct dentry *debugfs_entry;
+   int debugfs_id;
+
+   if (!(shrinker->flags & SHRINKER_REGISTERED))
+   return;
+
+   shrinker_put(shrinker);
+   wait_for_completion(>completion_wait);
+
+   mutex_lock(_mutex);
+   list_del_rcu(>list);


Should this function wait for RCU grace period(s) before it goes
touching shrinker fields?


Why? We will free this shrinker instance by rcu after executing
unregister_shrinker(). So it is safe to touch shrinker fields here.




+   shrinker->flags &= ~SHRINKER_REGISTERED;
+   if (shrinker->flags & SHRINKER_MEMCG_AWARE)
+   unregister_memcg_shrinker(shrinker);
+   debugfs_entry = shrinker_debugfs_detach(shrinker, _id);
+   mutex_unlock(_mutex);
+
+   shrinker_debugfs_remove(debugfs_entry, debugfs_id);
+
+   kfree(shrinker->nr_deferred);
+   shrinker->nr_deferred = NULL;
+}
+EXPORT_SYMBOL(unregister_shrinker);


[..]


+void shrinker_free(struct shrinker *shrinker)
+{
+   kfree(shrinker);
+}
+EXPORT_SYMBOL(shrinker_free);
+
+void unregister_and_free_shrinker(struct shrinker *shrinker)
+{
+   unregister_shrinker(shrinker);
+   kfree_rcu(shrinker, rcu);
+}


Seems like this

unregister_shrinker();
shrinker_free();

is not exact equivalent of this

unregister_and_free_shrinker();


Yes, my original intention is that shrinker_free() is only used to
handle the case where register_shrinker() returns failure.

I will implement the method suggested by Dave in 02/29. Those APIs are
more concise and will bring more benefits. :)

Thanks,
Qi





Re: [Intel-gfx] [PATCH 15/29] NFSD: dynamically allocate the nfsd-client shrinker

2023-06-27 Thread Chuck Lever
On Thu, Jun 22, 2023 at 04:53:21PM +0800, Qi Zheng wrote:
> In preparation for implementing lockless slab shrink,
> we need to dynamically allocate the nfsd-client shrinker,
> so that it can be freed asynchronously using kfree_rcu().
> Then it doesn't need to wait for RCU read-side critical
> section when releasing the struct nfsd_net.
> 
> Signed-off-by: Qi Zheng 

For 15/29 and 16/29 of this series:

Acked-by: Chuck Lever 


> ---
>  fs/nfsd/netns.h |  2 +-
>  fs/nfsd/nfs4state.c | 20 
>  2 files changed, 13 insertions(+), 9 deletions(-)
> 
> diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
> index ec49b200b797..f669444d5336 100644
> --- a/fs/nfsd/netns.h
> +++ b/fs/nfsd/netns.h
> @@ -195,7 +195,7 @@ struct nfsd_net {
>   int nfs4_max_clients;
>  
>   atomic_tnfsd_courtesy_clients;
> - struct shrinker nfsd_client_shrinker;
> + struct shrinker *nfsd_client_shrinker;
>   struct work_struct  nfsd_shrinker_work;
>  };
>  
> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> index 6e61fa3acaf1..a06184270548 100644
> --- a/fs/nfsd/nfs4state.c
> +++ b/fs/nfsd/nfs4state.c
> @@ -4388,8 +4388,7 @@ static unsigned long
>  nfsd4_state_shrinker_count(struct shrinker *shrink, struct shrink_control 
> *sc)
>  {
>   int count;
> - struct nfsd_net *nn = container_of(shrink,
> - struct nfsd_net, nfsd_client_shrinker);
> + struct nfsd_net *nn = shrink->private_data;
>  
>   count = atomic_read(>nfsd_courtesy_clients);
>   if (!count)
> @@ -8094,14 +8093,19 @@ static int nfs4_state_create_net(struct net *net)
>   INIT_WORK(>nfsd_shrinker_work, nfsd4_state_shrinker_worker);
>   get_net(net);
>  
> - nn->nfsd_client_shrinker.scan_objects = nfsd4_state_shrinker_scan;
> - nn->nfsd_client_shrinker.count_objects = nfsd4_state_shrinker_count;
> - nn->nfsd_client_shrinker.seeks = DEFAULT_SEEKS;
> -
> - if (register_shrinker(>nfsd_client_shrinker, "nfsd-client"))
> + nn->nfsd_client_shrinker = 
> shrinker_alloc_and_init(nfsd4_state_shrinker_count,
> +
> nfsd4_state_shrinker_scan,
> +0, DEFAULT_SEEKS, 0,
> +nn);
> + if (!nn->nfsd_client_shrinker)
>   goto err_shrinker;
> +
> + if (register_shrinker(nn->nfsd_client_shrinker, "nfsd-client"))
> + goto err_register;
>   return 0;
>  
> +err_register:
> + shrinker_free(nn->nfsd_client_shrinker);
>  err_shrinker:
>   put_net(net);
>   kfree(nn->sessionid_hashtbl);
> @@ -8197,7 +8201,7 @@ nfs4_state_shutdown_net(struct net *net)
>   struct list_head *pos, *next, reaplist;
>   struct nfsd_net *nn = net_generic(net, nfsd_net_id);
>  
> - unregister_shrinker(>nfsd_client_shrinker);
> + unregister_and_free_shrinker(nn->nfsd_client_shrinker);
>   cancel_work(>nfsd_shrinker_work);
>   cancel_delayed_work_sync(>laundromat_work);
>   locks_end_grace(>nfsd4_manager);
> -- 
> 2.30.2
> 


Re: [Intel-gfx] [PATCH 24/29] mm: vmscan: make global slab shrink lockless

2023-06-27 Thread Qi Zheng




On 2023/6/22 23:12, Vlastimil Babka wrote:

On 6/22/23 10:53, Qi Zheng wrote:

The shrinker_rwsem is a global read-write lock in
shrinkers subsystem, which protects most operations
such as slab shrink, registration and unregistration
of shrinkers, etc. This can easily cause problems in
the following cases.

1) When the memory pressure is high and there are many
filesystems mounted or unmounted at the same time,
slab shrink will be affected (down_read_trylock()
failed).

Such as the real workload mentioned by Kirill Tkhai:

```
One of the real workloads from my experience is start
of an overcommitted node containing many starting
containers after node crash (or many resuming containers
after reboot for kernel update). In these cases memory
pressure is huge, and the node goes round in long reclaim.
```

2) If a shrinker is blocked (such as the case mentioned
in [1]) and a writer comes in (such as mount a fs),
then this writer will be blocked and cause all
subsequent shrinker-related operations to be blocked.

Even if there is no competitor when shrinking slab, there
may still be a problem. If we have a long shrinker list
and we do not reclaim enough memory with each shrinker,
then the down_read_trylock() may be called with high
frequency. Because of the poor multicore scalability of
atomic operations, this can lead to a significant drop
in IPC (instructions per cycle).

We used to implement the lockless slab shrink with
SRCU [1], but then kernel test robot reported -88.8%
regression in stress-ng.ramfs.ops_per_sec test case [2],
so we reverted it [3].

This commit uses the refcount+RCU method [4] proposed by
by Dave Chinner to re-implement the lockless global slab
shrink. The memcg slab shrink is handled in the subsequent
patch.

Currently, the shrinker instances can be divided into
the following three types:

a) global shrinker instance statically defined in the kernel,
such as workingset_shadow_shrinker.

b) global shrinker instance statically defined in the kernel
modules, such as mmu_shrinker in x86.

c) shrinker instance embedded in other structures.

For case a, the memory of shrinker instance is never freed.
For case b, the memory of shrinker instance will be freed
after the module is unloaded. But we will call synchronize_rcu()
in free_module() to wait for RCU read-side critical section to
exit. For case c, the memory of shrinker instance will be
dynamically freed by calling kfree_rcu(). So we can use
rcu_read_{lock,unlock}() to ensure that the shrinker instance
is valid.

The shrinker::refcount mechanism ensures that the shrinker
instance will not be run again after unregistration. So the
structure that records the pointer of shrinker instance can be
safely freed without waiting for the RCU read-side critical
section.

In this way, while we implement the lockless slab shrink, we
don't need to be blocked in unregister_shrinker() to wait
RCU read-side critical section.

The following are the test results:

stress-ng --timeout 60 --times --verify --metrics-brief --ramfs 9 &

1) Before applying this patchset:

  setting to a 60 second run per stressor
  dispatching hogs: 9 ramfs
  stressor   bogo ops real time  usr time  sys time   bogo ops/s bogo 
ops/s
(secs)(secs)(secs)   (real time) (usr+sys 
time)
  ramfs880623 60.02  7.71226.93 14671.45
3753.09
  ramfs:
   1 System Management Interrupt
  for a 60.03s run time:
 5762.40s available CPU time
7.71s user time   (  0.13%)
  226.93s system time (  3.94%)
  234.64s total time  (  4.07%)
  load average: 8.54 3.06 2.11
  passed: 9: ramfs (9)
  failed: 0
  skipped: 0
  successful run completed in 60.03s (1 min, 0.03 secs)

2) After applying this patchset:

  setting to a 60 second run per stressor
  dispatching hogs: 9 ramfs
  stressor   bogo ops real time  usr time  sys time   bogo ops/s bogo 
ops/s
(secs)(secs)(secs)   (real time) (usr+sys 
time)
  ramfs847562 60.02  7.44230.22 14120.66
3566.23
  ramfs:
   4 System Management Interrupts
  for a 60.12s run time:
 5771.95s available CPU time
7.44s user time   (  0.13%)
  230.22s system time (  3.99%)
  237.66s total time  (  4.12%)
  load average: 8.18 2.43 0.84
  passed: 9: ramfs (9)
  failed: 0
  skipped: 0
  successful run completed in 60.12s (1 min, 0.12 secs)

We can see that the ops/s has hardly changed.

[1]. 
https://lore.kernel.org/lkml/20230313112819.38938-1-zhengqi.a...@bytedance.com/
[2]. https://lore.kernel.org/lkml/202305230837.db2c233f-yujie@intel.com/
[3]. https://lore.kernel.org/all/20230609081518.3039120-1-qi.zh...@linux.dev/
[4]. https://lore.kernel.org/lkml/zijhou1d55d4h...@dread.disaster.area/

Signed-off-by: Qi Zheng 
---
  include/linux/shrinker.h |  6 ++
  mm/vmscan.c  | 33 

[Intel-gfx] [PATCH 21/29] fs: super: dynamically allocate the s_shrink

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the s_shrink, so that
it can be freed asynchronously using kfree_rcu(). Then
it doesn't need to wait for RCU read-side critical
section when releasing the struct super_block.

Signed-off-by: Qi Zheng 
---
 fs/btrfs/super.c   |  2 +-
 fs/kernfs/mount.c  |  2 +-
 fs/proc/root.c |  2 +-
 fs/super.c | 38 ++
 include/linux/fs.h |  2 +-
 5 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index f1dd172d8d5b..fad4ded26c80 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1513,7 +1513,7 @@ static struct dentry *btrfs_mount_root(struct 
file_system_type *fs_type,
error = -EBUSY;
} else {
snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
-   shrinker_debugfs_rename(>s_shrink, "sb-%s:%s", fs_type->name,
+   shrinker_debugfs_rename(s->s_shrink, "sb-%s:%s", fs_type->name,
s->s_id);
btrfs_sb(s)->bdev_holder = fs_type;
error = btrfs_fill_super(s, fs_devices, data);
diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c
index d49606accb07..2657ff1181f1 100644
--- a/fs/kernfs/mount.c
+++ b/fs/kernfs/mount.c
@@ -256,7 +256,7 @@ static int kernfs_fill_super(struct super_block *sb, struct 
kernfs_fs_context *k
sb->s_time_gran = 1;
 
/* sysfs dentries and inodes don't require IO to create */
-   sb->s_shrink.seeks = 0;
+   sb->s_shrink->seeks = 0;
 
/* get root inode, initialize and unlock it */
down_read(_root->kernfs_rwsem);
diff --git a/fs/proc/root.c b/fs/proc/root.c
index a86e65a608da..22b78b28b477 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -188,7 +188,7 @@ static int proc_fill_super(struct super_block *s, struct 
fs_context *fc)
s->s_stack_depth = FILESYSTEM_MAX_STACK_DEPTH;
 
/* procfs dentries and inodes don't require IO to create */
-   s->s_shrink.seeks = 0;
+   s->s_shrink->seeks = 0;
 
pde_get(_root);
root_inode = proc_get_inode(s, _root);
diff --git a/fs/super.c b/fs/super.c
index 2e83c8cd435b..791342bb8ac9 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -67,7 +67,7 @@ static unsigned long super_cache_scan(struct shrinker *shrink,
longdentries;
longinodes;
 
-   sb = container_of(shrink, struct super_block, s_shrink);
+   sb = shrink->private_data;
 
/*
 * Deadlock avoidance.  We may hold various FS locks, and we don't want
@@ -120,7 +120,7 @@ static unsigned long super_cache_count(struct shrinker 
*shrink,
struct super_block *sb;
longtotal_objects = 0;
 
-   sb = container_of(shrink, struct super_block, s_shrink);
+   sb = shrink->private_data;
 
/*
 * We don't call trylock_super() here as it is a scalability bottleneck,
@@ -182,7 +182,10 @@ static void destroy_unused_super(struct super_block *s)
security_sb_free(s);
put_user_ns(s->s_user_ns);
kfree(s->s_subtype);
-   free_prealloced_shrinker(>s_shrink);
+   if (s->s_shrink) {
+   free_prealloced_shrinker(s->s_shrink);
+   shrinker_free(s->s_shrink);
+   }
/* no delays needed */
destroy_super_work(>destroy_work);
 }
@@ -259,16 +262,19 @@ static struct super_block *alloc_super(struct 
file_system_type *type, int flags,
s->s_time_min = TIME64_MIN;
s->s_time_max = TIME64_MAX;
 
-   s->s_shrink.seeks = DEFAULT_SEEKS;
-   s->s_shrink.scan_objects = super_cache_scan;
-   s->s_shrink.count_objects = super_cache_count;
-   s->s_shrink.batch = 1024;
-   s->s_shrink.flags = SHRINKER_NUMA_AWARE | SHRINKER_MEMCG_AWARE;
-   if (prealloc_shrinker(>s_shrink, "sb-%s", type->name))
+   s->s_shrink = shrinker_alloc_and_init(super_cache_count,
+ super_cache_scan, 1024,
+ DEFAULT_SEEKS,
+ SHRINKER_NUMA_AWARE | 
SHRINKER_MEMCG_AWARE,
+ s);
+   if (!s->s_shrink)
+   goto fail;
+
+   if (prealloc_shrinker(s->s_shrink, "sb-%s", type->name))
goto fail;
-   if (list_lru_init_memcg(>s_dentry_lru, >s_shrink))
+   if (list_lru_init_memcg(>s_dentry_lru, s->s_shrink))
goto fail;
-   if (list_lru_init_memcg(>s_inode_lru, >s_shrink))
+   if (list_lru_init_memcg(>s_inode_lru, s->s_shrink))
goto fail;
return s;
 
@@ -326,7 +332,7 @@ void deactivate_locked_super(struct super_block *s)
 {
struct file_system_type *fs = s->s_type;
if (atomic_dec_and_test(>s_active)) {
-   unregister_shrinker(>s_shrink);
+   unregister_and_free_shrinker(s->s_shrink);
fs->kill_sb(s);
 
  

Re: [Intel-gfx] [PATCH 24/29] mm: vmscan: make global slab shrink lockless

2023-06-27 Thread Alan Huang


> 2023年6月23日 上午12:42,Qi Zheng  写道:
> 
> 
> 
> On 2023/6/22 23:12, Vlastimil Babka wrote:
>> On 6/22/23 10:53, Qi Zheng wrote:
>>> The shrinker_rwsem is a global read-write lock in
>>> shrinkers subsystem, which protects most operations
>>> such as slab shrink, registration and unregistration
>>> of shrinkers, etc. This can easily cause problems in
>>> the following cases.
>>> 
>>> 1) When the memory pressure is high and there are many
>>>filesystems mounted or unmounted at the same time,
>>>slab shrink will be affected (down_read_trylock()
>>>failed).
>>> 
>>>Such as the real workload mentioned by Kirill Tkhai:
>>> 
>>>```
>>>One of the real workloads from my experience is start
>>>of an overcommitted node containing many starting
>>>containers after node crash (or many resuming containers
>>>after reboot for kernel update). In these cases memory
>>>pressure is huge, and the node goes round in long reclaim.
>>>```
>>> 
>>> 2) If a shrinker is blocked (such as the case mentioned
>>>in [1]) and a writer comes in (such as mount a fs),
>>>then this writer will be blocked and cause all
>>>subsequent shrinker-related operations to be blocked.
>>> 
>>> Even if there is no competitor when shrinking slab, there
>>> may still be a problem. If we have a long shrinker list
>>> and we do not reclaim enough memory with each shrinker,
>>> then the down_read_trylock() may be called with high
>>> frequency. Because of the poor multicore scalability of
>>> atomic operations, this can lead to a significant drop
>>> in IPC (instructions per cycle).
>>> 
>>> We used to implement the lockless slab shrink with
>>> SRCU [1], but then kernel test robot reported -88.8%
>>> regression in stress-ng.ramfs.ops_per_sec test case [2],
>>> so we reverted it [3].
>>> 
>>> This commit uses the refcount+RCU method [4] proposed by
>>> by Dave Chinner to re-implement the lockless global slab
>>> shrink. The memcg slab shrink is handled in the subsequent
>>> patch.
>>> 
>>> Currently, the shrinker instances can be divided into
>>> the following three types:
>>> 
>>> a) global shrinker instance statically defined in the kernel,
>>> such as workingset_shadow_shrinker.
>>> 
>>> b) global shrinker instance statically defined in the kernel
>>> modules, such as mmu_shrinker in x86.
>>> 
>>> c) shrinker instance embedded in other structures.
>>> 
>>> For case a, the memory of shrinker instance is never freed.
>>> For case b, the memory of shrinker instance will be freed
>>> after the module is unloaded. But we will call synchronize_rcu()
>>> in free_module() to wait for RCU read-side critical section to
>>> exit. For case c, the memory of shrinker instance will be
>>> dynamically freed by calling kfree_rcu(). So we can use
>>> rcu_read_{lock,unlock}() to ensure that the shrinker instance
>>> is valid.
>>> 
>>> The shrinker::refcount mechanism ensures that the shrinker
>>> instance will not be run again after unregistration. So the
>>> structure that records the pointer of shrinker instance can be
>>> safely freed without waiting for the RCU read-side critical
>>> section.
>>> 
>>> In this way, while we implement the lockless slab shrink, we
>>> don't need to be blocked in unregister_shrinker() to wait
>>> RCU read-side critical section.
>>> 
>>> The following are the test results:
>>> 
>>> stress-ng --timeout 60 --times --verify --metrics-brief --ramfs 9 &
>>> 
>>> 1) Before applying this patchset:
>>> 
>>>  setting to a 60 second run per stressor
>>>  dispatching hogs: 9 ramfs
>>>  stressor   bogo ops real time  usr time  sys time   bogo ops/s 
>>> bogo ops/s
>>>(secs)(secs)(secs)   (real time) 
>>> (usr+sys time)
>>>  ramfs880623 60.02  7.71226.93 14671.45
>>> 3753.09
>>>  ramfs:
>>>   1 System Management Interrupt
>>>  for a 60.03s run time:
>>> 5762.40s available CPU time
>>>7.71s user time   (  0.13%)
>>>  226.93s system time (  3.94%)
>>>  234.64s total time  (  4.07%)
>>>  load average: 8.54 3.06 2.11
>>>  passed: 9: ramfs (9)
>>>  failed: 0
>>>  skipped: 0
>>>  successful run completed in 60.03s (1 min, 0.03 secs)
>>> 
>>> 2) After applying this patchset:
>>> 
>>>  setting to a 60 second run per stressor
>>>  dispatching hogs: 9 ramfs
>>>  stressor   bogo ops real time  usr time  sys time   bogo ops/s 
>>> bogo ops/s
>>>(secs)(secs)(secs)   (real time) 
>>> (usr+sys time)
>>>  ramfs847562 60.02  7.44230.22 14120.66
>>> 3566.23
>>>  ramfs:
>>>   4 System Management Interrupts
>>>  for a 60.12s run time:
>>> 5771.95s available CPU time
>>>7.44s user time   (  0.13%)
>>>  230.22s system time (  3.99%)
>>>  237.66s total time  (  4.12%)
>>>  load average: 8.18 2.43 0.84
>>>  passed: 9: ramfs (9)
>>>  failed: 0
>>>  skipped: 0
>>>  successful run completed in 60.12s (1 min, 0.12 

Re: [Intel-gfx] [PATCH 29/29] mm: shrinker: move shrinker-related code into a separate file

2023-06-27 Thread Qi Zheng

Hi Vlastimil,

On 2023/6/22 22:53, Vlastimil Babka wrote:

On 6/22/23 10:53, Qi Zheng wrote:

The mm/vmscan.c file is too large, so separate the shrinker-related
code from it into a separate file. No functional changes.

Signed-off-by: Qi Zheng 


Maybe do this move as patch 01 so the further changes are done in the new
file already?


Sure, I will do it in the v2.

Thanks,
Qi





Re: [Intel-gfx] [PATCH 09/11] sysctl: Remove the end element in sysctl table arrays

2023-06-27 Thread Jani Nikula
On Wed, 21 Jun 2023, Joel Granados  wrote:
> On Wed, Jun 21, 2023 at 02:16:55PM +0300, Jani Nikula wrote:
>> On Wed, 21 Jun 2023, Joel Granados  wrote:
>> > Remove the empty end element from all the arrays that are passed to the
>> > register sysctl calls. In some files this means reducing the explicit
>> > array size by one. Also make sure that we are using the size in
>> > ctl_table_header instead of evaluating the .procname element.
>> 
>> Where's the harm in removing the end elements driver by driver? This is
>> an unwieldy patch to handle.
>
> I totally agree. Its a big one!!! but I'm concerned of breaking bisectibility:
> * I could for example separate all the removes into separate commits and
>   then have a final commit that removes the check for the empty element.
>   But this will leave the tree in a state where the for loop will have
>   undefined behavior when it looks for the empty end element. It might
>   or might not work (probably not :) until the final commit where I fix
>   that.
>
> * I could also change the logic that looks for the final element,
>   commit that first and then remove the empty element one commit per
>   driver after that. But then for all the arrays that still have an
>   empty element, there would again be undefined behavior as it would
>   think that the last element is valid (when it is really the sentinel).
>
> Any ideas on how to get around these?

First add size to the register calls, and allow the last one to be
sentinel but do not require the sentinel.

Start removing sentinels, adjusting the size passed in.

Once enough sentinels have been removed, add warning if the final entry
is a sentinel.

Never really remove the check? (But surely you can rework the logic to
not count the number of elements up front, only while iterating.)


BR,
Jani.

>> 
>> > diff --git a/drivers/gpu/drm/i915/i915_perf.c 
>> > b/drivers/gpu/drm/i915/i915_perf.c
>> > index f43950219ffc..e4d7372afb10 100644
>> > --- a/drivers/gpu/drm/i915/i915_perf.c
>> > +++ b/drivers/gpu/drm/i915/i915_perf.c
>> > @@ -4884,24 +4884,23 @@ int i915_perf_remove_config_ioctl(struct 
>> > drm_device *dev, void *data,
>> >  
>> >  static struct ctl_table oa_table[] = {
>> >{
>> > -   .procname = "perf_stream_paranoid",
>> > -   .data = _perf_stream_paranoid,
>> > -   .maxlen = sizeof(i915_perf_stream_paranoid),
>> > -   .mode = 0644,
>> > -   .proc_handler = proc_dointvec_minmax,
>> > -   .extra1 = SYSCTL_ZERO,
>> > -   .extra2 = SYSCTL_ONE,
>> > -   },
>> > +  .procname = "perf_stream_paranoid",
>> > +  .data = _perf_stream_paranoid,
>> > +  .maxlen = sizeof(i915_perf_stream_paranoid),
>> > +  .mode = 0644,
>> > +  .proc_handler = proc_dointvec_minmax,
>> > +  .extra1 = SYSCTL_ZERO,
>> > +  .extra2 = SYSCTL_ONE,
>> > +  },
>> >{
>> > -   .procname = "oa_max_sample_rate",
>> > -   .data = _oa_max_sample_rate,
>> > -   .maxlen = sizeof(i915_oa_max_sample_rate),
>> > -   .mode = 0644,
>> > -   .proc_handler = proc_dointvec_minmax,
>> > -   .extra1 = SYSCTL_ZERO,
>> > -   .extra2 = _sample_rate_hard_limit,
>> > -   },
>> > -  {}
>> > +  .procname = "oa_max_sample_rate",
>> > +  .data = _oa_max_sample_rate,
>> > +  .maxlen = sizeof(i915_oa_max_sample_rate),
>> > +  .mode = 0644,
>> > +  .proc_handler = proc_dointvec_minmax,
>> > +  .extra1 = SYSCTL_ZERO,
>> > +  .extra2 = _sample_rate_hard_limit,
>> > +  }
>> >  };
>> 
>> The existing indentation is off, but fixing it doesn't really belong in
>> this patch.
>
> Agreed. But I actually was trying to fix something that checkpatch
> flagged. I'll change these back (which will cause this patch to be
> flagged).
>
> An alternative solution would be to fix the indentation as part of the
> preparation patches. Tell me what you think.
>
> Thx
>
>> 
>> BR,
>> Jani.
>> 
>> 
>> -- 
>> Jani Nikula, Intel Open Source Graphics Center

-- 
Jani Nikula, Intel Open Source Graphics Center


[Intel-gfx] [PATCH 20/29] zsmalloc: dynamically allocate the mm-zspool shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the mm-zspool shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct zs_pool.

Signed-off-by: Qi Zheng 
---
 mm/zsmalloc.c | 28 
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 3f057970504e..c03b34ae637e 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -229,7 +229,7 @@ struct zs_pool {
struct zs_pool_stats stats;
 
/* Compact classes */
-   struct shrinker shrinker;
+   struct shrinker *shrinker;
 
 #ifdef CONFIG_ZSMALLOC_STAT
struct dentry *stat_dentry;
@@ -2107,8 +2107,7 @@ static unsigned long zs_shrinker_scan(struct shrinker 
*shrinker,
struct shrink_control *sc)
 {
unsigned long pages_freed;
-   struct zs_pool *pool = container_of(shrinker, struct zs_pool,
-   shrinker);
+   struct zs_pool *pool = shrinker->private_data;
 
/*
 * Compact classes and calculate compaction delta.
@@ -2126,8 +2125,7 @@ static unsigned long zs_shrinker_count(struct shrinker 
*shrinker,
int i;
struct size_class *class;
unsigned long pages_to_free = 0;
-   struct zs_pool *pool = container_of(shrinker, struct zs_pool,
-   shrinker);
+   struct zs_pool *pool = shrinker->private_data;
 
for (i = ZS_SIZE_CLASSES - 1; i >= 0; i--) {
class = pool->size_class[i];
@@ -2142,18 +2140,24 @@ static unsigned long zs_shrinker_count(struct shrinker 
*shrinker,
 
 static void zs_unregister_shrinker(struct zs_pool *pool)
 {
-   unregister_shrinker(>shrinker);
+   unregister_and_free_shrinker(pool->shrinker);
 }
 
 static int zs_register_shrinker(struct zs_pool *pool)
 {
-   pool->shrinker.scan_objects = zs_shrinker_scan;
-   pool->shrinker.count_objects = zs_shrinker_count;
-   pool->shrinker.batch = 0;
-   pool->shrinker.seeks = DEFAULT_SEEKS;
+   int ret;
+
+   pool->shrinker = shrinker_alloc_and_init(zs_shrinker_count,
+zs_shrinker_scan, 0,
+DEFAULT_SEEKS, 0, pool);
+   if (!pool->shrinker)
+   return -ENOMEM;
 
-   return register_shrinker(>shrinker, "mm-zspool:%s",
-pool->name);
+   ret = register_shrinker(pool->shrinker, "mm-zspool:%s", pool->name);
+   if (ret)
+   shrinker_free(pool->shrinker);
+
+   return ret;
 }
 
 static int calculate_zspage_chain_size(int class_size)
-- 
2.30.2



Re: [Intel-gfx] [PATCH 24/29] mm: vmscan: make global slab shrink lockless

2023-06-27 Thread Qi Zheng




On 2023/6/23 01:41, Alan Huang wrote:



2023年6月23日 上午12:42,Qi Zheng  写道:



On 2023/6/22 23:12, Vlastimil Babka wrote:

On 6/22/23 10:53, Qi Zheng wrote:

The shrinker_rwsem is a global read-write lock in
shrinkers subsystem, which protects most operations
such as slab shrink, registration and unregistration
of shrinkers, etc. This can easily cause problems in
the following cases.

1) When the memory pressure is high and there are many
filesystems mounted or unmounted at the same time,
slab shrink will be affected (down_read_trylock()
failed).

Such as the real workload mentioned by Kirill Tkhai:

```
One of the real workloads from my experience is start
of an overcommitted node containing many starting
containers after node crash (or many resuming containers
after reboot for kernel update). In these cases memory
pressure is huge, and the node goes round in long reclaim.
```

2) If a shrinker is blocked (such as the case mentioned
in [1]) and a writer comes in (such as mount a fs),
then this writer will be blocked and cause all
subsequent shrinker-related operations to be blocked.

Even if there is no competitor when shrinking slab, there
may still be a problem. If we have a long shrinker list
and we do not reclaim enough memory with each shrinker,
then the down_read_trylock() may be called with high
frequency. Because of the poor multicore scalability of
atomic operations, this can lead to a significant drop
in IPC (instructions per cycle).

We used to implement the lockless slab shrink with
SRCU [1], but then kernel test robot reported -88.8%
regression in stress-ng.ramfs.ops_per_sec test case [2],
so we reverted it [3].

This commit uses the refcount+RCU method [4] proposed by
by Dave Chinner to re-implement the lockless global slab
shrink. The memcg slab shrink is handled in the subsequent
patch.

Currently, the shrinker instances can be divided into
the following three types:

a) global shrinker instance statically defined in the kernel,
such as workingset_shadow_shrinker.

b) global shrinker instance statically defined in the kernel
modules, such as mmu_shrinker in x86.

c) shrinker instance embedded in other structures.

For case a, the memory of shrinker instance is never freed.
For case b, the memory of shrinker instance will be freed
after the module is unloaded. But we will call synchronize_rcu()
in free_module() to wait for RCU read-side critical section to
exit. For case c, the memory of shrinker instance will be
dynamically freed by calling kfree_rcu(). So we can use
rcu_read_{lock,unlock}() to ensure that the shrinker instance
is valid.

The shrinker::refcount mechanism ensures that the shrinker
instance will not be run again after unregistration. So the
structure that records the pointer of shrinker instance can be
safely freed without waiting for the RCU read-side critical
section.

In this way, while we implement the lockless slab shrink, we
don't need to be blocked in unregister_shrinker() to wait
RCU read-side critical section.

The following are the test results:

stress-ng --timeout 60 --times --verify --metrics-brief --ramfs 9 &

1) Before applying this patchset:

  setting to a 60 second run per stressor
  dispatching hogs: 9 ramfs
  stressor   bogo ops real time  usr time  sys time   bogo ops/s bogo 
ops/s
(secs)(secs)(secs)   (real time) (usr+sys 
time)
  ramfs880623 60.02  7.71226.93 14671.45
3753.09
  ramfs:
   1 System Management Interrupt
  for a 60.03s run time:
 5762.40s available CPU time
7.71s user time   (  0.13%)
  226.93s system time (  3.94%)
  234.64s total time  (  4.07%)
  load average: 8.54 3.06 2.11
  passed: 9: ramfs (9)
  failed: 0
  skipped: 0
  successful run completed in 60.03s (1 min, 0.03 secs)

2) After applying this patchset:

  setting to a 60 second run per stressor
  dispatching hogs: 9 ramfs
  stressor   bogo ops real time  usr time  sys time   bogo ops/s bogo 
ops/s
(secs)(secs)(secs)   (real time) (usr+sys 
time)
  ramfs847562 60.02  7.44230.22 14120.66
3566.23
  ramfs:
   4 System Management Interrupts
  for a 60.12s run time:
 5771.95s available CPU time
7.44s user time   (  0.13%)
  230.22s system time (  3.99%)
  237.66s total time  (  4.12%)
  load average: 8.18 2.43 0.84
  passed: 9: ramfs (9)
  failed: 0
  skipped: 0
  successful run completed in 60.12s (1 min, 0.12 secs)

We can see that the ops/s has hardly changed.

[1]. 
https://lore.kernel.org/lkml/20230313112819.38938-1-zhengqi.a...@bytedance.com/
[2]. https://lore.kernel.org/lkml/202305230837.db2c233f-yujie@intel.com/
[3]. https://lore.kernel.org/all/20230609081518.3039120-1-qi.zh...@linux.dev/
[4]. https://lore.kernel.org/lkml/zijhou1d55d4h...@dread.disaster.area/

Signed-off-by: Qi Zheng 
---
  

[Intel-gfx] [PATCH 05/29] drm/panfrost: dynamically allocate the drm-panfrost shrinker

2023-06-27 Thread Qi Zheng
From: Qi Zheng 

In preparation for implementing lockless slab shrink,
we need to dynamically allocate the drm-panfrost shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct panfrost_device.

Signed-off-by: Qi Zheng 
---
 drivers/gpu/drm/panfrost/panfrost_device.h|  2 +-
 .../gpu/drm/panfrost/panfrost_gem_shrinker.c  | 24 ++-
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
b/drivers/gpu/drm/panfrost/panfrost_device.h
index b0126b9fbadc..e667e5689353 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -118,7 +118,7 @@ struct panfrost_device {
 
struct mutex shrinker_lock;
struct list_head shrinker_list;
-   struct shrinker shrinker;
+   struct shrinker *shrinker;
 
struct panfrost_devfreq pfdevfreq;
 };
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c 
b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
index bf0170782f25..2a5513eb9e1f 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
@@ -18,8 +18,7 @@
 static unsigned long
 panfrost_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control 
*sc)
 {
-   struct panfrost_device *pfdev =
-   container_of(shrinker, struct panfrost_device, shrinker);
+   struct panfrost_device *pfdev = shrinker->private_data;
struct drm_gem_shmem_object *shmem;
unsigned long count = 0;
 
@@ -65,8 +64,7 @@ static bool panfrost_gem_purge(struct drm_gem_object *obj)
 static unsigned long
 panfrost_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control 
*sc)
 {
-   struct panfrost_device *pfdev =
-   container_of(shrinker, struct panfrost_device, shrinker);
+   struct panfrost_device *pfdev = shrinker->private_data;
struct drm_gem_shmem_object *shmem, *tmp;
unsigned long freed = 0;
 
@@ -100,10 +98,15 @@ panfrost_gem_shrinker_scan(struct shrinker *shrinker, 
struct shrink_control *sc)
 void panfrost_gem_shrinker_init(struct drm_device *dev)
 {
struct panfrost_device *pfdev = dev->dev_private;
-   pfdev->shrinker.count_objects = panfrost_gem_shrinker_count;
-   pfdev->shrinker.scan_objects = panfrost_gem_shrinker_scan;
-   pfdev->shrinker.seeks = DEFAULT_SEEKS;
-   WARN_ON(register_shrinker(>shrinker, "drm-panfrost"));
+
+   pfdev->shrinker = shrinker_alloc_and_init(panfrost_gem_shrinker_count,
+ panfrost_gem_shrinker_scan, 0,
+ DEFAULT_SEEKS, 0, pfdev);
+   if (pfdev->shrinker &&
+   register_shrinker(pfdev->shrinker, "drm-panfrost")) {
+   shrinker_free(pfdev->shrinker);
+   WARN_ON(1);
+   }
 }
 
 /**
@@ -116,7 +119,6 @@ void panfrost_gem_shrinker_cleanup(struct drm_device *dev)
 {
struct panfrost_device *pfdev = dev->dev_private;
 
-   if (pfdev->shrinker.nr_deferred) {
-   unregister_shrinker(>shrinker);
-   }
+   if (pfdev->shrinker->nr_deferred)
+   unregister_and_free_shrinker(pfdev->shrinker);
 }
-- 
2.30.2



[Intel-gfx] [PATCH 10/29] vmw_balloon: dynamically allocate the vmw-balloon shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the vmw-balloon shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct vmballoon.

Signed-off-by: Qi Zheng 
---
 drivers/misc/vmw_balloon.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c
index 9ce9b9e0e9b6..2f86f666b476 100644
--- a/drivers/misc/vmw_balloon.c
+++ b/drivers/misc/vmw_balloon.c
@@ -380,7 +380,7 @@ struct vmballoon {
/**
 * @shrinker: shrinker interface that is used to avoid over-inflation.
 */
-   struct shrinker shrinker;
+   struct shrinker *shrinker;
 
/**
 * @shrinker_registered: whether the shrinker was registered.
@@ -1569,7 +1569,7 @@ static unsigned long vmballoon_shrinker_count(struct 
shrinker *shrinker,
 static void vmballoon_unregister_shrinker(struct vmballoon *b)
 {
if (b->shrinker_registered)
-   unregister_shrinker(>shrinker);
+   unregister_and_free_shrinker(b->shrinker);
b->shrinker_registered = false;
 }
 
@@ -1581,14 +1581,18 @@ static int vmballoon_register_shrinker(struct vmballoon 
*b)
if (!vmwballoon_shrinker_enable)
return 0;
 
-   b->shrinker.scan_objects = vmballoon_shrinker_scan;
-   b->shrinker.count_objects = vmballoon_shrinker_count;
-   b->shrinker.seeks = DEFAULT_SEEKS;
+   b->shrinker = shrinker_alloc_and_init(vmballoon_shrinker_count,
+ vmballoon_shrinker_scan,
+ 0, DEFAULT_SEEKS, 0, b);
+   if (!b->shrinker)
+   return -ENOMEM;
 
-   r = register_shrinker(>shrinker, "vmw-balloon");
+   r = register_shrinker(b->shrinker, "vmw-balloon");
 
if (r == 0)
b->shrinker_registered = true;
+   else
+   shrinker_free(b->shrinker);
 
return r;
 }
-- 
2.30.2



Re: [Intel-gfx] [PATCH 09/11] sysctl: Remove the end element in sysctl table arrays

2023-06-27 Thread Jani Nikula
On Wed, 21 Jun 2023, Joel Granados  wrote:
> Remove the empty end element from all the arrays that are passed to the
> register sysctl calls. In some files this means reducing the explicit
> array size by one. Also make sure that we are using the size in
> ctl_table_header instead of evaluating the .procname element.

Where's the harm in removing the end elements driver by driver? This is
an unwieldy patch to handle.

> diff --git a/drivers/gpu/drm/i915/i915_perf.c 
> b/drivers/gpu/drm/i915/i915_perf.c
> index f43950219ffc..e4d7372afb10 100644
> --- a/drivers/gpu/drm/i915/i915_perf.c
> +++ b/drivers/gpu/drm/i915/i915_perf.c
> @@ -4884,24 +4884,23 @@ int i915_perf_remove_config_ioctl(struct drm_device 
> *dev, void *data,
>  
>  static struct ctl_table oa_table[] = {
>   {
> -  .procname = "perf_stream_paranoid",
> -  .data = _perf_stream_paranoid,
> -  .maxlen = sizeof(i915_perf_stream_paranoid),
> -  .mode = 0644,
> -  .proc_handler = proc_dointvec_minmax,
> -  .extra1 = SYSCTL_ZERO,
> -  .extra2 = SYSCTL_ONE,
> -  },
> + .procname = "perf_stream_paranoid",
> + .data = _perf_stream_paranoid,
> + .maxlen = sizeof(i915_perf_stream_paranoid),
> + .mode = 0644,
> + .proc_handler = proc_dointvec_minmax,
> + .extra1 = SYSCTL_ZERO,
> + .extra2 = SYSCTL_ONE,
> + },
>   {
> -  .procname = "oa_max_sample_rate",
> -  .data = _oa_max_sample_rate,
> -  .maxlen = sizeof(i915_oa_max_sample_rate),
> -  .mode = 0644,
> -  .proc_handler = proc_dointvec_minmax,
> -  .extra1 = SYSCTL_ZERO,
> -  .extra2 = _sample_rate_hard_limit,
> -  },
> - {}
> + .procname = "oa_max_sample_rate",
> + .data = _oa_max_sample_rate,
> + .maxlen = sizeof(i915_oa_max_sample_rate),
> + .mode = 0644,
> + .proc_handler = proc_dointvec_minmax,
> + .extra1 = SYSCTL_ZERO,
> + .extra2 = _sample_rate_hard_limit,
> + }
>  };

The existing indentation is off, but fixing it doesn't really belong in
this patch.

BR,
Jani.


-- 
Jani Nikula, Intel Open Source Graphics Center


[Intel-gfx] [PATCH 23/29] mm: shrinker: add refcount and completion_wait fields

2023-06-27 Thread Qi Zheng
This commit introduces refcount and completion_wait
fields to struct shrinker to manage the life cycle
of shrinker instance.

Just a preparation work for implementing the lockless
slab shrink, no functional changes.

Signed-off-by: Qi Zheng 
---
 include/linux/shrinker.h | 11 +++
 mm/vmscan.c  |  5 +
 2 files changed, 16 insertions(+)

diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index 4094e4c44e80..7bfeb2f25246 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -4,6 +4,8 @@
 
 #include 
 #include 
+#include 
+#include 
 
 /*
  * This struct is used to pass information from page reclaim to the shrinkers.
@@ -70,6 +72,9 @@ struct shrinker {
int seeks;  /* seeks to recreate an obj */
unsigned flags;
 
+   refcount_t refcount;
+   struct completion completion_wait;
+
void *private_data;
 
/* These are for internal use */
@@ -118,6 +123,12 @@ struct shrinker *shrinker_alloc_and_init(count_objects_cb 
count,
 void shrinker_free(struct shrinker *shrinker);
 void unregister_and_free_shrinker(struct shrinker *shrinker);
 
+static inline void shrinker_put(struct shrinker *shrinker)
+{
+   if (refcount_dec_and_test(>refcount))
+   complete(>completion_wait);
+}
+
 #ifdef CONFIG_SHRINKER_DEBUG
 extern int shrinker_debugfs_add(struct shrinker *shrinker);
 extern struct dentry *shrinker_debugfs_detach(struct shrinker *shrinker,
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 3a8d50ad6ff6..6f9c4750effa 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -740,6 +740,8 @@ void free_prealloced_shrinker(struct shrinker *shrinker)
 void register_shrinker_prepared(struct shrinker *shrinker)
 {
down_write(_rwsem);
+   refcount_set(>refcount, 1);
+   init_completion(>completion_wait);
list_add_tail(>list, _list);
shrinker->flags |= SHRINKER_REGISTERED;
shrinker_debugfs_add(shrinker);
@@ -794,6 +796,9 @@ void unregister_shrinker(struct shrinker *shrinker)
if (!(shrinker->flags & SHRINKER_REGISTERED))
return;
 
+   shrinker_put(shrinker);
+   wait_for_completion(>completion_wait);
+
down_write(_rwsem);
list_del(>list);
shrinker->flags &= ~SHRINKER_REGISTERED;
-- 
2.30.2



[Intel-gfx] [PATCH 03/29] drm/i915: dynamically allocate the i915_gem_mm shrinker

2023-06-27 Thread Qi Zheng
From: Qi Zheng 

In preparation for implementing lockless slab shrink,
we need to dynamically allocate the i915_gem_mm shrinker,
so that it can be freed asynchronously by using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct drm_i915_private.

Signed-off-by: Qi Zheng 
---
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 27 ++--
 drivers/gpu/drm/i915/i915_drv.h  |  3 ++-
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index 214763942aa2..4dcdace26a08 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -284,8 +284,7 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private 
*i915)
 static unsigned long
 i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
 {
-   struct drm_i915_private *i915 =
-   container_of(shrinker, struct drm_i915_private, mm.shrinker);
+   struct drm_i915_private *i915 = shrinker->private_data;
unsigned long num_objects;
unsigned long count;
 
@@ -302,8 +301,8 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct 
shrink_control *sc)
if (num_objects) {
unsigned long avg = 2 * count / num_objects;
 
-   i915->mm.shrinker.batch =
-   max((i915->mm.shrinker.batch + avg) >> 1,
+   i915->mm.shrinker->batch =
+   max((i915->mm.shrinker->batch + avg) >> 1,
128ul /* default SHRINK_BATCH */);
}
 
@@ -313,8 +312,7 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct 
shrink_control *sc)
 static unsigned long
 i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
 {
-   struct drm_i915_private *i915 =
-   container_of(shrinker, struct drm_i915_private, mm.shrinker);
+   struct drm_i915_private *i915 = shrinker->private_data;
unsigned long freed;
 
sc->nr_scanned = 0;
@@ -422,12 +420,15 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, 
unsigned long event, void *ptr
 
 void i915_gem_driver_register__shrinker(struct drm_i915_private *i915)
 {
-   i915->mm.shrinker.scan_objects = i915_gem_shrinker_scan;
-   i915->mm.shrinker.count_objects = i915_gem_shrinker_count;
-   i915->mm.shrinker.seeks = DEFAULT_SEEKS;
-   i915->mm.shrinker.batch = 4096;
-   drm_WARN_ON(>drm, register_shrinker(>mm.shrinker,
- "drm-i915_gem"));
+   i915->mm.shrinker = shrinker_alloc_and_init(i915_gem_shrinker_count,
+   i915_gem_shrinker_scan,
+   4096, DEFAULT_SEEKS, 0,
+   i915);
+   if (i915->mm.shrinker &&
+   register_shrinker(i915->mm.shrinker, "drm-i915_gem")) {
+   shrinker_free(i915->mm.shrinker);
+   drm_WARN_ON(>drm, 1);
+   }
 
i915->mm.oom_notifier.notifier_call = i915_gem_shrinker_oom;
drm_WARN_ON(>drm, register_oom_notifier(>mm.oom_notifier));
@@ -443,7 +444,7 @@ void i915_gem_driver_unregister__shrinker(struct 
drm_i915_private *i915)
unregister_vmap_purge_notifier(>mm.vmap_notifier));
drm_WARN_ON(>drm,
unregister_oom_notifier(>mm.oom_notifier));
-   unregister_shrinker(>mm.shrinker);
+   unregister_and_free_shrinker(i915->mm.shrinker);
 }
 
 void i915_gem_shrinker_taints_mutex(struct drm_i915_private *i915,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b4cf6f0f636d..06b04428596d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -163,7 +163,8 @@ struct i915_gem_mm {
 
struct notifier_block oom_notifier;
struct notifier_block vmap_notifier;
-   struct shrinker shrinker;
+
+   struct shrinker *shrinker;
 
 #ifdef CONFIG_MMU_NOTIFIER
/**
-- 
2.30.2



[Intel-gfx] [PATCH 12/29] mbcache: dynamically allocate the mbcache shrinker

2023-06-27 Thread Qi Zheng
From: Qi Zheng 

In preparation for implementing lockless slab shrink,
we need to dynamically allocate the mbcache shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct mb_cache.

Signed-off-by: Qi Zheng 
---
 fs/mbcache.c | 39 +--
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/fs/mbcache.c b/fs/mbcache.c
index 2a4b8b549e93..fec393e55a66 100644
--- a/fs/mbcache.c
+++ b/fs/mbcache.c
@@ -37,7 +37,7 @@ struct mb_cache {
struct list_headc_list;
/* Number of entries in cache */
unsigned long   c_entry_count;
-   struct shrinker c_shrink;
+   struct shrinker *c_shrink;
/* Work for shrinking when the cache has too many entries */
struct work_struct  c_shrink_work;
 };
@@ -293,8 +293,7 @@ EXPORT_SYMBOL(mb_cache_entry_touch);
 static unsigned long mb_cache_count(struct shrinker *shrink,
struct shrink_control *sc)
 {
-   struct mb_cache *cache = container_of(shrink, struct mb_cache,
- c_shrink);
+   struct mb_cache *cache = shrink->private_data;
 
return cache->c_entry_count;
 }
@@ -333,8 +332,8 @@ static unsigned long mb_cache_shrink(struct mb_cache *cache,
 static unsigned long mb_cache_scan(struct shrinker *shrink,
   struct shrink_control *sc)
 {
-   struct mb_cache *cache = container_of(shrink, struct mb_cache,
- c_shrink);
+   struct mb_cache *cache = shrink->private_data;
+
return mb_cache_shrink(cache, sc->nr_to_scan);
 }
 
@@ -370,26 +369,30 @@ struct mb_cache *mb_cache_create(int bucket_bits)
cache->c_hash = kmalloc_array(bucket_count,
  sizeof(struct hlist_bl_head),
  GFP_KERNEL);
-   if (!cache->c_hash) {
-   kfree(cache);
-   goto err_out;
-   }
+   if (!cache->c_hash)
+   goto err_c_hash;
+
for (i = 0; i < bucket_count; i++)
INIT_HLIST_BL_HEAD(>c_hash[i]);
 
-   cache->c_shrink.count_objects = mb_cache_count;
-   cache->c_shrink.scan_objects = mb_cache_scan;
-   cache->c_shrink.seeks = DEFAULT_SEEKS;
-   if (register_shrinker(>c_shrink, "mbcache-shrinker")) {
-   kfree(cache->c_hash);
-   kfree(cache);
-   goto err_out;
-   }
+   cache->c_shrink = shrinker_alloc_and_init(mb_cache_count, mb_cache_scan,
+ 0, DEFAULT_SEEKS, 0, cache);
+   if (!cache->c_shrink)
+   goto err_shrinker;
+
+   if (register_shrinker(cache->c_shrink, "mbcache-shrinker"))
+   goto err_register;
 
INIT_WORK(>c_shrink_work, mb_cache_shrink_worker);
 
return cache;
 
+err_register:
+   shrinker_free(cache->c_shrink);
+err_shrinker:
+   kfree(cache->c_hash);
+err_c_hash:
+   kfree(cache);
 err_out:
return NULL;
 }
@@ -406,7 +409,7 @@ void mb_cache_destroy(struct mb_cache *cache)
 {
struct mb_cache_entry *entry, *next;
 
-   unregister_shrinker(>c_shrink);
+   unregister_and_free_shrinker(cache->c_shrink);
 
/*
 * We don't bother with any locking. Cache must not be used at this
-- 
2.30.2



Re: [Intel-gfx] [PATCH 09/13] net: Convert sunrpc from pagevec to folio_batch

2023-06-27 Thread Chuck Lever
On Wed, Jun 21, 2023 at 05:45:53PM +0100, Matthew Wilcox (Oracle) wrote:
> Remove the last usage of pagevecs.  There is a slight change here; we
> now free the folio_batch as soon as it fills up instead of freeing the
> folio_batch when we try to add a page to a full batch.  This should have
> no effect in practice.
> 
> Signed-off-by: Matthew Wilcox (Oracle) 

I don't yet have visibility into the folio_batch_* helpers, but this
looks like a wholly mechanical replacement of pagevec. LGTM.

I assume this is going to be merged via another tree, not nfsd-next,
so:

Acked-by: Chuck Lever 


> ---
>  include/linux/sunrpc/svc.h |  2 +-
>  net/sunrpc/svc.c   | 10 +-
>  2 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
> index c2807e301790..f8751118c122 100644
> --- a/include/linux/sunrpc/svc.h
> +++ b/include/linux/sunrpc/svc.h
> @@ -222,7 +222,7 @@ struct svc_rqst {
>   struct page *   *rq_next_page; /* next reply page to use */
>   struct page *   *rq_page_end;  /* one past the last page */
>  
> - struct pagevec  rq_pvec;
> + struct folio_batch  rq_fbatch;
>   struct kvec rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. 
> */
>   struct bio_vec  rq_bvec[RPCSVC_MAXPAGES];
>  
> diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
> index e7c101290425..587811a002c9 100644
> --- a/net/sunrpc/svc.c
> +++ b/net/sunrpc/svc.c
> @@ -640,7 +640,7 @@ svc_rqst_alloc(struct svc_serv *serv, struct svc_pool 
> *pool, int node)
>   if (!rqstp)
>   return rqstp;
>  
> - pagevec_init(>rq_pvec);
> + folio_batch_init(>rq_fbatch);
>  
>   __set_bit(RQ_BUSY, >rq_flags);
>   rqstp->rq_server = serv;
> @@ -851,9 +851,9 @@ bool svc_rqst_replace_page(struct svc_rqst *rqstp, struct 
> page *page)
>   }
>  
>   if (*rqstp->rq_next_page) {
> - if (!pagevec_space(>rq_pvec))
> - __pagevec_release(>rq_pvec);
> - pagevec_add(>rq_pvec, *rqstp->rq_next_page);
> + if (!folio_batch_add(>rq_fbatch,
> + page_folio(*rqstp->rq_next_page)))
> + __folio_batch_release(>rq_fbatch);
>   }
>  
>   get_page(page);
> @@ -887,7 +887,7 @@ void svc_rqst_release_pages(struct svc_rqst *rqstp)
>  void
>  svc_rqst_free(struct svc_rqst *rqstp)
>  {
> - pagevec_release(>rq_pvec);
> + folio_batch_release(>rq_fbatch);
>   svc_release_buffer(rqstp);
>   if (rqstp->rq_scratch_page)
>   put_page(rqstp->rq_scratch_page);
> -- 
> 2.39.2
> 


[Intel-gfx] [PATCH 00/29] use refcount+RCU method to implement lockless slab shrink

2023-06-27 Thread Qi Zheng
From: Qi Zheng 

Hi all,

1. Background
=

We used to implement the lockless slab shrink with SRCU [1], but then kernel
test robot reported -88.8% regression in stress-ng.ramfs.ops_per_sec test
case [2], so we reverted it [3].

This patch series aims to re-implement the lockless slab shrink using the
refcount+RCU method proposed by Dave Chinner [4].

[1]. 
https://lore.kernel.org/lkml/20230313112819.38938-1-zhengqi.a...@bytedance.com/
[2]. https://lore.kernel.org/lkml/202305230837.db2c233f-yujie@intel.com/
[3]. https://lore.kernel.org/all/20230609081518.3039120-1-qi.zh...@linux.dev/
[4]. https://lore.kernel.org/lkml/zijhou1d55d4h...@dread.disaster.area/

2. Implementation
=

Currently, the shrinker instances can be divided into the following three types:

a) global shrinker instance statically defined in the kernel, such as
   workingset_shadow_shrinker.

b) global shrinker instance statically defined in the kernel modules, such as
   mmu_shrinker in x86.

c) shrinker instance embedded in other structures.

For *case a*, the memory of shrinker instance is never freed. For *case b*, the
memory of shrinker instance will be freed after the module is unloaded. But we
will call synchronize_rcu() in free_module() to wait for RCU read-side critical
section to exit. For *case c*, we need to dynamically allocate these shrinker
instances, then the memory of shrinker instance can be dynamically freed alone
by calling kfree_rcu(). Then we can use rcu_read_{lock,unlock}() to ensure that
the shrinker instance is valid.

The shrinker::refcount mechanism ensures that the shrinker instance will not be
run again after unregistration. So the structure that records the pointer of
shrinker instance can be safely freed without waiting for the RCU read-side
critical section.

In this way, while we implement the lockless slab shrink, we don't need to be
blocked in unregister_shrinker() to wait RCU read-side critical section.

PATCH 1 ~ 2: infrastructure for dynamically allocating shrinker instances
PATCH 3 ~ 21: dynamically allocate the shrinker instances in case c
PATCH 22: introduce pool_shrink_rwsem to implement private 
synchronize_shrinkers()
PATCH 23 ~ 28: implement the lockless slab shrink
PATCH 29: move shrinker-related code into a separate file

3. Testing
==

3.1 slab shrink stress test
---

We can reproduce the down_read_trylock() hotspot through the following script:

```

DIR="/root/shrinker/memcg/mnt"

do_create()
{
mkdir -p /sys/fs/cgroup/memory/test
mkdir -p /sys/fs/cgroup/perf_event/test
echo 4G > /sys/fs/cgroup/memory/test/memory.limit_in_bytes
for i in `seq 0 $1`;
do
mkdir -p /sys/fs/cgroup/memory/test/$i;
echo $$ > /sys/fs/cgroup/memory/test/$i/cgroup.procs;
echo $$ > /sys/fs/cgroup/perf_event/test/cgroup.procs;
mkdir -p $DIR/$i;
done
}

do_mount()
{
for i in `seq $1 $2`;
do
mount -t tmpfs $i $DIR/$i;
done
}

do_touch()
{
for i in `seq $1 $2`;
do
echo $$ > /sys/fs/cgroup/memory/test/$i/cgroup.procs;
echo $$ > /sys/fs/cgroup/perf_event/test/cgroup.procs;
dd if=/dev/zero of=$DIR/$i/file$i bs=1M count=1 &
done
}

case "$1" in
  touch)
do_touch $2 $3
;;
  test)
do_create 4000
do_mount 0 4000
do_touch 0 3000
;;
  *)
exit 1
;;
esac
```

Save the above script, then run test and touch commands. Then we can use the
following perf command to view hotspots:

perf top -U -F 999 [-g]

1) Before applying this patchset:

  35.34%  [kernel] [k] down_read_trylock
  18.44%  [kernel] [k] shrink_slab
  15.98%  [kernel] [k] pv_native_safe_halt
  15.08%  [kernel] [k] up_read
   5.33%  [kernel] [k] idr_find
   2.71%  [kernel] [k] _find_next_bit
   2.21%  [kernel] [k] shrink_node
   1.29%  [kernel] [k] shrink_lruvec
   0.66%  [kernel] [k] do_shrink_slab
   0.33%  [kernel] [k] list_lru_count_one
   0.33%  [kernel] [k] __radix_tree_lookup
   0.25%  [kernel] [k] mem_cgroup_iter

-   82.19%19.49%  [kernel]  [k] shrink_slab
   - 62.00% shrink_slab
36.37% down_read_trylock
15.52% up_read
5.48% idr_find
3.38% _find_next_bit
  + 0.98% do_shrink_slab

2) After applying this patchset:

  46.83%  [kernel]   [k] shrink_slab
  20.52%  [kernel]   [k] pv_native_safe_halt
   8.85%  [kernel]   [k] do_shrink_slab
   7.71%  [kernel]   [k] _find_next_bit
   1.72%  [kernel]   [k] xas_descend
   1.70%  [kernel]   [k] shrink_node
   1.44%  [kernel]   [k] shrink_lruvec
   1.43%  [kernel]   [k] mem_cgroup_iter
   1.28%  [kernel]   [k] xas_load
   0.89%  [kernel]   [k] super_cache_count
   0.84%  [kernel]   [k] xas_start
   0.66%  [kernel]   [k] 

[Intel-gfx] [PATCH 11/29] virtio_balloon: dynamically allocate the virtio-balloon shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the virtio-balloon shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct virtio_balloon.

Signed-off-by: Qi Zheng 
---
 drivers/virtio/virtio_balloon.c | 26 --
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 5b15936a5214..fa051bff8d90 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -111,7 +111,7 @@ struct virtio_balloon {
struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR];
 
/* Shrinker to return free pages - VIRTIO_BALLOON_F_FREE_PAGE_HINT */
-   struct shrinker shrinker;
+   struct shrinker *shrinker;
 
/* OOM notifier to deflate on OOM - VIRTIO_BALLOON_F_DEFLATE_ON_OOM */
struct notifier_block oom_nb;
@@ -816,8 +816,7 @@ static unsigned long shrink_free_pages(struct 
virtio_balloon *vb,
 static unsigned long virtio_balloon_shrinker_scan(struct shrinker *shrinker,
  struct shrink_control *sc)
 {
-   struct virtio_balloon *vb = container_of(shrinker,
-   struct virtio_balloon, shrinker);
+   struct virtio_balloon *vb = shrinker->private_data;
 
return shrink_free_pages(vb, sc->nr_to_scan);
 }
@@ -825,8 +824,7 @@ static unsigned long virtio_balloon_shrinker_scan(struct 
shrinker *shrinker,
 static unsigned long virtio_balloon_shrinker_count(struct shrinker *shrinker,
   struct shrink_control *sc)
 {
-   struct virtio_balloon *vb = container_of(shrinker,
-   struct virtio_balloon, shrinker);
+   struct virtio_balloon *vb = shrinker->private_data;
 
return vb->num_free_page_blocks * VIRTIO_BALLOON_HINT_BLOCK_PAGES;
 }
@@ -847,16 +845,24 @@ static int virtio_balloon_oom_notify(struct 
notifier_block *nb,
 
 static void virtio_balloon_unregister_shrinker(struct virtio_balloon *vb)
 {
-   unregister_shrinker(>shrinker);
+   unregister_and_free_shrinker(vb->shrinker);
 }
 
 static int virtio_balloon_register_shrinker(struct virtio_balloon *vb)
 {
-   vb->shrinker.scan_objects = virtio_balloon_shrinker_scan;
-   vb->shrinker.count_objects = virtio_balloon_shrinker_count;
-   vb->shrinker.seeks = DEFAULT_SEEKS;
+   int ret;
+
+   vb->shrinker = shrinker_alloc_and_init(virtio_balloon_shrinker_count,
+  virtio_balloon_shrinker_scan,
+  0, DEFAULT_SEEKS, 0, vb);
+   if (!vb->shrinker)
+   return -ENOMEM;
+
+   ret = register_shrinker(vb->shrinker, "virtio-balloon");
+   if (ret)
+   shrinker_free(vb->shrinker);
 
-   return register_shrinker(>shrinker, "virtio-balloon");
+   return ret;
 }
 
 static int virtballoon_probe(struct virtio_device *vdev)
-- 
2.30.2



[Intel-gfx] [PATCH 14/29] jbd2, ext4: dynamically allocate the jbd2-journal shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the jbd2-journal shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct journal_s.

Signed-off-by: Qi Zheng 
---
 fs/jbd2/journal.c| 32 +++-
 include/linux/jbd2.h |  2 +-
 2 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index eee3c0ae349a..92a2f4360b5f 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1301,7 +1301,7 @@ static int jbd2_min_tag_size(void)
 static unsigned long jbd2_journal_shrink_scan(struct shrinker *shrink,
  struct shrink_control *sc)
 {
-   journal_t *journal = container_of(shrink, journal_t, j_shrinker);
+   journal_t *journal = shrink->private_data;
unsigned long nr_to_scan = sc->nr_to_scan;
unsigned long nr_shrunk;
unsigned long count;
@@ -1327,7 +1327,7 @@ static unsigned long jbd2_journal_shrink_scan(struct 
shrinker *shrink,
 static unsigned long jbd2_journal_shrink_count(struct shrinker *shrink,
   struct shrink_control *sc)
 {
-   journal_t *journal = container_of(shrink, journal_t, j_shrinker);
+   journal_t *journal = shrink->private_data;
unsigned long count;
 
count = percpu_counter_read_positive(>j_checkpoint_jh_count);
@@ -1415,21 +1415,27 @@ static journal_t *journal_init_common(struct 
block_device *bdev,
journal->j_superblock = (journal_superblock_t *)bh->b_data;
 
journal->j_shrink_transaction = NULL;
-   journal->j_shrinker.scan_objects = jbd2_journal_shrink_scan;
-   journal->j_shrinker.count_objects = jbd2_journal_shrink_count;
-   journal->j_shrinker.seeks = DEFAULT_SEEKS;
-   journal->j_shrinker.batch = journal->j_max_transaction_buffers;
 
if (percpu_counter_init(>j_checkpoint_jh_count, 0, GFP_KERNEL))
goto err_cleanup;
 
-   if (register_shrinker(>j_shrinker, "jbd2-journal:(%u:%u)",
- MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev))) {
-   percpu_counter_destroy(>j_checkpoint_jh_count);
-   goto err_cleanup;
-   }
+   journal->j_shrinker = shrinker_alloc_and_init(jbd2_journal_shrink_count,
+ jbd2_journal_shrink_scan,
+ 
journal->j_max_transaction_buffers,
+ DEFAULT_SEEKS, 0, 
journal);
+   if (!journal->j_shrinker)
+   goto err_shrinker;
+
+   if (register_shrinker(journal->j_shrinker, "jbd2-journal:(%u:%u)",
+ MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)))
+   goto err_register;
+
return journal;
 
+err_register:
+   shrinker_free(journal->j_shrinker);
+err_shrinker:
+   percpu_counter_destroy(>j_checkpoint_jh_count);
 err_cleanup:
brelse(journal->j_sb_buffer);
kfree(journal->j_wbuf);
@@ -2190,9 +2196,9 @@ int jbd2_journal_destroy(journal_t *journal)
brelse(journal->j_sb_buffer);
}
 
-   if (journal->j_shrinker.flags & SHRINKER_REGISTERED) {
+   if (journal->j_shrinker->flags & SHRINKER_REGISTERED) {
percpu_counter_destroy(>j_checkpoint_jh_count);
-   unregister_shrinker(>j_shrinker);
+   unregister_and_free_shrinker(journal->j_shrinker);
}
if (journal->j_proc_entry)
jbd2_stats_proc_exit(journal);
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 44c298aa58d4..beb4c4586320 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -891,7 +891,7 @@ struct journal_s
 * Journal head shrinker, reclaim buffer's journal head which
 * has been written back.
 */
-   struct shrinker j_shrinker;
+   struct shrinker *j_shrinker;
 
/**
 * @j_checkpoint_jh_count:
-- 
2.30.2



[Intel-gfx] [PATCH 04/29] drm/msm: dynamically allocate the drm-msm_gem shrinker

2023-06-27 Thread Qi Zheng
From: Qi Zheng 

In preparation for implementing lockless slab shrink,
we need to dynamically allocate the drm-msm_gem shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct msm_drm_private.

Signed-off-by: Qi Zheng 
---
 drivers/gpu/drm/msm/msm_drv.h  |  2 +-
 drivers/gpu/drm/msm/msm_gem_shrinker.c | 25 ++---
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index e13a8cbd61c9..4f3ba55058cd 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -217,7 +217,7 @@ struct msm_drm_private {
} vram;
 
struct notifier_block vmap_notifier;
-   struct shrinker shrinker;
+   struct shrinker *shrinker;
 
struct drm_atomic_state *pm_state;
 
diff --git a/drivers/gpu/drm/msm/msm_gem_shrinker.c 
b/drivers/gpu/drm/msm/msm_gem_shrinker.c
index f38296ad8743..db7582ae1f19 100644
--- a/drivers/gpu/drm/msm/msm_gem_shrinker.c
+++ b/drivers/gpu/drm/msm/msm_gem_shrinker.c
@@ -34,8 +34,7 @@ static bool can_block(struct shrink_control *sc)
 static unsigned long
 msm_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
 {
-   struct msm_drm_private *priv =
-   container_of(shrinker, struct msm_drm_private, shrinker);
+   struct msm_drm_private *priv = shrinker->private_data;
unsigned count = priv->lru.dontneed.count;
 
if (can_swap())
@@ -100,8 +99,7 @@ active_evict(struct drm_gem_object *obj)
 static unsigned long
 msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
 {
-   struct msm_drm_private *priv =
-   container_of(shrinker, struct msm_drm_private, shrinker);
+   struct msm_drm_private *priv = shrinker->private_data;
struct {
struct drm_gem_lru *lru;
bool (*shrink)(struct drm_gem_object *obj);
@@ -151,7 +149,7 @@ msm_gem_shrinker_shrink(struct drm_device *dev, unsigned 
long nr_to_scan)
int ret;
 
fs_reclaim_acquire(GFP_KERNEL);
-   ret = msm_gem_shrinker_scan(>shrinker, );
+   ret = msm_gem_shrinker_scan(priv->shrinker, );
fs_reclaim_release(GFP_KERNEL);
 
return ret;
@@ -213,10 +211,15 @@ msm_gem_shrinker_vmap(struct notifier_block *nb, unsigned 
long event, void *ptr)
 void msm_gem_shrinker_init(struct drm_device *dev)
 {
struct msm_drm_private *priv = dev->dev_private;
-   priv->shrinker.count_objects = msm_gem_shrinker_count;
-   priv->shrinker.scan_objects = msm_gem_shrinker_scan;
-   priv->shrinker.seeks = DEFAULT_SEEKS;
-   WARN_ON(register_shrinker(>shrinker, "drm-msm_gem"));
+
+   priv->shrinker = shrinker_alloc_and_init(msm_gem_shrinker_count,
+msm_gem_shrinker_scan, 0,
+DEFAULT_SEEKS, 0, priv);
+   if (priv->shrinker &&
+   register_shrinker(priv->shrinker, "drm-msm_gem")) {
+   shrinker_free(priv->shrinker);
+   WARN_ON(1);
+   }
 
priv->vmap_notifier.notifier_call = msm_gem_shrinker_vmap;
WARN_ON(register_vmap_purge_notifier(>vmap_notifier));
@@ -232,8 +235,8 @@ void msm_gem_shrinker_cleanup(struct drm_device *dev)
 {
struct msm_drm_private *priv = dev->dev_private;
 
-   if (priv->shrinker.nr_deferred) {
+   if (priv->shrinker->nr_deferred) {
WARN_ON(unregister_vmap_purge_notifier(>vmap_notifier));
-   unregister_shrinker(>shrinker);
+   unregister_and_free_shrinker(priv->shrinker);
}
 }
-- 
2.30.2



[Intel-gfx] [PATCH 11/29] virtio_balloon: dynamically allocate the virtio-balloon shrinker

2023-06-27 Thread Qi Zheng
From: Qi Zheng 

In preparation for implementing lockless slab shrink,
we need to dynamically allocate the virtio-balloon shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct virtio_balloon.

Signed-off-by: Qi Zheng 
---
 drivers/virtio/virtio_balloon.c | 26 --
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 5b15936a5214..fa051bff8d90 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -111,7 +111,7 @@ struct virtio_balloon {
struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR];
 
/* Shrinker to return free pages - VIRTIO_BALLOON_F_FREE_PAGE_HINT */
-   struct shrinker shrinker;
+   struct shrinker *shrinker;
 
/* OOM notifier to deflate on OOM - VIRTIO_BALLOON_F_DEFLATE_ON_OOM */
struct notifier_block oom_nb;
@@ -816,8 +816,7 @@ static unsigned long shrink_free_pages(struct 
virtio_balloon *vb,
 static unsigned long virtio_balloon_shrinker_scan(struct shrinker *shrinker,
  struct shrink_control *sc)
 {
-   struct virtio_balloon *vb = container_of(shrinker,
-   struct virtio_balloon, shrinker);
+   struct virtio_balloon *vb = shrinker->private_data;
 
return shrink_free_pages(vb, sc->nr_to_scan);
 }
@@ -825,8 +824,7 @@ static unsigned long virtio_balloon_shrinker_scan(struct 
shrinker *shrinker,
 static unsigned long virtio_balloon_shrinker_count(struct shrinker *shrinker,
   struct shrink_control *sc)
 {
-   struct virtio_balloon *vb = container_of(shrinker,
-   struct virtio_balloon, shrinker);
+   struct virtio_balloon *vb = shrinker->private_data;
 
return vb->num_free_page_blocks * VIRTIO_BALLOON_HINT_BLOCK_PAGES;
 }
@@ -847,16 +845,24 @@ static int virtio_balloon_oom_notify(struct 
notifier_block *nb,
 
 static void virtio_balloon_unregister_shrinker(struct virtio_balloon *vb)
 {
-   unregister_shrinker(>shrinker);
+   unregister_and_free_shrinker(vb->shrinker);
 }
 
 static int virtio_balloon_register_shrinker(struct virtio_balloon *vb)
 {
-   vb->shrinker.scan_objects = virtio_balloon_shrinker_scan;
-   vb->shrinker.count_objects = virtio_balloon_shrinker_count;
-   vb->shrinker.seeks = DEFAULT_SEEKS;
+   int ret;
+
+   vb->shrinker = shrinker_alloc_and_init(virtio_balloon_shrinker_count,
+  virtio_balloon_shrinker_scan,
+  0, DEFAULT_SEEKS, 0, vb);
+   if (!vb->shrinker)
+   return -ENOMEM;
+
+   ret = register_shrinker(vb->shrinker, "virtio-balloon");
+   if (ret)
+   shrinker_free(vb->shrinker);
 
-   return register_shrinker(>shrinker, "virtio-balloon");
+   return ret;
 }
 
 static int virtballoon_probe(struct virtio_device *vdev)
-- 
2.30.2



[Intel-gfx] [PATCH 24/29] mm: vmscan: make global slab shrink lockless

2023-06-27 Thread Qi Zheng
The shrinker_rwsem is a global read-write lock in
shrinkers subsystem, which protects most operations
such as slab shrink, registration and unregistration
of shrinkers, etc. This can easily cause problems in
the following cases.

1) When the memory pressure is high and there are many
   filesystems mounted or unmounted at the same time,
   slab shrink will be affected (down_read_trylock()
   failed).

   Such as the real workload mentioned by Kirill Tkhai:

   ```
   One of the real workloads from my experience is start
   of an overcommitted node containing many starting
   containers after node crash (or many resuming containers
   after reboot for kernel update). In these cases memory
   pressure is huge, and the node goes round in long reclaim.
   ```

2) If a shrinker is blocked (such as the case mentioned
   in [1]) and a writer comes in (such as mount a fs),
   then this writer will be blocked and cause all
   subsequent shrinker-related operations to be blocked.

Even if there is no competitor when shrinking slab, there
may still be a problem. If we have a long shrinker list
and we do not reclaim enough memory with each shrinker,
then the down_read_trylock() may be called with high
frequency. Because of the poor multicore scalability of
atomic operations, this can lead to a significant drop
in IPC (instructions per cycle).

We used to implement the lockless slab shrink with
SRCU [1], but then kernel test robot reported -88.8%
regression in stress-ng.ramfs.ops_per_sec test case [2],
so we reverted it [3].

This commit uses the refcount+RCU method [4] proposed by
by Dave Chinner to re-implement the lockless global slab
shrink. The memcg slab shrink is handled in the subsequent
patch.

Currently, the shrinker instances can be divided into
the following three types:

a) global shrinker instance statically defined in the kernel,
such as workingset_shadow_shrinker.

b) global shrinker instance statically defined in the kernel
modules, such as mmu_shrinker in x86.

c) shrinker instance embedded in other structures.

For case a, the memory of shrinker instance is never freed.
For case b, the memory of shrinker instance will be freed
after the module is unloaded. But we will call synchronize_rcu()
in free_module() to wait for RCU read-side critical section to
exit. For case c, the memory of shrinker instance will be
dynamically freed by calling kfree_rcu(). So we can use
rcu_read_{lock,unlock}() to ensure that the shrinker instance
is valid.

The shrinker::refcount mechanism ensures that the shrinker
instance will not be run again after unregistration. So the
structure that records the pointer of shrinker instance can be
safely freed without waiting for the RCU read-side critical
section.

In this way, while we implement the lockless slab shrink, we
don't need to be blocked in unregister_shrinker() to wait
RCU read-side critical section.

The following are the test results:

stress-ng --timeout 60 --times --verify --metrics-brief --ramfs 9 &

1) Before applying this patchset:

 setting to a 60 second run per stressor
 dispatching hogs: 9 ramfs
 stressor   bogo ops real time  usr time  sys time   bogo ops/s bogo 
ops/s
   (secs)(secs)(secs)   (real time) (usr+sys 
time)
 ramfs880623 60.02  7.71226.93 14671.45
3753.09
 ramfs:
  1 System Management Interrupt
 for a 60.03s run time:
5762.40s available CPU time
   7.71s user time   (  0.13%)
 226.93s system time (  3.94%)
 234.64s total time  (  4.07%)
 load average: 8.54 3.06 2.11
 passed: 9: ramfs (9)
 failed: 0
 skipped: 0
 successful run completed in 60.03s (1 min, 0.03 secs)

2) After applying this patchset:

 setting to a 60 second run per stressor
 dispatching hogs: 9 ramfs
 stressor   bogo ops real time  usr time  sys time   bogo ops/s bogo 
ops/s
   (secs)(secs)(secs)   (real time) (usr+sys 
time)
 ramfs847562 60.02  7.44230.22 14120.66
3566.23
 ramfs:
  4 System Management Interrupts
 for a 60.12s run time:
5771.95s available CPU time
   7.44s user time   (  0.13%)
 230.22s system time (  3.99%)
 237.66s total time  (  4.12%)
 load average: 8.18 2.43 0.84
 passed: 9: ramfs (9)
 failed: 0
 skipped: 0
 successful run completed in 60.12s (1 min, 0.12 secs)

We can see that the ops/s has hardly changed.

[1]. 
https://lore.kernel.org/lkml/20230313112819.38938-1-zhengqi.a...@bytedance.com/
[2]. https://lore.kernel.org/lkml/202305230837.db2c233f-yujie@intel.com/
[3]. https://lore.kernel.org/all/20230609081518.3039120-1-qi.zh...@linux.dev/
[4]. https://lore.kernel.org/lkml/zijhou1d55d4h...@dread.disaster.area/

Signed-off-by: Qi Zheng 
---
 include/linux/shrinker.h |  6 ++
 mm/vmscan.c  | 33 ++---
 2 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h

[Intel-gfx] [PATCH 13/29] ext4: dynamically allocate the ext4-es shrinker

2023-06-27 Thread Qi Zheng
From: Qi Zheng 

In preparation for implementing lockless slab shrink,
we need to dynamically allocate the ext4-es shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct ext4_sb_info.

Signed-off-by: Qi Zheng 
---
 fs/ext4/ext4.h   |  2 +-
 fs/ext4/extents_status.c | 21 -
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 0a2d55faa095..1bd150d454f5 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1651,7 +1651,7 @@ struct ext4_sb_info {
__u32 s_csum_seed;
 
/* Reclaim extents from extent status tree */
-   struct shrinker s_es_shrinker;
+   struct shrinker *s_es_shrinker;
struct list_head s_es_list; /* List of inodes with reclaimable 
extents */
long s_es_nr_inode;
struct ext4_es_stats s_es_stats;
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
index 9b5b8951afb4..fea82339f4b4 100644
--- a/fs/ext4/extents_status.c
+++ b/fs/ext4/extents_status.c
@@ -1596,7 +1596,7 @@ static unsigned long ext4_es_count(struct shrinker 
*shrink,
unsigned long nr;
struct ext4_sb_info *sbi;
 
-   sbi = container_of(shrink, struct ext4_sb_info, s_es_shrinker);
+   sbi = shrink->private_data;
nr = percpu_counter_read_positive(>s_es_stats.es_stats_shk_cnt);
trace_ext4_es_shrink_count(sbi->s_sb, sc->nr_to_scan, nr);
return nr;
@@ -1605,8 +1605,7 @@ static unsigned long ext4_es_count(struct shrinker 
*shrink,
 static unsigned long ext4_es_scan(struct shrinker *shrink,
  struct shrink_control *sc)
 {
-   struct ext4_sb_info *sbi = container_of(shrink,
-   struct ext4_sb_info, s_es_shrinker);
+   struct ext4_sb_info *sbi = shrink->private_data;
int nr_to_scan = sc->nr_to_scan;
int ret, nr_shrunk;
 
@@ -1690,15 +1689,19 @@ int ext4_es_register_shrinker(struct ext4_sb_info *sbi)
if (err)
goto err3;
 
-   sbi->s_es_shrinker.scan_objects = ext4_es_scan;
-   sbi->s_es_shrinker.count_objects = ext4_es_count;
-   sbi->s_es_shrinker.seeks = DEFAULT_SEEKS;
-   err = register_shrinker(>s_es_shrinker, "ext4-es:%s",
+   sbi->s_es_shrinker = shrinker_alloc_and_init(ext4_es_count, 
ext4_es_scan,
+0, DEFAULT_SEEKS, 0, sbi);
+   if (!sbi->s_es_shrinker)
+   goto err4;
+
+   err = register_shrinker(sbi->s_es_shrinker, "ext4-es:%s",
sbi->s_sb->s_id);
if (err)
-   goto err4;
+   goto err5;
 
return 0;
+err5:
+   shrinker_free(sbi->s_es_shrinker);
 err4:
percpu_counter_destroy(>s_es_stats.es_stats_shk_cnt);
 err3:
@@ -1716,7 +1719,7 @@ void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi)
percpu_counter_destroy(>s_es_stats.es_stats_cache_misses);
percpu_counter_destroy(>s_es_stats.es_stats_all_cnt);
percpu_counter_destroy(>s_es_stats.es_stats_shk_cnt);
-   unregister_shrinker(>s_es_shrinker);
+   unregister_and_free_shrinker(sbi->s_es_shrinker);
 }
 
 /*
-- 
2.30.2



[Intel-gfx] [PATCH 02/29] mm: vmscan: introduce some helpers for dynamically allocating shrinker

2023-06-27 Thread Qi Zheng
From: Qi Zheng 

Introduce some helpers for dynamically allocating shrinker instance,
and their uses are as follows:

1. shrinker_alloc_and_init()

Used to allocate and initialize a shrinker instance, the priv_data
parameter is used to pass the pointer of the previously embedded
structure of the shrinker instance.

2. shrinker_free()

Used to free the shrinker instance when the registration of shrinker
fails.

3. unregister_and_free_shrinker()

Used to unregister and free the shrinker instance, and the kfree()
will be changed to kfree_rcu() later.

Signed-off-by: Qi Zheng 
---
 include/linux/shrinker.h | 12 
 mm/vmscan.c  | 35 +++
 2 files changed, 47 insertions(+)

diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index 43e6fcabbf51..8e9ba6fa3fcc 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -107,6 +107,18 @@ extern void unregister_shrinker(struct shrinker *shrinker);
 extern void free_prealloced_shrinker(struct shrinker *shrinker);
 extern void synchronize_shrinkers(void);
 
+typedef unsigned long (*count_objects_cb)(struct shrinker *s,
+ struct shrink_control *sc);
+typedef unsigned long (*scan_objects_cb)(struct shrinker *s,
+struct shrink_control *sc);
+
+struct shrinker *shrinker_alloc_and_init(count_objects_cb count,
+scan_objects_cb scan, long batch,
+int seeks, unsigned flags,
+void *priv_data);
+void shrinker_free(struct shrinker *shrinker);
+void unregister_and_free_shrinker(struct shrinker *shrinker);
+
 #ifdef CONFIG_SHRINKER_DEBUG
 extern int shrinker_debugfs_add(struct shrinker *shrinker);
 extern struct dentry *shrinker_debugfs_detach(struct shrinker *shrinker,
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 45d17c7cc555..64ff598fbad9 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -809,6 +809,41 @@ void unregister_shrinker(struct shrinker *shrinker)
 }
 EXPORT_SYMBOL(unregister_shrinker);
 
+struct shrinker *shrinker_alloc_and_init(count_objects_cb count,
+scan_objects_cb scan, long batch,
+int seeks, unsigned flags,
+void *priv_data)
+{
+   struct shrinker *shrinker;
+
+   shrinker = kzalloc(sizeof(struct shrinker), GFP_KERNEL);
+   if (!shrinker)
+   return NULL;
+
+   shrinker->count_objects = count;
+   shrinker->scan_objects = scan;
+   shrinker->batch = batch;
+   shrinker->seeks = seeks;
+   shrinker->flags = flags;
+   shrinker->private_data = priv_data;
+
+   return shrinker;
+}
+EXPORT_SYMBOL(shrinker_alloc_and_init);
+
+void shrinker_free(struct shrinker *shrinker)
+{
+   kfree(shrinker);
+}
+EXPORT_SYMBOL(shrinker_free);
+
+void unregister_and_free_shrinker(struct shrinker *shrinker)
+{
+   unregister_shrinker(shrinker);
+   kfree(shrinker);
+}
+EXPORT_SYMBOL(unregister_and_free_shrinker);
+
 /**
  * synchronize_shrinkers - Wait for all running shrinkers to complete.
  *
-- 
2.30.2



[Intel-gfx] [PATCH 07/11] sysctl: Add size to register_sysctl

2023-06-27 Thread Joel Granados
In order to remove the end element from the ctl_table struct arrays, we
explicitly define the size when registering the targes.
We add a size argument to register_sysctl and change all the callers to
pass the ARRAY_SIZE of their table arg.

Signed-off-by: Joel Granados 
---
 arch/arm/kernel/isa.c |  2 +-
 arch/arm64/kernel/armv8_deprecated.c  |  2 +-
 arch/arm64/kernel/fpsimd.c|  6 +++--
 arch/arm64/kernel/process.c   |  3 ++-
 arch/ia64/kernel/crash.c  |  3 ++-
 arch/powerpc/kernel/idle.c|  3 ++-
 arch/powerpc/platforms/pseries/mobility.c |  3 ++-
 arch/s390/appldata/appldata_base.c|  4 +++-
 arch/s390/kernel/debug.c  |  3 ++-
 arch/s390/kernel/topology.c   |  3 ++-
 arch/s390/mm/cmm.c|  3 ++-
 arch/s390/mm/pgalloc.c|  3 ++-
 arch/x86/entry/vdso/vdso32-setup.c|  2 +-
 arch/x86/kernel/itmt.c|  3 ++-
 crypto/fips.c |  3 ++-
 drivers/base/firmware_loader/fallback_table.c |  6 ++---
 drivers/cdrom/cdrom.c |  3 ++-
 drivers/char/hpet.c   |  3 ++-
 drivers/char/ipmi/ipmi_poweroff.c |  3 ++-
 drivers/gpu/drm/i915/i915_perf.c  |  3 ++-
 drivers/hv/hv_common.c|  3 ++-
 drivers/macintosh/mac_hid.c   |  3 ++-
 drivers/md/md.c   |  3 ++-
 drivers/misc/sgi-xp/xpc_main.c|  6 +++--
 drivers/parport/procfs.c  | 11 +
 drivers/perf/arm_pmuv3.c  |  3 ++-
 drivers/scsi/scsi_sysctl.c|  3 ++-
 drivers/scsi/sg.c |  3 ++-
 fs/cachefiles/error_inject.c  |  3 ++-
 fs/coda/sysctl.c  |  3 ++-
 fs/devpts/inode.c |  3 ++-
 fs/eventpoll.c|  2 +-
 fs/lockd/svc.c|  3 ++-
 fs/nfs/nfs4sysctl.c   |  3 ++-
 fs/nfs/sysctl.c   |  3 ++-
 fs/notify/fanotify/fanotify_user.c|  3 ++-
 fs/notify/inotify/inotify_user.c  |  3 ++-
 fs/ntfs/sysctl.c  |  3 ++-
 fs/ocfs2/stackglue.c  |  3 ++-
 fs/proc/proc_sysctl.c | 23 ++-
 fs/verity/signature.c |  4 +++-
 fs/xfs/xfs_sysctl.c   |  3 ++-
 include/linux/sysctl.h|  6 +++--
 kernel/pid_sysctl.h   |  2 +-
 kernel/time/timer.c   |  2 +-
 kernel/ucount.c   |  2 +-
 kernel/utsname_sysctl.c   |  2 +-
 lib/test_sysctl.c |  9 +---
 net/sunrpc/sysctl.c   |  3 ++-
 net/sunrpc/xprtrdma/svc_rdma.c|  3 ++-
 net/sunrpc/xprtrdma/transport.c   |  4 +++-
 net/sunrpc/xprtsock.c |  4 +++-
 net/sysctl_net.c  |  2 +-
 security/apparmor/lsm.c   |  3 ++-
 security/loadpin/loadpin.c|  3 ++-
 security/yama/yama_lsm.c  |  3 ++-
 56 files changed, 133 insertions(+), 76 deletions(-)

diff --git a/arch/arm/kernel/isa.c b/arch/arm/kernel/isa.c
index 20218876bef2..561432e3c55a 100644
--- a/arch/arm/kernel/isa.c
+++ b/arch/arm/kernel/isa.c
@@ -46,5 +46,5 @@ register_isa_ports(unsigned int membase, unsigned int 
portbase, unsigned int por
isa_membase = membase;
isa_portbase = portbase;
isa_portshift = portshift;
-   isa_sysctl_header = register_sysctl("bus/isa", ctl_isa_vars);
+   isa_sysctl_header = register_sysctl("bus/isa", ctl_isa_vars, 
ARRAY_SIZE(ctl_isa_vars));
 }
diff --git a/arch/arm64/kernel/armv8_deprecated.c 
b/arch/arm64/kernel/armv8_deprecated.c
index 1febd412b4d2..68ed60a521a6 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -569,7 +569,7 @@ static void __init register_insn_emulation(struct 
insn_emulation *insn)
sysctl->extra2 = >max;
sysctl->proc_handler = emulation_proc_handler;
 
-   register_sysctl("abi", sysctl);
+   register_sysctl("abi", sysctl, 1);
}
 }
 
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 2fbafa5cc7ac..ecfb2ef6a036 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -595,7 +595,8 @@ static struct ctl_table sve_default_vl_table[] = {
 static int __init sve_sysctl_init(void)
 {
if (system_supports_sve())
-   if (!register_sysctl("abi", sve_default_vl_table))
+   if (!register_sysctl("abi", 

[Intel-gfx] [PATCH 00/29] use refcount+RCU method to implement lockless slab shrink

2023-06-27 Thread Qi Zheng
From: Qi Zheng 

Hi all,

1. Background
=

We used to implement the lockless slab shrink with SRCU [1], but then kernel
test robot reported -88.8% regression in stress-ng.ramfs.ops_per_sec test
case [2], so we reverted it [3].

This patch series aims to re-implement the lockless slab shrink using the
refcount+RCU method proposed by Dave Chinner [4].

[1]. 
https://lore.kernel.org/lkml/20230313112819.38938-1-zhengqi.a...@bytedance.com/
[2]. https://lore.kernel.org/lkml/202305230837.db2c233f-yujie@intel.com/
[3]. https://lore.kernel.org/all/20230609081518.3039120-1-qi.zh...@linux.dev/
[4]. https://lore.kernel.org/lkml/zijhou1d55d4h...@dread.disaster.area/

2. Implementation
=

Currently, the shrinker instances can be divided into the following three types:

a) global shrinker instance statically defined in the kernel, such as
   workingset_shadow_shrinker.

b) global shrinker instance statically defined in the kernel modules, such as
   mmu_shrinker in x86.

c) shrinker instance embedded in other structures.

For *case a*, the memory of shrinker instance is never freed. For *case b*, the
memory of shrinker instance will be freed after the module is unloaded. But we
will call synchronize_rcu() in free_module() to wait for RCU read-side critical
section to exit. For *case c*, we need to dynamically allocate these shrinker
instances, then the memory of shrinker instance can be dynamically freed alone
by calling kfree_rcu(). Then we can use rcu_read_{lock,unlock}() to ensure that
the shrinker instance is valid.

The shrinker::refcount mechanism ensures that the shrinker instance will not be
run again after unregistration. So the structure that records the pointer of
shrinker instance can be safely freed without waiting for the RCU read-side
critical section.

In this way, while we implement the lockless slab shrink, we don't need to be
blocked in unregister_shrinker() to wait RCU read-side critical section.

PATCH 1 ~ 2: infrastructure for dynamically allocating shrinker instances
PATCH 3 ~ 21: dynamically allocate the shrinker instances in case c
PATCH 22: introduce pool_shrink_rwsem to implement private 
synchronize_shrinkers()
PATCH 23 ~ 28: implement the lockless slab shrink
PATCH 29: move shrinker-related code into a separate file

3. Testing
==

3.1 slab shrink stress test
---

We can reproduce the down_read_trylock() hotspot through the following script:

```

DIR="/root/shrinker/memcg/mnt"

do_create()
{
mkdir -p /sys/fs/cgroup/memory/test
mkdir -p /sys/fs/cgroup/perf_event/test
echo 4G > /sys/fs/cgroup/memory/test/memory.limit_in_bytes
for i in `seq 0 $1`;
do
mkdir -p /sys/fs/cgroup/memory/test/$i;
echo $$ > /sys/fs/cgroup/memory/test/$i/cgroup.procs;
echo $$ > /sys/fs/cgroup/perf_event/test/cgroup.procs;
mkdir -p $DIR/$i;
done
}

do_mount()
{
for i in `seq $1 $2`;
do
mount -t tmpfs $i $DIR/$i;
done
}

do_touch()
{
for i in `seq $1 $2`;
do
echo $$ > /sys/fs/cgroup/memory/test/$i/cgroup.procs;
echo $$ > /sys/fs/cgroup/perf_event/test/cgroup.procs;
dd if=/dev/zero of=$DIR/$i/file$i bs=1M count=1 &
done
}

case "$1" in
  touch)
do_touch $2 $3
;;
  test)
do_create 4000
do_mount 0 4000
do_touch 0 3000
;;
  *)
exit 1
;;
esac
```

Save the above script, then run test and touch commands. Then we can use the
following perf command to view hotspots:

perf top -U -F 999 [-g]

1) Before applying this patchset:

  35.34%  [kernel] [k] down_read_trylock
  18.44%  [kernel] [k] shrink_slab
  15.98%  [kernel] [k] pv_native_safe_halt
  15.08%  [kernel] [k] up_read
   5.33%  [kernel] [k] idr_find
   2.71%  [kernel] [k] _find_next_bit
   2.21%  [kernel] [k] shrink_node
   1.29%  [kernel] [k] shrink_lruvec
   0.66%  [kernel] [k] do_shrink_slab
   0.33%  [kernel] [k] list_lru_count_one
   0.33%  [kernel] [k] __radix_tree_lookup
   0.25%  [kernel] [k] mem_cgroup_iter

-   82.19%19.49%  [kernel]  [k] shrink_slab
   - 62.00% shrink_slab
36.37% down_read_trylock
15.52% up_read
5.48% idr_find
3.38% _find_next_bit
  + 0.98% do_shrink_slab

2) After applying this patchset:

  46.83%  [kernel]   [k] shrink_slab
  20.52%  [kernel]   [k] pv_native_safe_halt
   8.85%  [kernel]   [k] do_shrink_slab
   7.71%  [kernel]   [k] _find_next_bit
   1.72%  [kernel]   [k] xas_descend
   1.70%  [kernel]   [k] shrink_node
   1.44%  [kernel]   [k] shrink_lruvec
   1.43%  [kernel]   [k] mem_cgroup_iter
   1.28%  [kernel]   [k] xas_load
   0.89%  [kernel]   [k] super_cache_count
   0.84%  [kernel]   [k] xas_start
   0.66%  [kernel]   [k] 

Re: [Intel-gfx] [PATCH 24/29] mm: vmscan: make global slab shrink lockless

2023-06-27 Thread Qi Zheng

Hi Dave,

On 2023/6/24 06:19, Dave Chinner wrote:

On Fri, Jun 23, 2023 at 09:10:57PM +0800, Qi Zheng wrote:

On 2023/6/23 14:29, Dave Chinner wrote:

On Thu, Jun 22, 2023 at 05:12:02PM +0200, Vlastimil Babka wrote:

On 6/22/23 10:53, Qi Zheng wrote:

Yes, I suggested the IDR route because radix tree lookups under RCU
with reference counted objects are a known safe pattern that we can
easily confirm is correct or not.  Hence I suggested the unification
+ IDR route because it makes the life of reviewers so, so much
easier...


In fact, I originally planned to try the unification + IDR method you
suggested at the beginning. But in the case of CONFIG_MEMCG disabled,
the struct mem_cgroup is not even defined, and root_mem_cgroup and
shrinker_info will not be allocated.  This required more code changes, so
I ended up keeping the shrinker_list and implementing the above pattern.


Yes. Go back and read what I originally said needed to be done
first. In the case of CONFIG_MEMCG=n, a dummy root memcg still needs
to exist that holds all of the global shrinkers. Then shrink_slab()
is only ever passed a memcg that should be iterated.

Yes, it needs changes external to the shrinker code itself to be
made to work. And even if memcg's are not enabled, we can still use
the memcg structures to ensure a common abstraction is used for the
shrinker tracking infrastructure


Yeah, what I imagined before was to define a more concise struct
mem_cgroup in the case of CONFIG_MEMCG=n, then allocate a dummy root
memcg on system boot:

#ifdef !CONFIG_MEMCG

struct shrinker_info {
struct rcu_head rcu;
atomic_long_t *nr_deferred;
unsigned long *map;
int map_nr_max;
};

struct mem_cgroup_per_node {
struct shrinker_info __rcu  *shrinker_info;
};

struct mem_cgroup {
struct mem_cgroup_per_node *nodeinfo[];
};

#endif

But I have a concern: if all global shrinkers are tracking with the
info->map of root memcg, a shrinker->id needs to be assigned to them,
which will cause info->map_nr_max to become larger than before, then
making the traversal of info->map slower.




If the above pattern is not safe, I will go back to the unification +
IDR method.


And that is exactly how we got into this mess in the first place


I only found one similar pattern in the kernel:

fs/smb/server/oplock.c:find_same_lease_key/smb_break_all_levII_oplock/lookup_lease_in_table

But IIUC, the refcount here needs to be decremented after holding
rcu lock as I did above.

So regardless of whether we choose unification + IDR in the end, I still
want to confirm whether the pattern I implemented above is safe. :)

Thanks,
Qi



-Dave


Re: [Intel-gfx] [PATCH 15/29] NFSD: dynamically allocate the nfsd-client shrinker

2023-06-27 Thread Qi Zheng

Hi Chuck,

On 2023/6/24 05:49, Chuck Lever wrote:

On Thu, Jun 22, 2023 at 04:53:21PM +0800, Qi Zheng wrote:

In preparation for implementing lockless slab shrink,
we need to dynamically allocate the nfsd-client shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct nfsd_net.

Signed-off-by: Qi Zheng 


For 15/29 and 16/29 of this series:

Acked-by: Chuck Lever 


Thanks for your review! :)

And I will implement the APIs suggested by Dave in 02/29 in
the v2, so there will be some changes here, but it should
not be much. So I will keep your Acked-bys in the v2.

Thanks,
Qi





---
  fs/nfsd/netns.h |  2 +-
  fs/nfsd/nfs4state.c | 20 
  2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index ec49b200b797..f669444d5336 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -195,7 +195,7 @@ struct nfsd_net {
int nfs4_max_clients;
  
  	atomic_t		nfsd_courtesy_clients;

-   struct shrinker nfsd_client_shrinker;
+   struct shrinker *nfsd_client_shrinker;
struct work_struct  nfsd_shrinker_work;
  };
  
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c

index 6e61fa3acaf1..a06184270548 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -4388,8 +4388,7 @@ static unsigned long
  nfsd4_state_shrinker_count(struct shrinker *shrink, struct shrink_control *sc)
  {
int count;
-   struct nfsd_net *nn = container_of(shrink,
-   struct nfsd_net, nfsd_client_shrinker);
+   struct nfsd_net *nn = shrink->private_data;
  
  	count = atomic_read(>nfsd_courtesy_clients);

if (!count)
@@ -8094,14 +8093,19 @@ static int nfs4_state_create_net(struct net *net)
INIT_WORK(>nfsd_shrinker_work, nfsd4_state_shrinker_worker);
get_net(net);
  
-	nn->nfsd_client_shrinker.scan_objects = nfsd4_state_shrinker_scan;

-   nn->nfsd_client_shrinker.count_objects = nfsd4_state_shrinker_count;
-   nn->nfsd_client_shrinker.seeks = DEFAULT_SEEKS;
-
-   if (register_shrinker(>nfsd_client_shrinker, "nfsd-client"))
+   nn->nfsd_client_shrinker = 
shrinker_alloc_and_init(nfsd4_state_shrinker_count,
+  
nfsd4_state_shrinker_scan,
+  0, DEFAULT_SEEKS, 0,
+  nn);
+   if (!nn->nfsd_client_shrinker)
goto err_shrinker;
+
+   if (register_shrinker(nn->nfsd_client_shrinker, "nfsd-client"))
+   goto err_register;
return 0;
  
+err_register:

+   shrinker_free(nn->nfsd_client_shrinker);
  err_shrinker:
put_net(net);
kfree(nn->sessionid_hashtbl);
@@ -8197,7 +8201,7 @@ nfs4_state_shutdown_net(struct net *net)
struct list_head *pos, *next, reaplist;
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  
-	unregister_shrinker(>nfsd_client_shrinker);

+   unregister_and_free_shrinker(nn->nfsd_client_shrinker);
cancel_work(>nfsd_shrinker_work);
cancel_delayed_work_sync(>laundromat_work);
locks_end_grace(>nfsd4_manager);
--
2.30.2



[Intel-gfx] [PATCH 04/29] drm/msm: dynamically allocate the drm-msm_gem shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the drm-msm_gem shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct msm_drm_private.

Signed-off-by: Qi Zheng 
---
 drivers/gpu/drm/msm/msm_drv.h  |  2 +-
 drivers/gpu/drm/msm/msm_gem_shrinker.c | 25 ++---
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index e13a8cbd61c9..4f3ba55058cd 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -217,7 +217,7 @@ struct msm_drm_private {
} vram;
 
struct notifier_block vmap_notifier;
-   struct shrinker shrinker;
+   struct shrinker *shrinker;
 
struct drm_atomic_state *pm_state;
 
diff --git a/drivers/gpu/drm/msm/msm_gem_shrinker.c 
b/drivers/gpu/drm/msm/msm_gem_shrinker.c
index f38296ad8743..db7582ae1f19 100644
--- a/drivers/gpu/drm/msm/msm_gem_shrinker.c
+++ b/drivers/gpu/drm/msm/msm_gem_shrinker.c
@@ -34,8 +34,7 @@ static bool can_block(struct shrink_control *sc)
 static unsigned long
 msm_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
 {
-   struct msm_drm_private *priv =
-   container_of(shrinker, struct msm_drm_private, shrinker);
+   struct msm_drm_private *priv = shrinker->private_data;
unsigned count = priv->lru.dontneed.count;
 
if (can_swap())
@@ -100,8 +99,7 @@ active_evict(struct drm_gem_object *obj)
 static unsigned long
 msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
 {
-   struct msm_drm_private *priv =
-   container_of(shrinker, struct msm_drm_private, shrinker);
+   struct msm_drm_private *priv = shrinker->private_data;
struct {
struct drm_gem_lru *lru;
bool (*shrink)(struct drm_gem_object *obj);
@@ -151,7 +149,7 @@ msm_gem_shrinker_shrink(struct drm_device *dev, unsigned 
long nr_to_scan)
int ret;
 
fs_reclaim_acquire(GFP_KERNEL);
-   ret = msm_gem_shrinker_scan(>shrinker, );
+   ret = msm_gem_shrinker_scan(priv->shrinker, );
fs_reclaim_release(GFP_KERNEL);
 
return ret;
@@ -213,10 +211,15 @@ msm_gem_shrinker_vmap(struct notifier_block *nb, unsigned 
long event, void *ptr)
 void msm_gem_shrinker_init(struct drm_device *dev)
 {
struct msm_drm_private *priv = dev->dev_private;
-   priv->shrinker.count_objects = msm_gem_shrinker_count;
-   priv->shrinker.scan_objects = msm_gem_shrinker_scan;
-   priv->shrinker.seeks = DEFAULT_SEEKS;
-   WARN_ON(register_shrinker(>shrinker, "drm-msm_gem"));
+
+   priv->shrinker = shrinker_alloc_and_init(msm_gem_shrinker_count,
+msm_gem_shrinker_scan, 0,
+DEFAULT_SEEKS, 0, priv);
+   if (priv->shrinker &&
+   register_shrinker(priv->shrinker, "drm-msm_gem")) {
+   shrinker_free(priv->shrinker);
+   WARN_ON(1);
+   }
 
priv->vmap_notifier.notifier_call = msm_gem_shrinker_vmap;
WARN_ON(register_vmap_purge_notifier(>vmap_notifier));
@@ -232,8 +235,8 @@ void msm_gem_shrinker_cleanup(struct drm_device *dev)
 {
struct msm_drm_private *priv = dev->dev_private;
 
-   if (priv->shrinker.nr_deferred) {
+   if (priv->shrinker->nr_deferred) {
WARN_ON(unregister_vmap_purge_notifier(>vmap_notifier));
-   unregister_shrinker(>shrinker);
+   unregister_and_free_shrinker(priv->shrinker);
}
 }
-- 
2.30.2



[Intel-gfx] [PATCH 15/29] NFSD: dynamically allocate the nfsd-client shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the nfsd-client shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct nfsd_net.

Signed-off-by: Qi Zheng 
---
 fs/nfsd/netns.h |  2 +-
 fs/nfsd/nfs4state.c | 20 
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index ec49b200b797..f669444d5336 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -195,7 +195,7 @@ struct nfsd_net {
int nfs4_max_clients;
 
atomic_tnfsd_courtesy_clients;
-   struct shrinker nfsd_client_shrinker;
+   struct shrinker *nfsd_client_shrinker;
struct work_struct  nfsd_shrinker_work;
 };
 
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 6e61fa3acaf1..a06184270548 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -4388,8 +4388,7 @@ static unsigned long
 nfsd4_state_shrinker_count(struct shrinker *shrink, struct shrink_control *sc)
 {
int count;
-   struct nfsd_net *nn = container_of(shrink,
-   struct nfsd_net, nfsd_client_shrinker);
+   struct nfsd_net *nn = shrink->private_data;
 
count = atomic_read(>nfsd_courtesy_clients);
if (!count)
@@ -8094,14 +8093,19 @@ static int nfs4_state_create_net(struct net *net)
INIT_WORK(>nfsd_shrinker_work, nfsd4_state_shrinker_worker);
get_net(net);
 
-   nn->nfsd_client_shrinker.scan_objects = nfsd4_state_shrinker_scan;
-   nn->nfsd_client_shrinker.count_objects = nfsd4_state_shrinker_count;
-   nn->nfsd_client_shrinker.seeks = DEFAULT_SEEKS;
-
-   if (register_shrinker(>nfsd_client_shrinker, "nfsd-client"))
+   nn->nfsd_client_shrinker = 
shrinker_alloc_and_init(nfsd4_state_shrinker_count,
+  
nfsd4_state_shrinker_scan,
+  0, DEFAULT_SEEKS, 0,
+  nn);
+   if (!nn->nfsd_client_shrinker)
goto err_shrinker;
+
+   if (register_shrinker(nn->nfsd_client_shrinker, "nfsd-client"))
+   goto err_register;
return 0;
 
+err_register:
+   shrinker_free(nn->nfsd_client_shrinker);
 err_shrinker:
put_net(net);
kfree(nn->sessionid_hashtbl);
@@ -8197,7 +8201,7 @@ nfs4_state_shutdown_net(struct net *net)
struct list_head *pos, *next, reaplist;
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 
-   unregister_shrinker(>nfsd_client_shrinker);
+   unregister_and_free_shrinker(nn->nfsd_client_shrinker);
cancel_work(>nfsd_shrinker_work);
cancel_delayed_work_sync(>laundromat_work);
locks_end_grace(>nfsd4_manager);
-- 
2.30.2



[Intel-gfx] [PATCH 19/29] xfs: dynamically allocate the xfs-qm shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the xfs-qm shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct xfs_quotainfo.

Signed-off-by: Qi Zheng 
---
 fs/xfs/xfs_qm.c | 24 +---
 fs/xfs/xfs_qm.h |  2 +-
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 6abcc34fafd8..b15320d469cc 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -504,8 +504,7 @@ xfs_qm_shrink_scan(
struct shrinker *shrink,
struct shrink_control   *sc)
 {
-   struct xfs_quotainfo*qi = container_of(shrink,
-   struct xfs_quotainfo, qi_shrinker);
+   struct xfs_quotainfo*qi = shrink->private_data;
struct xfs_qm_isolate   isol;
unsigned long   freed;
int error;
@@ -539,8 +538,7 @@ xfs_qm_shrink_count(
struct shrinker *shrink,
struct shrink_control   *sc)
 {
-   struct xfs_quotainfo*qi = container_of(shrink,
-   struct xfs_quotainfo, qi_shrinker);
+   struct xfs_quotainfo*qi = shrink->private_data;
 
return list_lru_shrink_count(>qi_lru, sc);
 }
@@ -680,18 +678,22 @@ xfs_qm_init_quotainfo(
if (XFS_IS_PQUOTA_ON(mp))
xfs_qm_set_defquota(mp, XFS_DQTYPE_PROJ, qinf);
 
-   qinf->qi_shrinker.count_objects = xfs_qm_shrink_count;
-   qinf->qi_shrinker.scan_objects = xfs_qm_shrink_scan;
-   qinf->qi_shrinker.seeks = DEFAULT_SEEKS;
-   qinf->qi_shrinker.flags = SHRINKER_NUMA_AWARE;
+   qinf->qi_shrinker = shrinker_alloc_and_init(xfs_qm_shrink_count,
+   xfs_qm_shrink_scan,
+   0, DEFAULT_SEEKS,
+   SHRINKER_NUMA_AWARE, qinf);
+   if (!qinf->qi_shrinker)
+   goto out_free_inos;
 
-   error = register_shrinker(>qi_shrinker, "xfs-qm:%s",
+   error = register_shrinker(qinf->qi_shrinker, "xfs-qm:%s",
  mp->m_super->s_id);
if (error)
-   goto out_free_inos;
+   goto out_shrinker;
 
return 0;
 
+out_shrinker:
+   shrinker_free(qinf->qi_shrinker);
 out_free_inos:
mutex_destroy(>qi_quotaofflock);
mutex_destroy(>qi_tree_lock);
@@ -718,7 +720,7 @@ xfs_qm_destroy_quotainfo(
qi = mp->m_quotainfo;
ASSERT(qi != NULL);
 
-   unregister_shrinker(>qi_shrinker);
+   unregister_and_free_shrinker(qi->qi_shrinker);
list_lru_destroy(>qi_lru);
xfs_qm_destroy_quotainos(qi);
mutex_destroy(>qi_tree_lock);
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 9683f0457d19..d5c9fc4ba591 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -63,7 +63,7 @@ struct xfs_quotainfo {
struct xfs_def_quotaqi_usr_default;
struct xfs_def_quotaqi_grp_default;
struct xfs_def_quotaqi_prj_default;
-   struct shrinker qi_shrinker;
+   struct shrinker *qi_shrinker;
 
/* Minimum and maximum quota expiration timestamp values. */
time64_tqi_expiry_min;
-- 
2.30.2



[Intel-gfx] [PATCH 05/29] drm/panfrost: dynamically allocate the drm-panfrost shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the drm-panfrost shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct panfrost_device.

Signed-off-by: Qi Zheng 
---
 drivers/gpu/drm/panfrost/panfrost_device.h|  2 +-
 .../gpu/drm/panfrost/panfrost_gem_shrinker.c  | 24 ++-
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
b/drivers/gpu/drm/panfrost/panfrost_device.h
index b0126b9fbadc..e667e5689353 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -118,7 +118,7 @@ struct panfrost_device {
 
struct mutex shrinker_lock;
struct list_head shrinker_list;
-   struct shrinker shrinker;
+   struct shrinker *shrinker;
 
struct panfrost_devfreq pfdevfreq;
 };
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c 
b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
index bf0170782f25..2a5513eb9e1f 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
@@ -18,8 +18,7 @@
 static unsigned long
 panfrost_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control 
*sc)
 {
-   struct panfrost_device *pfdev =
-   container_of(shrinker, struct panfrost_device, shrinker);
+   struct panfrost_device *pfdev = shrinker->private_data;
struct drm_gem_shmem_object *shmem;
unsigned long count = 0;
 
@@ -65,8 +64,7 @@ static bool panfrost_gem_purge(struct drm_gem_object *obj)
 static unsigned long
 panfrost_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control 
*sc)
 {
-   struct panfrost_device *pfdev =
-   container_of(shrinker, struct panfrost_device, shrinker);
+   struct panfrost_device *pfdev = shrinker->private_data;
struct drm_gem_shmem_object *shmem, *tmp;
unsigned long freed = 0;
 
@@ -100,10 +98,15 @@ panfrost_gem_shrinker_scan(struct shrinker *shrinker, 
struct shrink_control *sc)
 void panfrost_gem_shrinker_init(struct drm_device *dev)
 {
struct panfrost_device *pfdev = dev->dev_private;
-   pfdev->shrinker.count_objects = panfrost_gem_shrinker_count;
-   pfdev->shrinker.scan_objects = panfrost_gem_shrinker_scan;
-   pfdev->shrinker.seeks = DEFAULT_SEEKS;
-   WARN_ON(register_shrinker(>shrinker, "drm-panfrost"));
+
+   pfdev->shrinker = shrinker_alloc_and_init(panfrost_gem_shrinker_count,
+ panfrost_gem_shrinker_scan, 0,
+ DEFAULT_SEEKS, 0, pfdev);
+   if (pfdev->shrinker &&
+   register_shrinker(pfdev->shrinker, "drm-panfrost")) {
+   shrinker_free(pfdev->shrinker);
+   WARN_ON(1);
+   }
 }
 
 /**
@@ -116,7 +119,6 @@ void panfrost_gem_shrinker_cleanup(struct drm_device *dev)
 {
struct panfrost_device *pfdev = dev->dev_private;
 
-   if (pfdev->shrinker.nr_deferred) {
-   unregister_shrinker(>shrinker);
-   }
+   if (pfdev->shrinker->nr_deferred)
+   unregister_and_free_shrinker(pfdev->shrinker);
 }
-- 
2.30.2



Re: [Intel-gfx] [PATCH 05/29] drm/panfrost: dynamically allocate the drm-panfrost shrinker

2023-06-27 Thread Bobs_Email
Please remove Bob Lee from this email group.
He is deceased


On Thu, Jun 22, 2023, 1:56 AM Qi Zheng  wrote:

> In preparation for implementing lockless slab shrink,
> we need to dynamically allocate the drm-panfrost shrinker,
> so that it can be freed asynchronously using kfree_rcu().
> Then it doesn't need to wait for RCU read-side critical
> section when releasing the struct panfrost_device.
>
> Signed-off-by: Qi Zheng 
> ---
>  drivers/gpu/drm/panfrost/panfrost_device.h|  2 +-
>  .../gpu/drm/panfrost/panfrost_gem_shrinker.c  | 24 ++-
>  2 files changed, 14 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h
> b/drivers/gpu/drm/panfrost/panfrost_device.h
> index b0126b9fbadc..e667e5689353 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_device.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_device.h
> @@ -118,7 +118,7 @@ struct panfrost_device {
>
> struct mutex shrinker_lock;
> struct list_head shrinker_list;
> -   struct shrinker shrinker;
> +   struct shrinker *shrinker;
>
> struct panfrost_devfreq pfdevfreq;
>  };
> diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
> b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
> index bf0170782f25..2a5513eb9e1f 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
> @@ -18,8 +18,7 @@
>  static unsigned long
>  panfrost_gem_shrinker_count(struct shrinker *shrinker, struct
> shrink_control *sc)
>  {
> -   struct panfrost_device *pfdev =
> -   container_of(shrinker, struct panfrost_device, shrinker);
> +   struct panfrost_device *pfdev = shrinker->private_data;
> struct drm_gem_shmem_object *shmem;
> unsigned long count = 0;
>
> @@ -65,8 +64,7 @@ static bool panfrost_gem_purge(struct drm_gem_object
> *obj)
>  static unsigned long
>  panfrost_gem_shrinker_scan(struct shrinker *shrinker, struct
> shrink_control *sc)
>  {
> -   struct panfrost_device *pfdev =
> -   container_of(shrinker, struct panfrost_device, shrinker);
> +   struct panfrost_device *pfdev = shrinker->private_data;
> struct drm_gem_shmem_object *shmem, *tmp;
> unsigned long freed = 0;
>
> @@ -100,10 +98,15 @@ panfrost_gem_shrinker_scan(struct shrinker *shrinker,
> struct shrink_control *sc)
>  void panfrost_gem_shrinker_init(struct drm_device *dev)
>  {
> struct panfrost_device *pfdev = dev->dev_private;
> -   pfdev->shrinker.count_objects = panfrost_gem_shrinker_count;
> -   pfdev->shrinker.scan_objects = panfrost_gem_shrinker_scan;
> -   pfdev->shrinker.seeks = DEFAULT_SEEKS;
> -   WARN_ON(register_shrinker(>shrinker, "drm-panfrost"));
> +
> +   pfdev->shrinker =
> shrinker_alloc_and_init(panfrost_gem_shrinker_count,
> +
>  panfrost_gem_shrinker_scan, 0,
> + DEFAULT_SEEKS, 0, pfdev);
> +   if (pfdev->shrinker &&
> +   register_shrinker(pfdev->shrinker, "drm-panfrost")) {
> +   shrinker_free(pfdev->shrinker);
> +   WARN_ON(1);
> +   }
>  }
>
>  /**
> @@ -116,7 +119,6 @@ void panfrost_gem_shrinker_cleanup(struct drm_device
> *dev)
>  {
> struct panfrost_device *pfdev = dev->dev_private;
>
> -   if (pfdev->shrinker.nr_deferred) {
> -   unregister_shrinker(>shrinker);
> -   }
> +   if (pfdev->shrinker->nr_deferred)
> +   unregister_and_free_shrinker(pfdev->shrinker);
>  }
> --
> 2.30.2
>
>


Re: [Intel-gfx] [PATCH 24/29] mm: vmscan: make global slab shrink lockless

2023-06-27 Thread Qi Zheng




On 2023/6/23 14:29, Dave Chinner wrote:

On Thu, Jun 22, 2023 at 05:12:02PM +0200, Vlastimil Babka wrote:

On 6/22/23 10:53, Qi Zheng wrote:

@@ -1067,33 +1068,27 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int 
nid,
if (!mem_cgroup_disabled() && !mem_cgroup_is_root(memcg))
return shrink_slab_memcg(gfp_mask, nid, memcg, priority);
  
-	if (!down_read_trylock(_rwsem))

-   goto out;
-
-   list_for_each_entry(shrinker, _list, list) {
+   rcu_read_lock();
+   list_for_each_entry_rcu(shrinker, _list, list) {
struct shrink_control sc = {
.gfp_mask = gfp_mask,
.nid = nid,
.memcg = memcg,
};
  
+		if (!shrinker_try_get(shrinker))

+   continue;
+   rcu_read_unlock();


I don't think you can do this unlock?


+
ret = do_shrink_slab(, shrinker, priority);
if (ret == SHRINK_EMPTY)
ret = 0;
freed += ret;
-   /*
-* Bail out if someone want to register a new shrinker to
-* prevent the registration from being stalled for long periods
-* by parallel ongoing shrinking.
-*/
-   if (rwsem_is_contended(_rwsem)) {
-   freed = freed ? : 1;
-   break;
-   }
-   }
  
-	up_read(_rwsem);

-out:
+   rcu_read_lock();


That new rcu_read_lock() won't help AFAIK, the whole
list_for_each_entry_rcu() needs to be under the single rcu_read_lock() to be
safe.


Yeah, that's the pattern we've been taught and the one we can look
at and immediately say "this is safe".

This is a different pattern, as has been explained bi Qi, and I
think it *might* be safe.

*However.*

Right now I don't have time to go through a novel RCU list iteration
pattern it one step at to determine the correctness of the
algorithm. I'm mostly worried about list manipulations that can
occur outside rcu_read_lock() section bleeding into the RCU
critical section because rcu_read_lock() by itself is not a memory
barrier.

Maybe Paul has seen this pattern often enough he could simply tell
us what conditions it is safe in. But for me to work that out from
first principles? I just don't have the time to do that right now.


Hi Paul, can you help to confirm this?




IIUC this is why Dave in [4] suggests unifying shrink_slab() with
shrink_slab_memcg(), as the latter doesn't iterate the list but uses IDR.


Yes, I suggested the IDR route because radix tree lookups under RCU
with reference counted objects are a known safe pattern that we can
easily confirm is correct or not.  Hence I suggested the unification
+ IDR route because it makes the life of reviewers so, so much
easier...


In fact, I originally planned to try the unification + IDR method you
suggested at the beginning. But in the case of CONFIG_MEMCG disabled,
the struct mem_cgroup is not even defined, and root_mem_cgroup and
shrinker_info will not be allocated. This required more code changes, so
I ended up keeping the shrinker_list and implementing the above pattern.

If the above pattern is not safe, I will go back to the unification +
IDR method.

Thanks,
Qi



Cheers,

Dave.


[Intel-gfx] [PATCH 08/29] md/raid5: dynamically allocate the md-raid5 shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the md-raid5 shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct r5conf.

Signed-off-by: Qi Zheng 
---
 drivers/md/raid5.c | 28 +---
 drivers/md/raid5.h |  2 +-
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index f4eea1bbbeaf..4866cad1ad62 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -7391,7 +7391,7 @@ static void free_conf(struct r5conf *conf)
 
log_exit(conf);
 
-   unregister_shrinker(>shrinker);
+   unregister_and_free_shrinker(conf->shrinker);
free_thread_groups(conf);
shrink_stripes(conf);
raid5_free_percpu(conf);
@@ -7439,7 +7439,7 @@ static int raid5_alloc_percpu(struct r5conf *conf)
 static unsigned long raid5_cache_scan(struct shrinker *shrink,
  struct shrink_control *sc)
 {
-   struct r5conf *conf = container_of(shrink, struct r5conf, shrinker);
+   struct r5conf *conf = shrink->private_data;
unsigned long ret = SHRINK_STOP;
 
if (mutex_trylock(>cache_size_mutex)) {
@@ -7460,7 +7460,7 @@ static unsigned long raid5_cache_scan(struct shrinker 
*shrink,
 static unsigned long raid5_cache_count(struct shrinker *shrink,
   struct shrink_control *sc)
 {
-   struct r5conf *conf = container_of(shrink, struct r5conf, shrinker);
+   struct r5conf *conf = shrink->private_data;
 
if (conf->max_nr_stripes < conf->min_nr_stripes)
/* unlikely, but not impossible */
@@ -7695,16 +7695,21 @@ static struct r5conf *setup_conf(struct mddev *mddev)
 * it reduces the queue depth and so can hurt throughput.
 * So set it rather large, scaled by number of devices.
 */
-   conf->shrinker.seeks = DEFAULT_SEEKS * conf->raid_disks * 4;
-   conf->shrinker.scan_objects = raid5_cache_scan;
-   conf->shrinker.count_objects = raid5_cache_count;
-   conf->shrinker.batch = 128;
-   conf->shrinker.flags = 0;
-   ret = register_shrinker(>shrinker, "md-raid5:%s", mdname(mddev));
+   conf->shrinker = shrinker_alloc_and_init(raid5_cache_count,
+raid5_cache_scan, 128,
+DEFAULT_SEEKS * 
conf->raid_disks * 4,
+0, conf);
+   if (!conf->shrinker) {
+   pr_warn("md/raid:%s: couldn't allocate shrinker.\n",
+   mdname(mddev));
+   goto abort;
+   }
+
+   ret = register_shrinker(conf->shrinker, "md-raid5:%s", mdname(mddev));
if (ret) {
pr_warn("md/raid:%s: couldn't register shrinker.\n",
mdname(mddev));
-   goto abort;
+   goto abort_shrinker;
}
 
sprintf(pers_name, "raid%d", mddev->new_level);
@@ -7717,7 +7722,8 @@ static struct r5conf *setup_conf(struct mddev *mddev)
}
 
return conf;
-
+abort_shrinker:
+   shrinker_free(conf->shrinker);
  abort:
if (conf)
free_conf(conf);
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index 6a92fafb0748..806f84681599 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -670,7 +670,7 @@ struct r5conf {
wait_queue_head_t   wait_for_stripe;
wait_queue_head_t   wait_for_overlap;
unsigned long   cache_state;
-   struct shrinker shrinker;
+   struct shrinker *shrinker;
int pool_size; /* number of disks in stripeheads in 
pool */
spinlock_t  device_lock;
struct disk_info*disks;
-- 
2.30.2



[Intel-gfx] [PATCH 25/29] mm: vmscan: make memcg slab shrink lockless

2023-06-27 Thread Qi Zheng
Like global slab shrink, this commit also uses refcount+RCU
method to make memcg slab shrink lockless.

We can reproduce the down_read_trylock() hotspot through the
following script:

```

DIR="/root/shrinker/memcg/mnt"

do_create()
{
mkdir -p /sys/fs/cgroup/memory/test
mkdir -p /sys/fs/cgroup/perf_event/test
echo 4G > /sys/fs/cgroup/memory/test/memory.limit_in_bytes
for i in `seq 0 $1`;
do
mkdir -p /sys/fs/cgroup/memory/test/$i;
echo $$ > /sys/fs/cgroup/memory/test/$i/cgroup.procs;
echo $$ > /sys/fs/cgroup/perf_event/test/cgroup.procs;
mkdir -p $DIR/$i;
done
}

do_mount()
{
for i in `seq $1 $2`;
do
mount -t tmpfs $i $DIR/$i;
done
}

do_touch()
{
for i in `seq $1 $2`;
do
echo $$ > /sys/fs/cgroup/memory/test/$i/cgroup.procs;
echo $$ > /sys/fs/cgroup/perf_event/test/cgroup.procs;
dd if=/dev/zero of=$DIR/$i/file$i bs=1M count=1 &
done
}

case "$1" in
  touch)
do_touch $2 $3
;;
  test)
  do_create 4000
do_mount 0 4000
do_touch 0 3000
;;
  *)
exit 1
;;
esac
```

Save the above script, then run test and touch commands.
Then we can use the following perf command to view hotspots:

perf top -U -F 999 [-g]

1) Before applying this patchset:

  35.34%  [kernel] [k] down_read_trylock
  18.44%  [kernel] [k] shrink_slab
  15.98%  [kernel] [k] pv_native_safe_halt
  15.08%  [kernel] [k] up_read
   5.33%  [kernel] [k] idr_find
   2.71%  [kernel] [k] _find_next_bit
   2.21%  [kernel] [k] shrink_node
   1.29%  [kernel] [k] shrink_lruvec
   0.66%  [kernel] [k] do_shrink_slab
   0.33%  [kernel] [k] list_lru_count_one
   0.33%  [kernel] [k] __radix_tree_lookup
   0.25%  [kernel] [k] mem_cgroup_iter

-   82.19%19.49%  [kernel]  [k] shrink_slab
   - 62.00% shrink_slab
36.37% down_read_trylock
15.52% up_read
5.48% idr_find
3.38% _find_next_bit
  + 0.98% do_shrink_slab

2) After applying this patchset:

  46.83%  [kernel]   [k] shrink_slab
  20.52%  [kernel]   [k] pv_native_safe_halt
   8.85%  [kernel]   [k] do_shrink_slab
   7.71%  [kernel]   [k] _find_next_bit
   1.72%  [kernel]   [k] xas_descend
   1.70%  [kernel]   [k] shrink_node
   1.44%  [kernel]   [k] shrink_lruvec
   1.43%  [kernel]   [k] mem_cgroup_iter
   1.28%  [kernel]   [k] xas_load
   0.89%  [kernel]   [k] super_cache_count
   0.84%  [kernel]   [k] xas_start
   0.66%  [kernel]   [k] list_lru_count_one

-   65.50%40.44%  [kernel]  [k] shrink_slab
   - 22.96% shrink_slab
13.11% _find_next_bit
  - 9.91% do_shrink_slab
 - 1.59% super_cache_count
  0.92% list_lru_count_one

We can see that the first perf hotspot becomes shrink_slab,
which is what we expect.

Signed-off-by: Qi Zheng 
---
 mm/vmscan.c | 58 +
 1 file changed, 41 insertions(+), 17 deletions(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 767569698946..357a1f2ad690 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -213,6 +213,12 @@ static struct shrinker_info 
*shrinker_info_protected(struct mem_cgroup *memcg,
 lockdep_is_held(_rwsem));
 }
 
+static struct shrinker_info *shrinker_info_rcu(struct mem_cgroup *memcg,
+  int nid)
+{
+   return rcu_dereference(memcg->nodeinfo[nid]->shrinker_info);
+}
+
 static int expand_one_shrinker_info(struct mem_cgroup *memcg,
int map_size, int defer_size,
int old_map_size, int old_defer_size,
@@ -339,7 +345,7 @@ void set_shrinker_bit(struct mem_cgroup *memcg, int nid, 
int shrinker_id)
struct shrinker_info *info;
 
rcu_read_lock();
-   info = rcu_dereference(memcg->nodeinfo[nid]->shrinker_info);
+   info = shrinker_info_rcu(memcg, nid);
if (!WARN_ON_ONCE(shrinker_id >= info->map_nr_max)) {
/* Pairs with smp mb in shrink_slab() */
smp_mb__before_atomic();
@@ -359,7 +365,6 @@ static int prealloc_memcg_shrinker(struct shrinker 
*shrinker)
return -ENOSYS;
 
down_write(_rwsem);
-   /* This may call shrinker, so it must use down_read_trylock() */
id = idr_alloc(_idr, shrinker, 0, 0, GFP_KERNEL);
if (id < 0)
goto unlock;
@@ -392,18 +397,28 @@ static long xchg_nr_deferred_memcg(int nid, struct 
shrinker *shrinker,
   struct mem_cgroup *memcg)
 {
struct shrinker_info *info;
+   long nr_deferred;
 
-   info = shrinker_info_protected(memcg, nid);
-   return 

Re: [Intel-gfx] [PATCH 05/29] drm/panfrost: dynamically allocate the drm-panfrost shrinker

2023-06-27 Thread Qi Zheng

Hi Steven,

The email you replied to was the failed version (due to the error
below), so I copied your reply and replied to you on this successful
version.

(4.7.1 Error: too many recipients from 49.7.199.173)

On 2023/6/23 18:01, Steven Price wrote:
> On 22/06/2023 09:39, Qi Zheng wrote:
>> From: Qi Zheng 
>>
>> In preparation for implementing lockless slab shrink,
>> we need to dynamically allocate the drm-panfrost shrinker,
>> so that it can be freed asynchronously using kfree_rcu().
>> Then it doesn't need to wait for RCU read-side critical
>> section when releasing the struct panfrost_device.
>>
>> Signed-off-by: Qi Zheng 
>> ---
>>   drivers/gpu/drm/panfrost/panfrost_device.h|  2 +-
>>   .../gpu/drm/panfrost/panfrost_gem_shrinker.c  | 24 ++-
>>   2 files changed, 14 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
b/drivers/gpu/drm/panfrost/panfrost_device.h

>> index b0126b9fbadc..e667e5689353 100644
>> --- a/drivers/gpu/drm/panfrost/panfrost_device.h
>> +++ b/drivers/gpu/drm/panfrost/panfrost_device.h
>> @@ -118,7 +118,7 @@ struct panfrost_device {
>>
>>struct mutex shrinker_lock;
>>struct list_head shrinker_list;
>> -  struct shrinker shrinker;
>> +  struct shrinker *shrinker;
>>
>>struct panfrost_devfreq pfdevfreq;
>>   };
>> diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c 
b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c

>> index bf0170782f25..2a5513eb9e1f 100644
>> --- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
>> +++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
>> @@ -18,8 +18,7 @@
>>   static unsigned long
>>   panfrost_gem_shrinker_count(struct shrinker *shrinker, struct 
shrink_control *sc)

>>   {
>> -  struct panfrost_device *pfdev =
>> -  container_of(shrinker, struct panfrost_device, shrinker);
>> +  struct panfrost_device *pfdev = shrinker->private_data;
>>struct drm_gem_shmem_object *shmem;
>>unsigned long count = 0;
>>
>> @@ -65,8 +64,7 @@ static bool panfrost_gem_purge(struct 
drm_gem_object *obj)

>>   static unsigned long
>>   panfrost_gem_shrinker_scan(struct shrinker *shrinker, struct 
shrink_control *sc)

>>   {
>> -  struct panfrost_device *pfdev =
>> -  container_of(shrinker, struct panfrost_device, shrinker);
>> +  struct panfrost_device *pfdev = shrinker->private_data;
>>struct drm_gem_shmem_object *shmem, *tmp;
>>unsigned long freed = 0;
>>
>> @@ -100,10 +98,15 @@ panfrost_gem_shrinker_scan(struct shrinker 
*shrinker, struct shrink_control *sc)

>>   void panfrost_gem_shrinker_init(struct drm_device *dev)
>>   {
>>struct panfrost_device *pfdev = dev->dev_private;
>> -  pfdev->shrinker.count_objects = panfrost_gem_shrinker_count;
>> -  pfdev->shrinker.scan_objects = panfrost_gem_shrinker_scan;
>> -  pfdev->shrinker.seeks = DEFAULT_SEEKS;
>> -  WARN_ON(register_shrinker(>shrinker, "drm-panfrost"));
>> +
>> +  pfdev->shrinker = shrinker_alloc_and_init(panfrost_gem_shrinker_count,
>> +panfrost_gem_shrinker_scan, 
0,
>> +DEFAULT_SEEKS, 0, pfdev);
>> +  if (pfdev->shrinker &&
>> +  register_shrinker(pfdev->shrinker, "drm-panfrost")) {
>> +  shrinker_free(pfdev->shrinker);
>> +  WARN_ON(1);
>> +  }
>
> So we didn't have good error handling here before, but this is
> significantly worse. Previously if register_shrinker() failed then the
> driver could safely continue without a shrinker - it would waste memory
> but still function.
>
> However we now have two failure conditions:
>   * shrinker_alloc_init() returns NULL. No warning and NULL deferences
> will happen later.
>
>   * register_shrinker() fails, shrinker_free() will free pdev->shrinker
> we get a warning, but followed by a use-after-free later.
>
> I think we need to modify panfrost_gem_shrinker_init() to be able to
> return an error, so a change something like the below (untested) before
> your change.

Indeed. I will fix it in the v2.

Thanks,
Qi

>
> Steve
>
> 8<---
> diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c
> b/drivers/gpu/drm/panfrost/panfrost_drv.c
> index bbada731bbbd..f705bbdea360 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
> @@ -598,10 +598,14 @@ static int panfrost_probe(struct platform_device
> *pdev)
>if (err < 0)
>goto err_out1;
>
> -  panfrost_gem_shrinker_init(ddev);
> +  err = panfrost_gem_shrinker_init(ddev);
> +  if (err)
> +  goto err_out2;
>
>return 0;
>
> +err_out2:
> +  drm_dev_unregister(ddev);
>   err_out1:
>pm_runtime_disable(pfdev->dev);
>panfrost_device_fini(pfdev);
> diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h
> b/drivers/gpu/drm/panfrost/panfrost_gem.h
> index ad2877eeeccd..863d2ec8d4f0 100644
> --- 

Re: [Intel-gfx] [PATCH 00/29] use refcount+RCU method to implement lockless slab shrink

2023-06-27 Thread Qi Zheng

Hi all,

Well, this one was sent successfully.

Since I always get the following error message, I deleted the original
cc people and only kept the mailing lists.

4.7.1 Error: too many recipients from 49.7.199.173

Thanks,
Qi


[Intel-gfx] [PATCH 09/29] bcache: dynamically allocate the md-bcache shrinker

2023-06-27 Thread Qi Zheng
From: Qi Zheng 

In preparation for implementing lockless slab shrink,
we need to dynamically allocate the md-bcache shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct cache_set.

Signed-off-by: Qi Zheng 
---
 drivers/md/bcache/bcache.h |  2 +-
 drivers/md/bcache/btree.c  | 23 ++-
 drivers/md/bcache/sysfs.c  |  2 +-
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index 700dc5588d5f..53c73b372e7a 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -541,7 +541,7 @@ struct cache_set {
struct bio_set  bio_split;
 
/* For the btree cache */
-   struct shrinker shrink;
+   struct shrinker *shrink;
 
/* For the btree cache and anything allocation related */
struct mutexbucket_lock;
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
index 569f48958bde..1131ae91f62a 100644
--- a/drivers/md/bcache/btree.c
+++ b/drivers/md/bcache/btree.c
@@ -667,7 +667,7 @@ static int mca_reap(struct btree *b, unsigned int 
min_order, bool flush)
 static unsigned long bch_mca_scan(struct shrinker *shrink,
  struct shrink_control *sc)
 {
-   struct cache_set *c = container_of(shrink, struct cache_set, shrink);
+   struct cache_set *c = shrink->private_data;
struct btree *b, *t;
unsigned long i, nr = sc->nr_to_scan;
unsigned long freed = 0;
@@ -734,7 +734,7 @@ static unsigned long bch_mca_scan(struct shrinker *shrink,
 static unsigned long bch_mca_count(struct shrinker *shrink,
   struct shrink_control *sc)
 {
-   struct cache_set *c = container_of(shrink, struct cache_set, shrink);
+   struct cache_set *c = shrink->private_data;
 
if (c->shrinker_disabled)
return 0;
@@ -752,8 +752,8 @@ void bch_btree_cache_free(struct cache_set *c)
 
closure_init_stack();
 
-   if (c->shrink.list.next)
-   unregister_shrinker(>shrink);
+   if (c->shrink->list.next)
+   unregister_and_free_shrinker(c->shrink);
 
mutex_lock(>bucket_lock);
 
@@ -828,14 +828,19 @@ int bch_btree_cache_alloc(struct cache_set *c)
c->verify_data = NULL;
 #endif
 
-   c->shrink.count_objects = bch_mca_count;
-   c->shrink.scan_objects = bch_mca_scan;
-   c->shrink.seeks = 4;
-   c->shrink.batch = c->btree_pages * 2;
+   c->shrink = shrinker_alloc_and_init(bch_mca_count, bch_mca_scan,
+   c->btree_pages * 2, 4, 0, c);
+   if (!c->shrink) {
+   pr_warn("bcache: %s: could not allocate shrinker\n",
+   __func__);
+   return -ENOMEM;
+   }
 
-   if (register_shrinker(>shrink, "md-bcache:%pU", c->set_uuid))
+   if (register_shrinker(c->shrink, "md-bcache:%pU", c->set_uuid)) {
pr_warn("bcache: %s: could not register shrinker\n",
__func__);
+   shrinker_free(c->shrink);
+   }
 
return 0;
 }
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
index c6f677059214..771577581f52 100644
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
@@ -866,7 +866,7 @@ STORE(__bch_cache_set)
 
sc.gfp_mask = GFP_KERNEL;
sc.nr_to_scan = strtoul_or_return(buf);
-   c->shrink.scan_objects(>shrink, );
+   c->shrink->scan_objects(c->shrink, );
}
 
sysfs_strtoul_clamp(congested_read_threshold_us,
-- 
2.30.2



[Intel-gfx] [PATCH 16/29] NFSD: dynamically allocate the nfsd-reply shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the nfsd-reply shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct nfsd_net.

Signed-off-by: Qi Zheng 
---
 fs/nfsd/netns.h|  2 +-
 fs/nfsd/nfscache.c | 33 +++--
 2 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index f669444d5336..ab303a8b77d5 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -177,7 +177,7 @@ struct nfsd_net {
/* size of cache when we saw the longest hash chain */
unsigned int longest_chain_cachesize;
 
-   struct shrinker nfsd_reply_cache_shrinker;
+   struct shrinker *nfsd_reply_cache_shrinker;
 
/* tracking server-to-server copy mounts */
spinlock_t  nfsd_ssc_lock;
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index 041faa13b852..ec33de8e418b 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -173,19 +173,23 @@ int nfsd_reply_cache_init(struct nfsd_net *nn)
if (status)
goto out_nomem;
 
-   nn->nfsd_reply_cache_shrinker.scan_objects = nfsd_reply_cache_scan;
-   nn->nfsd_reply_cache_shrinker.count_objects = nfsd_reply_cache_count;
-   nn->nfsd_reply_cache_shrinker.seeks = 1;
-   status = register_shrinker(>nfsd_reply_cache_shrinker,
-  "nfsd-reply:%s", nn->nfsd_name);
-   if (status)
-   goto out_stats_destroy;
-
nn->drc_hashtbl = kvzalloc(array_size(hashsize,
sizeof(*nn->drc_hashtbl)), GFP_KERNEL);
if (!nn->drc_hashtbl)
+   goto out_stats_destroy;
+
+   nn->nfsd_reply_cache_shrinker =
+   shrinker_alloc_and_init(nfsd_reply_cache_count,
+   nfsd_reply_cache_scan,
+   0, 1, 0, nn);
+   if (!nn->nfsd_reply_cache_shrinker)
goto out_shrinker;
 
+   status = register_shrinker(nn->nfsd_reply_cache_shrinker,
+  "nfsd-reply:%s", nn->nfsd_name);
+   if (status)
+   goto out_register;
+
for (i = 0; i < hashsize; i++) {
INIT_LIST_HEAD(>drc_hashtbl[i].lru_head);
spin_lock_init(>drc_hashtbl[i].cache_lock);
@@ -193,8 +197,11 @@ int nfsd_reply_cache_init(struct nfsd_net *nn)
nn->drc_hashsize = hashsize;
 
return 0;
+
+out_register:
+   shrinker_free(nn->nfsd_reply_cache_shrinker);
 out_shrinker:
-   unregister_shrinker(>nfsd_reply_cache_shrinker);
+   kvfree(nn->drc_hashtbl);
 out_stats_destroy:
nfsd_reply_cache_stats_destroy(nn);
 out_nomem:
@@ -207,7 +214,7 @@ void nfsd_reply_cache_shutdown(struct nfsd_net *nn)
struct svc_cacherep *rp;
unsigned int i;
 
-   unregister_shrinker(>nfsd_reply_cache_shrinker);
+   unregister_and_free_shrinker(nn->nfsd_reply_cache_shrinker);
 
for (i = 0; i < nn->drc_hashsize; i++) {
struct list_head *head = >drc_hashtbl[i].lru_head;
@@ -297,8 +304,7 @@ prune_cache_entries(struct nfsd_net *nn)
 static unsigned long
 nfsd_reply_cache_count(struct shrinker *shrink, struct shrink_control *sc)
 {
-   struct nfsd_net *nn = container_of(shrink,
-   struct nfsd_net, nfsd_reply_cache_shrinker);
+   struct nfsd_net *nn = shrink->private_data;
 
return atomic_read(>num_drc_entries);
 }
@@ -306,8 +312,7 @@ nfsd_reply_cache_count(struct shrinker *shrink, struct 
shrink_control *sc)
 static unsigned long
 nfsd_reply_cache_scan(struct shrinker *shrink, struct shrink_control *sc)
 {
-   struct nfsd_net *nn = container_of(shrink,
-   struct nfsd_net, nfsd_reply_cache_shrinker);
+   struct nfsd_net *nn = shrink->private_data;
 
return prune_cache_entries(nn);
 }
-- 
2.30.2



[Intel-gfx] [PATCH 03/29] drm/i915: dynamically allocate the i915_gem_mm shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the i915_gem_mm shrinker,
so that it can be freed asynchronously by using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct drm_i915_private.

Signed-off-by: Qi Zheng 
---
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 27 ++--
 drivers/gpu/drm/i915/i915_drv.h  |  3 ++-
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index 214763942aa2..4dcdace26a08 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -284,8 +284,7 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private 
*i915)
 static unsigned long
 i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
 {
-   struct drm_i915_private *i915 =
-   container_of(shrinker, struct drm_i915_private, mm.shrinker);
+   struct drm_i915_private *i915 = shrinker->private_data;
unsigned long num_objects;
unsigned long count;
 
@@ -302,8 +301,8 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct 
shrink_control *sc)
if (num_objects) {
unsigned long avg = 2 * count / num_objects;
 
-   i915->mm.shrinker.batch =
-   max((i915->mm.shrinker.batch + avg) >> 1,
+   i915->mm.shrinker->batch =
+   max((i915->mm.shrinker->batch + avg) >> 1,
128ul /* default SHRINK_BATCH */);
}
 
@@ -313,8 +312,7 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct 
shrink_control *sc)
 static unsigned long
 i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
 {
-   struct drm_i915_private *i915 =
-   container_of(shrinker, struct drm_i915_private, mm.shrinker);
+   struct drm_i915_private *i915 = shrinker->private_data;
unsigned long freed;
 
sc->nr_scanned = 0;
@@ -422,12 +420,15 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, 
unsigned long event, void *ptr
 
 void i915_gem_driver_register__shrinker(struct drm_i915_private *i915)
 {
-   i915->mm.shrinker.scan_objects = i915_gem_shrinker_scan;
-   i915->mm.shrinker.count_objects = i915_gem_shrinker_count;
-   i915->mm.shrinker.seeks = DEFAULT_SEEKS;
-   i915->mm.shrinker.batch = 4096;
-   drm_WARN_ON(>drm, register_shrinker(>mm.shrinker,
- "drm-i915_gem"));
+   i915->mm.shrinker = shrinker_alloc_and_init(i915_gem_shrinker_count,
+   i915_gem_shrinker_scan,
+   4096, DEFAULT_SEEKS, 0,
+   i915);
+   if (i915->mm.shrinker &&
+   register_shrinker(i915->mm.shrinker, "drm-i915_gem")) {
+   shrinker_free(i915->mm.shrinker);
+   drm_WARN_ON(>drm, 1);
+   }
 
i915->mm.oom_notifier.notifier_call = i915_gem_shrinker_oom;
drm_WARN_ON(>drm, register_oom_notifier(>mm.oom_notifier));
@@ -443,7 +444,7 @@ void i915_gem_driver_unregister__shrinker(struct 
drm_i915_private *i915)
unregister_vmap_purge_notifier(>mm.vmap_notifier));
drm_WARN_ON(>drm,
unregister_oom_notifier(>mm.oom_notifier));
-   unregister_shrinker(>mm.shrinker);
+   unregister_and_free_shrinker(i915->mm.shrinker);
 }
 
 void i915_gem_shrinker_taints_mutex(struct drm_i915_private *i915,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b4cf6f0f636d..06b04428596d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -163,7 +163,8 @@ struct i915_gem_mm {
 
struct notifier_block oom_notifier;
struct notifier_block vmap_notifier;
-   struct shrinker shrinker;
+
+   struct shrinker *shrinker;
 
 #ifdef CONFIG_MMU_NOTIFIER
/**
-- 
2.30.2



[Intel-gfx] [PATCH 26/29] mm: shrinker: make count and scan in shrinker debugfs lockless

2023-06-27 Thread Qi Zheng
Like global and memcg slab shrink, also make count and scan
operations in memory shrinker debugfs lockless.

The debugfs_remove_recursive() will wait for debugfs_file_put()
to return, so there is no need to call rcu_read_lock() before
calling shrinker_try_get().

Signed-off-by: Qi Zheng 
---
 mm/shrinker_debug.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/mm/shrinker_debug.c b/mm/shrinker_debug.c
index 3ab53fad8876..c18fa9b6b7f0 100644
--- a/mm/shrinker_debug.c
+++ b/mm/shrinker_debug.c
@@ -55,8 +55,8 @@ static int shrinker_debugfs_count_show(struct seq_file *m, 
void *v)
if (!count_per_node)
return -ENOMEM;
 
-   ret = down_read_killable(_rwsem);
-   if (ret) {
+   ret = shrinker_try_get(shrinker);
+   if (!ret) {
kfree(count_per_node);
return ret;
}
@@ -92,7 +92,7 @@ static int shrinker_debugfs_count_show(struct seq_file *m, 
void *v)
} while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL);
 
rcu_read_unlock();
-   up_read(_rwsem);
+   shrinker_put(shrinker);
 
kfree(count_per_node);
return ret;
@@ -146,8 +146,8 @@ static ssize_t shrinker_debugfs_scan_write(struct file 
*file,
return -EINVAL;
}
 
-   ret = down_read_killable(_rwsem);
-   if (ret) {
+   ret = shrinker_try_get(shrinker);
+   if (!ret) {
mem_cgroup_put(memcg);
return ret;
}
@@ -159,7 +159,7 @@ static ssize_t shrinker_debugfs_scan_write(struct file 
*file,
 
shrinker->scan_objects(shrinker, );
 
-   up_read(_rwsem);
+   shrinker_put(shrinker);
mem_cgroup_put(memcg);
 
return size;
-- 
2.30.2



[Intel-gfx] [PATCH 12/29] mbcache: dynamically allocate the mbcache shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the mbcache shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct mb_cache.

Signed-off-by: Qi Zheng 
---
 fs/mbcache.c | 39 +--
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/fs/mbcache.c b/fs/mbcache.c
index 2a4b8b549e93..fec393e55a66 100644
--- a/fs/mbcache.c
+++ b/fs/mbcache.c
@@ -37,7 +37,7 @@ struct mb_cache {
struct list_headc_list;
/* Number of entries in cache */
unsigned long   c_entry_count;
-   struct shrinker c_shrink;
+   struct shrinker *c_shrink;
/* Work for shrinking when the cache has too many entries */
struct work_struct  c_shrink_work;
 };
@@ -293,8 +293,7 @@ EXPORT_SYMBOL(mb_cache_entry_touch);
 static unsigned long mb_cache_count(struct shrinker *shrink,
struct shrink_control *sc)
 {
-   struct mb_cache *cache = container_of(shrink, struct mb_cache,
- c_shrink);
+   struct mb_cache *cache = shrink->private_data;
 
return cache->c_entry_count;
 }
@@ -333,8 +332,8 @@ static unsigned long mb_cache_shrink(struct mb_cache *cache,
 static unsigned long mb_cache_scan(struct shrinker *shrink,
   struct shrink_control *sc)
 {
-   struct mb_cache *cache = container_of(shrink, struct mb_cache,
- c_shrink);
+   struct mb_cache *cache = shrink->private_data;
+
return mb_cache_shrink(cache, sc->nr_to_scan);
 }
 
@@ -370,26 +369,30 @@ struct mb_cache *mb_cache_create(int bucket_bits)
cache->c_hash = kmalloc_array(bucket_count,
  sizeof(struct hlist_bl_head),
  GFP_KERNEL);
-   if (!cache->c_hash) {
-   kfree(cache);
-   goto err_out;
-   }
+   if (!cache->c_hash)
+   goto err_c_hash;
+
for (i = 0; i < bucket_count; i++)
INIT_HLIST_BL_HEAD(>c_hash[i]);
 
-   cache->c_shrink.count_objects = mb_cache_count;
-   cache->c_shrink.scan_objects = mb_cache_scan;
-   cache->c_shrink.seeks = DEFAULT_SEEKS;
-   if (register_shrinker(>c_shrink, "mbcache-shrinker")) {
-   kfree(cache->c_hash);
-   kfree(cache);
-   goto err_out;
-   }
+   cache->c_shrink = shrinker_alloc_and_init(mb_cache_count, mb_cache_scan,
+ 0, DEFAULT_SEEKS, 0, cache);
+   if (!cache->c_shrink)
+   goto err_shrinker;
+
+   if (register_shrinker(cache->c_shrink, "mbcache-shrinker"))
+   goto err_register;
 
INIT_WORK(>c_shrink_work, mb_cache_shrink_worker);
 
return cache;
 
+err_register:
+   shrinker_free(cache->c_shrink);
+err_shrinker:
+   kfree(cache->c_hash);
+err_c_hash:
+   kfree(cache);
 err_out:
return NULL;
 }
@@ -406,7 +409,7 @@ void mb_cache_destroy(struct mb_cache *cache)
 {
struct mb_cache_entry *entry, *next;
 
-   unregister_shrinker(>c_shrink);
+   unregister_and_free_shrinker(cache->c_shrink);
 
/*
 * We don't bother with any locking. Cache must not be used at this
-- 
2.30.2



Re: [Intel-gfx] [PATCH 2/3] linux/bits.h: Add fixed-width GENMASK and BIT macros

2023-06-27 Thread Yury Norov
Hi Lucas, all!

(Thanks, Andy, for pointing to this thread.)

On Mon, May 08, 2023 at 10:14:02PM -0700, Lucas De Marchi wrote:
> Add GENMASK_U32(), GENMASK_U16() and GENMASK_U8()  macros to create
> masks for fixed-width types and also the corresponding BIT_U32(),
> BIT_U16() and BIT_U8().

Can you split BIT() and GENMASK() material to separate patches?

> All of those depend on a new "U" suffix added to the integer constant.
> Due to naming clashes it's better to call the macro U32. Since C doesn't
> have a proper suffix for short and char types, the U16 and U18 variants
> just use U32 with one additional check in the BIT_* macros to make
> sure the compiler gives an error when the those types overflow.

I feel like I don't understand the sentence...

> The BIT_U16() and BIT_U8() need the help of GENMASK_INPUT_CHECK(),
> as otherwise they would allow an invalid bit to be passed. Hence
> implement them in include/linux/bits.h rather than together with
> the other BIT* variants.

I don't think it's a good way to go because BIT() belongs to a more basic
level than GENMASK(). Not mentioning possible header dependency issues.
If you need to test against tighter numeric region, I'd suggest to
do the same trick as  GENMASK_INPUT_CHECK() does, but in uapi/linux/const.h
directly. Something like:
#define _U8(x)  (CONST_GT(U8_MAX, x) + _AC(x, U))

> The following test file is is used to test this:
> 
>   $ cat mask.c
>   #include 
>   #include 
> 
>   static const u32 a = GENMASK_U32(31, 0);
>   static const u16 b = GENMASK_U16(15, 0);
>   static const u8 c = GENMASK_U8(7, 0);
>   static const u32 x = BIT_U32(31);
>   static const u16 y = BIT_U16(15);
>   static const u8 z = BIT_U8(7);
> 
>   #if FAIL
>   static const u32 a2 = GENMASK_U32(32, 0);
>   static const u16 b2 = GENMASK_U16(16, 0);
>   static const u8 c2 = GENMASK_U8(8, 0);
>   static const u32 x2 = BIT_U32(32);
>   static const u16 y2 = BIT_U16(16);
>   static const u8 z2 = BIT_U8(8);
>   #endif
> 
> Signed-off-by: Lucas De Marchi 
> ---
>  include/linux/bits.h   | 22 ++
>  include/uapi/linux/const.h |  2 ++
>  include/vdso/const.h   |  1 +
>  3 files changed, 25 insertions(+)
> 
> diff --git a/include/linux/bits.h b/include/linux/bits.h
> index 7c0cf5031abe..ff4786c99b8c 100644
> --- a/include/linux/bits.h
> +++ b/include/linux/bits.h
> @@ -42,4 +42,26 @@
>  #define GENMASK_ULL(h, l) \
>   (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
>  
> +#define __GENMASK_U32(h, l) \
> + (((~U32(0)) - (U32(1) << (l)) + 1) & \
> +  (~U32(0) >> (32 - 1 - (h
> +#define GENMASK_U32(h, l) \
> + (GENMASK_INPUT_CHECK(h, l) + __GENMASK_U32(h, l))
> +
> +#define __GENMASK_U16(h, l) \
> + ((U32(0x) - (U32(1) << (l)) + 1) & \
> +  (U32(0x) >> (16 - 1 - (h
> +#define GENMASK_U16(h, l) \
> + (GENMASK_INPUT_CHECK(h, l) + __GENMASK_U16(h, l))
> +
> +#define __GENMASK_U8(h, l) \
> + (((U32(0xff)) - (U32(1) << (l)) + 1) & \
> +  (U32(0xff) >> (8 - 1 - (h
> +#define GENMASK_U8(h, l) \
> + (GENMASK_INPUT_CHECK(h, l) + __GENMASK_U8(h, l))

[...]

I see nothing wrong with fixed-wight versions of GENMASK if it helps
people to write safer code. Can you please in commit message mention
the exact patch(es) that added a bug related to GENMASK() misuse? It
would be easier to advocate the purpose of new API with that in mind.

Regarding implementation - we should avoid copy-pasting in cases
like this. Below is the patch that I boot-tested for x86_64 and
compile-tested for arm64.

It looks less opencoded, and maybe Andy will be less skeptical about
this approach because of less maintenance burden. Please take it if
you like for v2.

Thanks,
Yury

>From 39c5b35075df67e7d88644470ca78a3486367c02 Mon Sep 17 00:00:00 2001
From: Yury Norov 
Date: Wed, 21 Jun 2023 15:27:29 -0700
Subject: [PATCH] bits: introduce fixed-type genmasks

Generalize __GENMASK() to support different types, and implement
fixed-types versions of GENMASK() based on it.

Signed-off-by: Yury Norov 
---
 include/linux/bitops.h |  1 -
 include/linux/bits.h   | 22 --
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 2ba557e067fe..1db50c69cfdb 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -15,7 +15,6 @@
 #  define aligned_byte_mask(n) (~0xffUL << (BITS_PER_LONG - 8 - 8*(n)))
 #endif
 
-#define BITS_PER_TYPE(type)(sizeof(type) * BITS_PER_BYTE)
 #define BITS_TO_LONGS(nr)  __KERNEL_DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
 #define BITS_TO_U64(nr)__KERNEL_DIV_ROUND_UP(nr, 
BITS_PER_TYPE(u64))
 #define BITS_TO_U32(nr)__KERNEL_DIV_ROUND_UP(nr, 
BITS_PER_TYPE(u32))
diff --git a/include/linux/bits.h b/include/linux/bits.h
index 7c0cf5031abe..cb94128171b2 100644
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -6,6 

[Intel-gfx] [PATCH 01/29] mm: shrinker: add shrinker::private_data field

2023-06-27 Thread Qi Zheng
To prepare for the dynamic allocation of shrinker instances
embedded in other structures, add a private_data field to
struct shrinker, so that we can use shrinker::private_data
to record and get the original embedded structure.

Signed-off-by: Qi Zheng 
---
 include/linux/shrinker.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index 224293b2dd06..43e6fcabbf51 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -70,6 +70,8 @@ struct shrinker {
int seeks;  /* seeks to recreate an obj */
unsigned flags;
 
+   void *private_data;
+
/* These are for internal use */
struct list_head list;
 #ifdef CONFIG_MEMCG
-- 
2.30.2



[Intel-gfx] [PATCH 29/29] mm: shrinker: move shrinker-related code into a separate file

2023-06-27 Thread Qi Zheng
The mm/vmscan.c file is too large, so separate the shrinker-related
code from it into a separate file. No functional changes.

Signed-off-by: Qi Zheng 
---
 include/linux/shrinker.h |   3 +
 mm/Makefile  |   4 +-
 mm/shrinker.c| 750 +++
 mm/vmscan.c  | 746 --
 4 files changed, 755 insertions(+), 748 deletions(-)
 create mode 100644 mm/shrinker.c

diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index b0c6c2df9db8..b837b4c0864a 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -104,6 +104,9 @@ struct shrinker {
  */
 #define SHRINKER_NONSLAB   (1 << 3)
 
+unsigned long shrink_slab(gfp_t gfp_mask, int nid, struct mem_cgroup *memcg,
+ int priority);
+
 extern int __printf(2, 3) prealloc_shrinker(struct shrinker *shrinker,
const char *fmt, ...);
 extern void register_shrinker_prepared(struct shrinker *shrinker);
diff --git a/mm/Makefile b/mm/Makefile
index 678530a07326..891899186608 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -48,8 +48,8 @@ endif
 
 obj-y  := filemap.o mempool.o oom_kill.o fadvise.o \
   maccess.o page-writeback.o folio-compat.o \
-  readahead.o swap.o truncate.o vmscan.o shmem.o \
-  util.o mmzone.o vmstat.o backing-dev.o \
+  readahead.o swap.o truncate.o vmscan.o shrinker.o \
+  shmem.o util.o mmzone.o vmstat.o backing-dev.o \
   mm_init.o percpu.o slab_common.o \
   compaction.o show_mem.o\
   interval_tree.o list_lru.o workingset.o \
diff --git a/mm/shrinker.c b/mm/shrinker.c
new file mode 100644
index ..f88966f3d6be
--- /dev/null
+++ b/mm/shrinker.c
@@ -0,0 +1,750 @@
+// SPDX-License-Identifier: GPL-2.0
+#include 
+#include 
+#include 
+#include 
+#include 
+
+LIST_HEAD(shrinker_list);
+DEFINE_MUTEX(shrinker_mutex);
+
+#ifdef CONFIG_MEMCG
+static int shrinker_nr_max;
+
+/* The shrinker_info is expanded in a batch of BITS_PER_LONG */
+static inline int shrinker_map_size(int nr_items)
+{
+   return (DIV_ROUND_UP(nr_items, BITS_PER_LONG) * sizeof(unsigned long));
+}
+
+static inline int shrinker_defer_size(int nr_items)
+{
+   return (round_up(nr_items, BITS_PER_LONG) * sizeof(atomic_long_t));
+}
+
+static struct shrinker_info *shrinker_info_protected(struct mem_cgroup *memcg,
+int nid)
+{
+   return rcu_dereference_protected(memcg->nodeinfo[nid]->shrinker_info,
+lockdep_is_held(_mutex));
+}
+
+static struct shrinker_info *shrinker_info_rcu(struct mem_cgroup *memcg,
+  int nid)
+{
+   return rcu_dereference(memcg->nodeinfo[nid]->shrinker_info);
+}
+
+static int expand_one_shrinker_info(struct mem_cgroup *memcg,
+   int map_size, int defer_size,
+   int old_map_size, int old_defer_size,
+   int new_nr_max)
+{
+   struct shrinker_info *new, *old;
+   struct mem_cgroup_per_node *pn;
+   int nid;
+   int size = map_size + defer_size;
+
+   for_each_node(nid) {
+   pn = memcg->nodeinfo[nid];
+   old = shrinker_info_protected(memcg, nid);
+   /* Not yet online memcg */
+   if (!old)
+   return 0;
+
+   /* Already expanded this shrinker_info */
+   if (new_nr_max <= old->map_nr_max)
+   continue;
+
+   new = kvmalloc_node(sizeof(*new) + size, GFP_KERNEL, nid);
+   if (!new)
+   return -ENOMEM;
+
+   new->nr_deferred = (atomic_long_t *)(new + 1);
+   new->map = (void *)new->nr_deferred + defer_size;
+   new->map_nr_max = new_nr_max;
+
+   /* map: set all old bits, clear all new bits */
+   memset(new->map, (int)0xff, old_map_size);
+   memset((void *)new->map + old_map_size, 0, map_size - 
old_map_size);
+   /* nr_deferred: copy old values, clear all new values */
+   memcpy(new->nr_deferred, old->nr_deferred, old_defer_size);
+   memset((void *)new->nr_deferred + old_defer_size, 0,
+  defer_size - old_defer_size);
+
+   rcu_assign_pointer(pn->shrinker_info, new);
+   kvfree_rcu(old, rcu);
+   }
+
+   return 0;
+}
+
+void free_shrinker_info(struct mem_cgroup *memcg)
+{
+   struct mem_cgroup_per_node *pn;
+   struct shrinker_info *info;
+   int nid;
+
+   for_each_node(nid) {
+   pn = memcg->nodeinfo[nid];
+   info = 

[Intel-gfx] [PATCH 27/29] mm: vmscan: hold write lock to reparent shrinker nr_deferred

2023-06-27 Thread Qi Zheng
For now, reparent_shrinker_deferred() is the only holder
of read lock of shrinker_rwsem. And it already holds the
global cgroup_mutex, so it will not be called in parallel.

Therefore, in order to convert shrinker_rwsem to shrinker_mutex
later, here we change to hold the write lock of shrinker_rwsem
to reparent.

Signed-off-by: Qi Zheng 
---
 mm/vmscan.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 357a1f2ad690..0711b63e68d9 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -433,7 +433,7 @@ void reparent_shrinker_deferred(struct mem_cgroup *memcg)
parent = root_mem_cgroup;
 
/* Prevent from concurrent shrinker_info expand */
-   down_read(_rwsem);
+   down_write(_rwsem);
for_each_node(nid) {
child_info = shrinker_info_protected(memcg, nid);
parent_info = shrinker_info_protected(parent, nid);
@@ -442,7 +442,7 @@ void reparent_shrinker_deferred(struct mem_cgroup *memcg)
atomic_long_add(nr, _info->nr_deferred[i]);
}
}
-   up_read(_rwsem);
+   up_write(_rwsem);
 }
 
 static bool cgroup_reclaim(struct scan_control *sc)
-- 
2.30.2



[Intel-gfx] [PATCH 18/29] xfs: dynamically allocate the xfs-inodegc shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the xfs-inodegc shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct xfs_mount.

Signed-off-by: Qi Zheng 
---
 fs/xfs/xfs_icache.c | 27 ---
 fs/xfs/xfs_mount.c  |  4 ++--
 fs/xfs/xfs_mount.h  |  2 +-
 3 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 453890942d9f..1ef0c9fa57de 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -2225,8 +2225,7 @@ xfs_inodegc_shrinker_count(
struct shrinker *shrink,
struct shrink_control   *sc)
 {
-   struct xfs_mount*mp = container_of(shrink, struct xfs_mount,
-  m_inodegc_shrinker);
+   struct xfs_mount*mp = shrink->private_data;
struct xfs_inodegc  *gc;
int cpu;
 
@@ -2247,8 +2246,7 @@ xfs_inodegc_shrinker_scan(
struct shrinker *shrink,
struct shrink_control   *sc)
 {
-   struct xfs_mount*mp = container_of(shrink, struct xfs_mount,
-  m_inodegc_shrinker);
+   struct xfs_mount*mp = shrink->private_data;
struct xfs_inodegc  *gc;
int cpu;
boolno_items = true;
@@ -2284,13 +2282,20 @@ int
 xfs_inodegc_register_shrinker(
struct xfs_mount*mp)
 {
-   struct shrinker *shrink = >m_inodegc_shrinker;
+   int ret;
 
-   shrink->count_objects = xfs_inodegc_shrinker_count;
-   shrink->scan_objects = xfs_inodegc_shrinker_scan;
-   shrink->seeks = 0;
-   shrink->flags = SHRINKER_NONSLAB;
-   shrink->batch = XFS_INODEGC_SHRINKER_BATCH;
+   mp->m_inodegc_shrinker =
+   shrinker_alloc_and_init(xfs_inodegc_shrinker_count,
+   xfs_inodegc_shrinker_scan,
+   XFS_INODEGC_SHRINKER_BATCH,
+   0, SHRINKER_NONSLAB, mp);
+   if (!mp->m_inodegc_shrinker)
+   return -ENOMEM;
+
+   ret = register_shrinker(mp->m_inodegc_shrinker, "xfs-inodegc:%s",
+   mp->m_super->s_id);
+   if (ret)
+   shrinker_free(mp->m_inodegc_shrinker);
 
-   return register_shrinker(shrink, "xfs-inodegc:%s", mp->m_super->s_id);
+   return ret;
 }
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index fb87ffb48f7f..67286859ad34 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1018,7 +1018,7 @@ xfs_mountfs(
  out_log_dealloc:
xfs_log_mount_cancel(mp);
  out_inodegc_shrinker:
-   unregister_shrinker(>m_inodegc_shrinker);
+   unregister_and_free_shrinker(mp->m_inodegc_shrinker);
  out_fail_wait:
if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp)
xfs_buftarg_drain(mp->m_logdev_targp);
@@ -1100,7 +1100,7 @@ xfs_unmountfs(
 #if defined(DEBUG)
xfs_errortag_clearall(mp);
 #endif
-   unregister_shrinker(>m_inodegc_shrinker);
+   unregister_and_free_shrinker(mp->m_inodegc_shrinker);
xfs_free_perag(mp);
 
xfs_errortag_del(mp);
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index e2866e7fa60c..562c294ca08e 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -217,7 +217,7 @@ typedef struct xfs_mount {
atomic_tm_agirotor; /* last ag dir inode alloced */
 
/* Memory shrinker to throttle and reprioritize inodegc */
-   struct shrinker m_inodegc_shrinker;
+   struct shrinker *m_inodegc_shrinker;
/*
 * Workqueue item so that we can coalesce multiple inode flush attempts
 * into a single flush.
-- 
2.30.2



[Intel-gfx] [PATCH 02/29] mm: vmscan: introduce some helpers for dynamically allocating shrinker

2023-06-27 Thread Qi Zheng
Introduce some helpers for dynamically allocating shrinker instance,
and their uses are as follows:

1. shrinker_alloc_and_init()

Used to allocate and initialize a shrinker instance, the priv_data
parameter is used to pass the pointer of the previously embedded
structure of the shrinker instance.

2. shrinker_free()

Used to free the shrinker instance when the registration of shrinker
fails.

3. unregister_and_free_shrinker()

Used to unregister and free the shrinker instance, and the kfree()
will be changed to kfree_rcu() later.

Signed-off-by: Qi Zheng 
---
 include/linux/shrinker.h | 12 
 mm/vmscan.c  | 35 +++
 2 files changed, 47 insertions(+)

diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index 43e6fcabbf51..8e9ba6fa3fcc 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -107,6 +107,18 @@ extern void unregister_shrinker(struct shrinker *shrinker);
 extern void free_prealloced_shrinker(struct shrinker *shrinker);
 extern void synchronize_shrinkers(void);
 
+typedef unsigned long (*count_objects_cb)(struct shrinker *s,
+ struct shrink_control *sc);
+typedef unsigned long (*scan_objects_cb)(struct shrinker *s,
+struct shrink_control *sc);
+
+struct shrinker *shrinker_alloc_and_init(count_objects_cb count,
+scan_objects_cb scan, long batch,
+int seeks, unsigned flags,
+void *priv_data);
+void shrinker_free(struct shrinker *shrinker);
+void unregister_and_free_shrinker(struct shrinker *shrinker);
+
 #ifdef CONFIG_SHRINKER_DEBUG
 extern int shrinker_debugfs_add(struct shrinker *shrinker);
 extern struct dentry *shrinker_debugfs_detach(struct shrinker *shrinker,
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 45d17c7cc555..64ff598fbad9 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -809,6 +809,41 @@ void unregister_shrinker(struct shrinker *shrinker)
 }
 EXPORT_SYMBOL(unregister_shrinker);
 
+struct shrinker *shrinker_alloc_and_init(count_objects_cb count,
+scan_objects_cb scan, long batch,
+int seeks, unsigned flags,
+void *priv_data)
+{
+   struct shrinker *shrinker;
+
+   shrinker = kzalloc(sizeof(struct shrinker), GFP_KERNEL);
+   if (!shrinker)
+   return NULL;
+
+   shrinker->count_objects = count;
+   shrinker->scan_objects = scan;
+   shrinker->batch = batch;
+   shrinker->seeks = seeks;
+   shrinker->flags = flags;
+   shrinker->private_data = priv_data;
+
+   return shrinker;
+}
+EXPORT_SYMBOL(shrinker_alloc_and_init);
+
+void shrinker_free(struct shrinker *shrinker)
+{
+   kfree(shrinker);
+}
+EXPORT_SYMBOL(shrinker_free);
+
+void unregister_and_free_shrinker(struct shrinker *shrinker)
+{
+   unregister_shrinker(shrinker);
+   kfree(shrinker);
+}
+EXPORT_SYMBOL(unregister_and_free_shrinker);
+
 /**
  * synchronize_shrinkers - Wait for all running shrinkers to complete.
  *
-- 
2.30.2



[Intel-gfx] [PATCH 01/29] mm: shrinker: add shrinker::private_data field

2023-06-27 Thread Qi Zheng
From: Qi Zheng 

To prepare for the dynamic allocation of shrinker instances
embedded in other structures, add a private_data field to
struct shrinker, so that we can use shrinker::private_data
to record and get the original embedded structure.

Signed-off-by: Qi Zheng 
---
 include/linux/shrinker.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index 224293b2dd06..43e6fcabbf51 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -70,6 +70,8 @@ struct shrinker {
int seeks;  /* seeks to recreate an obj */
unsigned flags;
 
+   void *private_data;
+
/* These are for internal use */
struct list_head list;
 #ifdef CONFIG_MEMCG
-- 
2.30.2



[Intel-gfx] [PATCH 06/29] dm: dynamically allocate the dm-bufio shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the dm-bufio shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct dm_bufio_client.

Signed-off-by: Qi Zheng 
---
 drivers/md/dm-bufio.c | 23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index eea977662e81..9472470d456d 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -963,7 +963,7 @@ struct dm_bufio_client {
 
sector_t start;
 
-   struct shrinker shrinker;
+   struct shrinker *shrinker;
struct work_struct shrink_work;
atomic_long_t need_shrink;
 
@@ -2385,7 +2385,7 @@ static unsigned long dm_bufio_shrink_scan(struct shrinker 
*shrink, struct shrink
 {
struct dm_bufio_client *c;
 
-   c = container_of(shrink, struct dm_bufio_client, shrinker);
+   c = shrink->private_data;
atomic_long_add(sc->nr_to_scan, >need_shrink);
queue_work(dm_bufio_wq, >shrink_work);
 
@@ -2394,7 +2394,7 @@ static unsigned long dm_bufio_shrink_scan(struct shrinker 
*shrink, struct shrink
 
 static unsigned long dm_bufio_shrink_count(struct shrinker *shrink, struct 
shrink_control *sc)
 {
-   struct dm_bufio_client *c = container_of(shrink, struct 
dm_bufio_client, shrinker);
+   struct dm_bufio_client *c = shrink->private_data;
unsigned long count = cache_total(>cache);
unsigned long retain_target = get_retain_buffers(c);
unsigned long queued_for_cleanup = atomic_long_read(>need_shrink);
@@ -2507,14 +2507,15 @@ struct dm_bufio_client *dm_bufio_client_create(struct 
block_device *bdev, unsign
INIT_WORK(>shrink_work, shrink_work);
atomic_long_set(>need_shrink, 0);
 
-   c->shrinker.count_objects = dm_bufio_shrink_count;
-   c->shrinker.scan_objects = dm_bufio_shrink_scan;
-   c->shrinker.seeks = 1;
-   c->shrinker.batch = 0;
-   r = register_shrinker(>shrinker, "dm-bufio:(%u:%u)",
+   c->shrinker = shrinker_alloc_and_init(dm_bufio_shrink_count,
+ dm_bufio_shrink_scan, 0, 1, 0, c);
+   if (!c->shrinker)
+   goto bad;
+
+   r = register_shrinker(c->shrinker, "dm-bufio:(%u:%u)",
  MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev));
if (r)
-   goto bad;
+   goto bad_shrinker;
 
mutex_lock(_bufio_clients_lock);
dm_bufio_client_count++;
@@ -2524,6 +2525,8 @@ struct dm_bufio_client *dm_bufio_client_create(struct 
block_device *bdev, unsign
 
return c;
 
+bad_shrinker:
+   shrinker_free(c->shrinker);
 bad:
while (!list_empty(>reserved_buffers)) {
struct dm_buffer *b = list_to_buffer(c->reserved_buffers.next);
@@ -2554,7 +2557,7 @@ void dm_bufio_client_destroy(struct dm_bufio_client *c)
 
drop_buffers(c);
 
-   unregister_shrinker(>shrinker);
+   unregister_and_free_shrinker(c->shrinker);
flush_work(>shrink_work);
 
mutex_lock(_bufio_clients_lock);
-- 
2.30.2



[Intel-gfx] [PATCH 09/29] bcache: dynamically allocate the md-bcache shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the md-bcache shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct cache_set.

Signed-off-by: Qi Zheng 
---
 drivers/md/bcache/bcache.h |  2 +-
 drivers/md/bcache/btree.c  | 23 ++-
 drivers/md/bcache/sysfs.c  |  2 +-
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index 700dc5588d5f..53c73b372e7a 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -541,7 +541,7 @@ struct cache_set {
struct bio_set  bio_split;
 
/* For the btree cache */
-   struct shrinker shrink;
+   struct shrinker *shrink;
 
/* For the btree cache and anything allocation related */
struct mutexbucket_lock;
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
index 569f48958bde..1131ae91f62a 100644
--- a/drivers/md/bcache/btree.c
+++ b/drivers/md/bcache/btree.c
@@ -667,7 +667,7 @@ static int mca_reap(struct btree *b, unsigned int 
min_order, bool flush)
 static unsigned long bch_mca_scan(struct shrinker *shrink,
  struct shrink_control *sc)
 {
-   struct cache_set *c = container_of(shrink, struct cache_set, shrink);
+   struct cache_set *c = shrink->private_data;
struct btree *b, *t;
unsigned long i, nr = sc->nr_to_scan;
unsigned long freed = 0;
@@ -734,7 +734,7 @@ static unsigned long bch_mca_scan(struct shrinker *shrink,
 static unsigned long bch_mca_count(struct shrinker *shrink,
   struct shrink_control *sc)
 {
-   struct cache_set *c = container_of(shrink, struct cache_set, shrink);
+   struct cache_set *c = shrink->private_data;
 
if (c->shrinker_disabled)
return 0;
@@ -752,8 +752,8 @@ void bch_btree_cache_free(struct cache_set *c)
 
closure_init_stack();
 
-   if (c->shrink.list.next)
-   unregister_shrinker(>shrink);
+   if (c->shrink->list.next)
+   unregister_and_free_shrinker(c->shrink);
 
mutex_lock(>bucket_lock);
 
@@ -828,14 +828,19 @@ int bch_btree_cache_alloc(struct cache_set *c)
c->verify_data = NULL;
 #endif
 
-   c->shrink.count_objects = bch_mca_count;
-   c->shrink.scan_objects = bch_mca_scan;
-   c->shrink.seeks = 4;
-   c->shrink.batch = c->btree_pages * 2;
+   c->shrink = shrinker_alloc_and_init(bch_mca_count, bch_mca_scan,
+   c->btree_pages * 2, 4, 0, c);
+   if (!c->shrink) {
+   pr_warn("bcache: %s: could not allocate shrinker\n",
+   __func__);
+   return -ENOMEM;
+   }
 
-   if (register_shrinker(>shrink, "md-bcache:%pU", c->set_uuid))
+   if (register_shrinker(c->shrink, "md-bcache:%pU", c->set_uuid)) {
pr_warn("bcache: %s: could not register shrinker\n",
__func__);
+   shrinker_free(c->shrink);
+   }
 
return 0;
 }
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
index c6f677059214..771577581f52 100644
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
@@ -866,7 +866,7 @@ STORE(__bch_cache_set)
 
sc.gfp_mask = GFP_KERNEL;
sc.nr_to_scan = strtoul_or_return(buf);
-   c->shrink.scan_objects(>shrink, );
+   c->shrink->scan_objects(c->shrink, );
}
 
sysfs_strtoul_clamp(congested_read_threshold_us,
-- 
2.30.2



[Intel-gfx] [PATCH 22/29] drm/ttm: introduce pool_shrink_rwsem

2023-06-27 Thread Qi Zheng
Currently, the synchronize_shrinkers() is only used by TTM
pool. It only requires that no shrinkers run in parallel.

After we use RCU+refcount method to implement the lockless
slab shrink, we can not use shrinker_rwsem or synchronize_rcu()
to guarantee that all shrinker invocations have seen an update
before freeing memory.

So we introduce a new pool_shrink_rwsem to implement a private
synchronize_shrinkers(), so as to achieve the same purpose.

Signed-off-by: Qi Zheng 
---
 drivers/gpu/drm/ttm/ttm_pool.c | 15 +++
 include/linux/shrinker.h   |  1 -
 mm/vmscan.c| 15 ---
 3 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index cddb9151d20f..713b1c0a70e1 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -74,6 +74,7 @@ static struct ttm_pool_type global_dma32_uncached[MAX_ORDER + 
1];
 static spinlock_t shrinker_lock;
 static struct list_head shrinker_list;
 static struct shrinker mm_shrinker;
+static DECLARE_RWSEM(pool_shrink_rwsem);
 
 /* Allocate pages of size 1 << order with the given gfp_flags */
 static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
@@ -317,6 +318,7 @@ static unsigned int ttm_pool_shrink(void)
unsigned int num_pages;
struct page *p;
 
+   down_read(_shrink_rwsem);
spin_lock(_lock);
pt = list_first_entry(_list, typeof(*pt), shrinker_list);
list_move_tail(>shrinker_list, _list);
@@ -329,6 +331,7 @@ static unsigned int ttm_pool_shrink(void)
} else {
num_pages = 0;
}
+   up_read(_shrink_rwsem);
 
return num_pages;
 }
@@ -572,6 +575,18 @@ void ttm_pool_init(struct ttm_pool *pool, struct device 
*dev,
 }
 EXPORT_SYMBOL(ttm_pool_init);
 
+/**
+ * synchronize_shrinkers - Wait for all running shrinkers to complete.
+ *
+ * This is useful to guarantee that all shrinker invocations have seen an
+ * update, before freeing memory, similar to rcu.
+ */
+static void synchronize_shrinkers(void)
+{
+   down_write(_shrink_rwsem);
+   up_write(_shrink_rwsem);
+}
+
 /**
  * ttm_pool_fini - Cleanup a pool
  *
diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index 8e9ba6fa3fcc..4094e4c44e80 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -105,7 +105,6 @@ extern int __printf(2, 3) register_shrinker(struct shrinker 
*shrinker,
const char *fmt, ...);
 extern void unregister_shrinker(struct shrinker *shrinker);
 extern void free_prealloced_shrinker(struct shrinker *shrinker);
-extern void synchronize_shrinkers(void);
 
 typedef unsigned long (*count_objects_cb)(struct shrinker *s,
  struct shrink_control *sc);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 64ff598fbad9..3a8d50ad6ff6 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -844,21 +844,6 @@ void unregister_and_free_shrinker(struct shrinker 
*shrinker)
 }
 EXPORT_SYMBOL(unregister_and_free_shrinker);
 
-/**
- * synchronize_shrinkers - Wait for all running shrinkers to complete.
- *
- * This is equivalent to calling unregister_shrink() and register_shrinker(),
- * but atomically and with less overhead. This is useful to guarantee that all
- * shrinker invocations have seen an update, before freeing memory, similar to
- * rcu.
- */
-void synchronize_shrinkers(void)
-{
-   down_write(_rwsem);
-   up_write(_rwsem);
-}
-EXPORT_SYMBOL(synchronize_shrinkers);
-
 #define SHRINK_BATCH 128
 
 static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
-- 
2.30.2



[Intel-gfx] [PATCH 09/11] sysctl: Remove the end element in sysctl table arrays

2023-06-27 Thread Joel Granados
Remove the empty end element from all the arrays that are passed to the
register sysctl calls. In some files this means reducing the explicit
array size by one. Also make sure that we are using the size in
ctl_table_header instead of evaluating the .procname element.

Signed-off-by: Joel Granados 
---
 arch/arm/kernel/isa.c |  4 +-
 arch/arm64/kernel/armv8_deprecated.c  |  8 ++--
 arch/arm64/kernel/fpsimd.c|  6 +--
 arch/arm64/kernel/process.c   |  3 +-
 arch/ia64/kernel/crash.c  |  3 +-
 arch/powerpc/kernel/idle.c|  3 +-
 arch/powerpc/platforms/pseries/mobility.c |  3 +-
 arch/s390/appldata/appldata_base.c|  7 ++--
 arch/s390/kernel/debug.c  |  3 +-
 arch/s390/kernel/topology.c   |  3 +-
 arch/s390/mm/cmm.c|  3 +-
 arch/s390/mm/pgalloc.c|  3 +-
 arch/x86/entry/vdso/vdso32-setup.c|  3 +-
 arch/x86/kernel/cpu/intel.c   |  3 +-
 arch/x86/kernel/itmt.c|  3 +-
 crypto/fips.c |  3 +-
 drivers/base/firmware_loader/fallback_table.c |  3 +-
 drivers/cdrom/cdrom.c |  3 +-
 drivers/char/hpet.c   | 13 +++---
 drivers/char/ipmi/ipmi_poweroff.c |  3 +-
 drivers/char/random.c |  3 +-
 drivers/gpu/drm/i915/i915_perf.c  | 33 +++
 drivers/hv/hv_common.c|  3 +-
 drivers/infiniband/core/iwcm.c|  3 +-
 drivers/infiniband/core/ucma.c|  3 +-
 drivers/macintosh/mac_hid.c   |  3 +-
 drivers/md/md.c   |  3 +-
 drivers/misc/sgi-xp/xpc_main.c|  6 +--
 drivers/net/vrf.c |  3 +-
 drivers/parport/procfs.c  | 42 ---
 drivers/perf/arm_pmuv3.c  |  3 +-
 drivers/scsi/scsi_sysctl.c|  3 +-
 drivers/scsi/sg.c |  3 +-
 drivers/tty/tty_io.c  |  3 +-
 drivers/xen/balloon.c |  3 +-
 fs/aio.c  |  3 +-
 fs/cachefiles/error_inject.c  |  3 +-
 fs/coda/sysctl.c  |  3 +-
 fs/coredump.c |  3 +-
 fs/dcache.c   |  3 +-
 fs/devpts/inode.c |  3 +-
 fs/eventpoll.c|  3 +-
 fs/exec.c |  3 +-
 fs/file_table.c   |  3 +-
 fs/inode.c|  3 +-
 fs/lockd/svc.c|  3 +-
 fs/locks.c|  3 +-
 fs/namei.c|  3 +-
 fs/namespace.c|  3 +-
 fs/nfs/nfs4sysctl.c   |  3 +-
 fs/nfs/sysctl.c   |  3 +-
 fs/notify/dnotify/dnotify.c   |  3 +-
 fs/notify/fanotify/fanotify_user.c|  3 +-
 fs/notify/inotify/inotify_user.c  |  3 +-
 fs/ntfs/sysctl.c  |  3 +-
 fs/ocfs2/stackglue.c  |  3 +-
 fs/pipe.c |  3 +-
 fs/proc/proc_sysctl.c |  8 ++--
 fs/quota/dquot.c  |  3 +-
 fs/sysctls.c  |  3 +-
 fs/userfaultfd.c  |  3 +-
 fs/verity/signature.c |  3 +-
 fs/xfs/xfs_sysctl.c   |  4 +-
 init/do_mounts_initrd.c   |  3 +-
 ipc/ipc_sysctl.c  |  3 +-
 ipc/mq_sysctl.c   |  3 +-
 kernel/acct.c |  3 +-
 kernel/bpf/syscall.c  |  3 +-
 kernel/delayacct.c|  3 +-
 kernel/exit.c |  3 +-
 kernel/hung_task.c|  3 +-
 kernel/kexec_core.c   |  3 +-
 kernel/kprobes.c  |  3 +-
 kernel/latencytop.c   |  3 +-
 kernel/locking/lockdep.c  |  3 +-
 kernel/panic.c|  3 +-
 kernel/pid_namespace.c|  3 +-
 kernel/pid_sysctl.h   |  3 +-
 kernel/printk/sysctl.c|  3 +-
 kernel/reboot.c   |  3 +-
 kernel/sched/autogroup.c  |  3 +-
 kernel/sched/core.c   |  3 +-
 kernel/sched/deadline.c   |  3 +-
 kernel/sched/fair.c   |  3 +-
 kernel/sched/rt.c

[Intel-gfx] [PATCH 13/29] ext4: dynamically allocate the ext4-es shrinker

2023-06-27 Thread Qi Zheng
In preparation for implementing lockless slab shrink,
we need to dynamically allocate the ext4-es shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct ext4_sb_info.

Signed-off-by: Qi Zheng 
---
 fs/ext4/ext4.h   |  2 +-
 fs/ext4/extents_status.c | 21 -
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 0a2d55faa095..1bd150d454f5 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1651,7 +1651,7 @@ struct ext4_sb_info {
__u32 s_csum_seed;
 
/* Reclaim extents from extent status tree */
-   struct shrinker s_es_shrinker;
+   struct shrinker *s_es_shrinker;
struct list_head s_es_list; /* List of inodes with reclaimable 
extents */
long s_es_nr_inode;
struct ext4_es_stats s_es_stats;
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
index 9b5b8951afb4..fea82339f4b4 100644
--- a/fs/ext4/extents_status.c
+++ b/fs/ext4/extents_status.c
@@ -1596,7 +1596,7 @@ static unsigned long ext4_es_count(struct shrinker 
*shrink,
unsigned long nr;
struct ext4_sb_info *sbi;
 
-   sbi = container_of(shrink, struct ext4_sb_info, s_es_shrinker);
+   sbi = shrink->private_data;
nr = percpu_counter_read_positive(>s_es_stats.es_stats_shk_cnt);
trace_ext4_es_shrink_count(sbi->s_sb, sc->nr_to_scan, nr);
return nr;
@@ -1605,8 +1605,7 @@ static unsigned long ext4_es_count(struct shrinker 
*shrink,
 static unsigned long ext4_es_scan(struct shrinker *shrink,
  struct shrink_control *sc)
 {
-   struct ext4_sb_info *sbi = container_of(shrink,
-   struct ext4_sb_info, s_es_shrinker);
+   struct ext4_sb_info *sbi = shrink->private_data;
int nr_to_scan = sc->nr_to_scan;
int ret, nr_shrunk;
 
@@ -1690,15 +1689,19 @@ int ext4_es_register_shrinker(struct ext4_sb_info *sbi)
if (err)
goto err3;
 
-   sbi->s_es_shrinker.scan_objects = ext4_es_scan;
-   sbi->s_es_shrinker.count_objects = ext4_es_count;
-   sbi->s_es_shrinker.seeks = DEFAULT_SEEKS;
-   err = register_shrinker(>s_es_shrinker, "ext4-es:%s",
+   sbi->s_es_shrinker = shrinker_alloc_and_init(ext4_es_count, 
ext4_es_scan,
+0, DEFAULT_SEEKS, 0, sbi);
+   if (!sbi->s_es_shrinker)
+   goto err4;
+
+   err = register_shrinker(sbi->s_es_shrinker, "ext4-es:%s",
sbi->s_sb->s_id);
if (err)
-   goto err4;
+   goto err5;
 
return 0;
+err5:
+   shrinker_free(sbi->s_es_shrinker);
 err4:
percpu_counter_destroy(>s_es_stats.es_stats_shk_cnt);
 err3:
@@ -1716,7 +1719,7 @@ void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi)
percpu_counter_destroy(>s_es_stats.es_stats_cache_misses);
percpu_counter_destroy(>s_es_stats.es_stats_all_cnt);
percpu_counter_destroy(>s_es_stats.es_stats_shk_cnt);
-   unregister_shrinker(>s_es_shrinker);
+   unregister_and_free_shrinker(sbi->s_es_shrinker);
 }
 
 /*
-- 
2.30.2



  1   2   >