[PATCH 6/6] drm/amd/pm: enable memory temp reading for SMU 13.0.0

2022-05-16 Thread Evan Quan
With the latest vbios, the memory temp reading is working.

Signed-off-by: Evan Quan 
Reviewed-by: Hawking Zhang 
Change-Id: I3b4679f03e5ff7cf8e0b68c095d210e608149fcb
---
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index 7bb2923eb819..7432b3e76d3d 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -275,9 +275,7 @@ smu_v13_0_0_get_allowed_feature_mask(struct smu_context 
*smu,
*(uint64_t *)feature_mask |= 
FEATURE_MASK(FEATURE_VDDIO_MEM_SCALING_BIT);
}
 
-#if 0
*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_MEM_TEMP_READ_BIT);
-#endif
 
if (adev->pm.pp_feature & PP_SCLK_DEEP_SLEEP_MASK)
*(uint64_t *)feature_mask |= 
FEATURE_MASK(FEATURE_DS_GFXCLK_BIT);
-- 
2.29.0



[PATCH 5/6] drm/amd/pm: enable more dpm features for SMU 13.0.0

2022-05-16 Thread Evan Quan
Enable OOB Monitor and SOC CG which are ready since 78.38.0.

Signed-off-by: Evan Quan 
Reviewed-by: Hawking Zhang 
Acked-by: Alex Deucher 
Change-Id: I0d7334106917ac83fff2b673ec7e9eb096089afe
---
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index 7bfceca246ae..7bb2923eb819 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -299,6 +299,9 @@ smu_v13_0_0_get_allowed_feature_mask(struct smu_context 
*smu,
*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT);
*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_FW_DSTATE_BIT);
 
+   *(uint64_t *)feature_mask |= 
FEATURE_MASK(FEATURE_OUT_OF_BAND_MONITOR_BIT);
+   *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_SOC_CG_BIT);
+
return 0;
 }
 
-- 
2.29.0



[PATCH 3/6] drm/amd/pm: update SMU 13.0.0 driver_if header

2022-05-16 Thread Evan Quan
To align with 78.37.0 and later PMFWs.

Signed-off-by: Evan Quan 
Reviewed-by: Hawking Zhang 
Change-Id: I17c3a6b466c921cb5ffe5025a94023fae478c80e
---
 .../inc/pmfw_if/smu13_driver_if_v13_0_0.h | 22 +--
 drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h  |  2 +-
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
index ecc6411dfc8d..c1f76236da26 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
@@ -671,8 +671,8 @@ typedef struct {
   uint16_t   reserved[2];
 
   //Frequency changes
-  uint16_t   GfxclkFmin;   // MHz
-  uint16_t   GfxclkFmax;   // MHz
+  int16_tGfxclkFmin;   // MHz
+  int16_tGfxclkFmax;   // MHz
   uint16_t   UclkFmin; // MHz
   uint16_t   UclkFmax; // MHz
 
@@ -683,15 +683,14 @@ typedef struct {
   //Fan control
   uint8_tFanLinearPwmPoints[NUM_OD_FAN_MAX_POINTS];
   uint8_tFanLinearTempPoints[NUM_OD_FAN_MAX_POINTS];
-  uint16_t   FanMaximumRpm;
   uint16_t   FanMinimumPwm;
-  uint16_t   FanAcousticLimitRpm;
+  uint16_t   AcousticTargetRpmThreshold;
+  uint16_t   AcousticLimitRpmThreshold;
   uint16_t   FanTargetTemperature; // Degree Celcius
   uint8_tFanZeroRpmEnable;
   uint8_tFanZeroRpmStopTemp;
   uint8_tFanMode;
-  uint8_tPadding[1];
-
+  uint8_tMaxOpTemp;
 
   uint32_t   Spare[13];
   uint32_t   MmHubPadding[8]; // SMU internal use. Adding here 
instead of external as a workaround
@@ -719,15 +718,14 @@ typedef struct {
 
   uint8_tFanLinearPwmPoints;
   uint8_tFanLinearTempPoints;
-  uint16_t   FanMaximumRpm;
   uint16_t   FanMinimumPwm;
-  uint16_t   FanAcousticLimitRpm;
+  uint16_t   AcousticTargetRpmThreshold;
+  uint16_t   AcousticLimitRpmThreshold;
   uint16_t   FanTargetTemperature; // Degree Celcius
   uint8_tFanZeroRpmEnable;
   uint8_tFanZeroRpmStopTemp;
   uint8_tFanMode;
-  uint8_tPadding[1];
-
+  uint8_tMaxOpTemp;
 
   uint32_t   Spare[13];
 
@@ -997,7 +995,8 @@ typedef struct {
   uint16_t SocketPowerLimitAcTau[PPT_THROTTLER_COUNT]; // Time constant of LPF 
in ms
   uint16_t SocketPowerLimitDcTau[PPT_THROTTLER_COUNT]; // Time constant of LPF 
in ms
 
-  uint32_t   SpareVmin[12];
+  QuadraticInt_t Vmin_droop;
+  uint32_t   SpareVmin[9];
 
 
   //SECTION: DPM Configuration 1
@@ -1286,7 +1285,6 @@ typedef struct {
   uint32_tPostVoltageSetBacoDelay; // in microseconds. Amount of time FW 
will wait after power good is established or PSI0 command is issued
   uint32_tBacoEntryDelay; // in milliseconds. Amount of time FW will wait 
to trigger BACO entry after receiving entry notification from OS
 
-
   // SECTION: Board Reserved
   uint32_t BoardSpare[64];
 
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h 
b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
index 2b44d41a5157..afa1991e26f9 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
@@ -30,7 +30,7 @@
 #define SMU13_DRIVER_IF_VERSION_ALDE 0x08
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x04
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
-#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0 0x27
+#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0 0x28
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x28
 
 #define SMU13_MODE1_RESET_WAIT_TIME_IN_MS 500  //500ms
-- 
2.29.0



[PATCH 2/6] drm/amd/pm: skip dpm disablement on suspend for SMU 13.0.0

2022-05-16 Thread Evan Quan
Since PMFW will handle this properly. Driver involvement is
unnecessary.

Signed-off-by: Evan Quan 
Reviewed-by: Hawking Zhang 
Change-Id: I19be26eed090d57040553f5cdff9534072f08106
---
 drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c 
b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index 6016b325b6b5..a601024ba4de 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -1436,6 +1436,7 @@ static int smu_disable_dpms(struct smu_context *smu)
case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 5):
case IP_VERSION(11, 0, 9):
+   case IP_VERSION(13, 0, 0):
return 0;
default:
break;
-- 
2.29.0



[PATCH 4/6] drm/amd/pm: correct the softpptable ids used for SMU 13.0.0

2022-05-16 Thread Evan Quan
To better match with the pptable_id settings from VBIOS.

Signed-off-by: Evan Quan 
Reviewed-by: Hawking Zhang 
Acked-by: Alex Deucher 
Change-Id: I3379443067a5df3a2fb04ff1bc48e8c8f28e1c66
---
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c| 47 ++-
 1 file changed, 35 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
index ae6321af9d88..7be4f6875a7b 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
@@ -218,13 +218,25 @@ int smu_v13_0_init_pptable_microcode(struct smu_context 
*smu)
pptable_id == 3688)
pptable_id = 36881;
/*
-* Temporary solution for SMU V13.0.0:
-*   - use 1 signed pptable when SCPM enabled
-* TODO: drop this when the pptable carried in vbios
-* is ready.
+* Temporary solution for SMU V13.0.0 with SCPM enabled:
+*   - use 36831 signed pptable when pp_table_id is 3683
+*   - use 36641 signed pptable when pp_table_id is 3664 or 0
+* TODO: drop these when the pptable carried in vbios is ready.
 */
-   if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 0))
-   pptable_id = 1;
+   if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 0)) {
+   switch (pptable_id) {
+   case 0:
+   case 3664:
+   pptable_id = 36641;
+   break;
+   case 3683:
+   pptable_id = 36831;
+   break;
+   default:
+   dev_err(adev->dev, "Unsupported pptable id 
%d\n", pptable_id);
+   return -EINVAL;
+   }
+   }
}
 
/* "pptable_id == 0" means vbios carries the pptable. */
@@ -448,13 +460,24 @@ int smu_v13_0_setup_pptable(struct smu_context *smu)
pptable_id = smu->smu_table.boot_values.pp_table_id;
 
/*
-* Temporary solution for SMU V13.0.0:
-*   - use  unsigned pptable when SCPM disabled
-* TODO: drop this when the pptable carried in vbios
-* is ready.
+* Temporary solution for SMU V13.0.0 with SCPM disabled:
+*   - use 3664 or 3683 on request
+*   - use 3664 when pptable_id is 0
+* TODO: drop these when the pptable carried in vbios is ready.
 */
-   if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 0))
-   pptable_id = ;
+   if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 0)) {
+   switch (pptable_id) {
+   case 0:
+   pptable_id = 3664;
+   break;
+   case 3664:
+   case 3683:
+   break;
+   default:
+   dev_err(adev->dev, "Unsupported pptable id 
%d\n", pptable_id);
+   return -EINVAL;
+   }
+   }
}
 
/* force using vbios pptable in sriov mode */
-- 
2.29.0



[PATCH 1/6] drm/amd/pm: enable more dpm features for SMU 13.0.0

2022-05-16 Thread Evan Quan
Enable MP0CLK DPM and FW Dstate since they are already supported
by latest 78.36.0 PMFW.

Signed-off-by: Evan Quan 
Reviewed-by: Hawking Zhang 
Change-Id: I75b6129dab509a51ccaf92bbc0b094eae41ea20f
---
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index 197a0e2ff063..7bfceca246ae 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -296,6 +296,9 @@ smu_v13_0_0_get_allowed_feature_mask(struct smu_context 
*smu,
 
*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_BACO_BIT);
 
+   *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT);
+   *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_FW_DSTATE_BIT);
+
return 0;
 }
 
-- 
2.29.0



RE: [PATCH] drm/amdgpu/discovery: validate VCN and SDMA instances

2022-05-16 Thread Chen, Guchun
Reviewed-by: Guchun Chen 

Regards,
Guchun

-Original Message-
From: amd-gfx  On Behalf Of Alex Deucher
Sent: Tuesday, May 17, 2022 2:17 AM
To: amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander 
Subject: [PATCH] drm/amdgpu/discovery: validate VCN and SDMA instances

Validate the VCN and SDMA instances against the driver structure sizes to make 
sure we don't get into a situation where the firmware reports more instances 
than the driver supports.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 1f4e07a32445..2c4f1adb5343 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -1137,13 +1137,24 @@ static int amdgpu_discovery_reg_base_init(struct 
amdgpu_device *adev)
adev->vcn.vcn_config[adev->vcn.num_vcn_inst] =
ip->revision & 0xc0;
ip->revision &= ~0xc0;
-   adev->vcn.num_vcn_inst++;
+   if (adev->vcn.num_vcn_inst < 
AMDGPU_MAX_VCN_INSTANCES)
+   adev->vcn.num_vcn_inst++;
+   else
+   dev_err(adev->dev, "Too many VCN 
instances: %d vs %d\n",
+   adev->vcn.num_vcn_inst + 1,
+   AMDGPU_MAX_VCN_INSTANCES);
}
if (le16_to_cpu(ip->hw_id) == SDMA0_HWID ||
le16_to_cpu(ip->hw_id) == SDMA1_HWID ||
le16_to_cpu(ip->hw_id) == SDMA2_HWID ||
-   le16_to_cpu(ip->hw_id) == SDMA3_HWID)
-   adev->sdma.num_instances++;
+   le16_to_cpu(ip->hw_id) == SDMA3_HWID) {
+   if (adev->sdma.num_instances < 
AMDGPU_MAX_SDMA_INSTANCES)
+   adev->sdma.num_instances++;
+   else
+   dev_err(adev->dev, "Too many SDMA 
instances: %d vs %d\n",
+   adev->sdma.num_instances + 1,
+   AMDGPU_MAX_SDMA_INSTANCES);
+   }
 
if (le16_to_cpu(ip->hw_id) == UMC_HWID)
adev->gmc.num_umc++;
--
2.35.3



[linux-next:master] BUILD REGRESSION 3f7bdc402fb06f897ff1f492a2d42e1f7c2efedb

2022-05-16 Thread kernel test robot
tree/branch: 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
branch HEAD: 3f7bdc402fb06f897ff1f492a2d42e1f7c2efedb  Add linux-next specific 
files for 20220516

Error/Warning reports:

https://lore.kernel.org/linux-mm/202204291924.vtgzmeri-...@intel.com
https://lore.kernel.org/linux-mm/202205041248.wgcwpcev-...@intel.com
https://lore.kernel.org/linux-mm/202205122113.ulkzd3sz-...@intel.com
https://lore.kernel.org/linux-mm/202205150051.3rzuooag-...@intel.com
https://lore.kernel.org/linux-mm/202205150117.sd6hzbvm-...@intel.com
https://lore.kernel.org/llvm/202205170327.tvbbish2-...@intel.com
https://lore.kernel.org/llvm/202205170352.5yjubp5h-...@intel.com

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

: fatal error: ./include/generated/utsrelease.h: No such file or 
directory
ERROR: modpost: "__udivdi3" [drivers/mtd/parsers/scpart.ko] undefined!
arch/riscv/include/asm/tlbflush.h:23:2: error: expected assembly-time absolute 
expression
arch/x86/kvm/pmu.h:20:32: warning: 'vmx_icl_pebs_cpu' defined but not used 
[-Wunused-const-variable=]
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c:1364:5: warning: no previous 
prototype for 'amdgpu_discovery_get_mall_info' [-Wmissing-prototypes]
drivers/gpu/drm/amd/amdgpu/soc21.c:171:6: warning: no previous prototype for 
'soc21_grbm_select' [-Wmissing-prototypes]
drivers/gpu/drm/solomon/ssd130x-spi.c:154:35: warning: 'ssd130x_spi_table' 
defined but not used [-Wunused-const-variable=]
drivers/video/fbdev/omap/hwa742.c:492:5: warning: no previous prototype for 
'hwa742_update_window_async' [-Wmissing-prototypes]
fs/buffer.c:2254:5: warning: stack frame size (2152) exceeds limit (1024) in 
'block_read_full_folio' [-Wframe-larger-than]
fs/ntfs/aops.c:378:12: warning: stack frame size (2216) exceeds limit (1024) in 
'ntfs_read_folio' [-Wframe-larger-than]
kernel/trace/fgraph.c:37:12: warning: no previous prototype for 
'ftrace_enable_ftrace_graph_caller' [-Wmissing-prototypes]
kernel/trace/fgraph.c:46:12: warning: no previous prototype for 
'ftrace_disable_ftrace_graph_caller' [-Wmissing-prototypes]

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

Error: Section .bss not empty in prom_init.c
Makefile:686: arch/h8300/Makefile: No such file or directory
arch/Kconfig:10: can't open file "arch/h8300/Kconfig"
arch/arm64/kvm/pmu.c:9:46: warning: tentative definition of variable with 
internal linkage has incomplete non-array type 'typeof(struct kvm_pmu_events)' 
(aka 'struct kvm_pmu_events') [-Wtentative-definition-incomplete-type]
drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_link_dp.c:5102:14: warning: 
variable 'allow_lttpr_non_transparent_mode' set but not used 
[-Wunused-but-set-variable]
drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_link_dp.c:5147:6: warning: no 
previous prototype for 'dp_parse_lttpr_mode' [-Wmissing-prototypes]
drivers/gpu/drm/bridge/adv7511/adv7511.h:229:17: warning: 
'ADV7511_REG_CEC_RX_FRAME_HDR' defined but not used [-Wunused-const-variable=]
drivers/gpu/drm/bridge/adv7511/adv7511.h:235:17: warning: 
'ADV7511_REG_CEC_RX_FRAME_LEN' defined but not used [-Wunused-const-variable=]
drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:46 sysfs_gt_attribute_w_func() 
error: uninitialized symbol 'ret'.
drivers/opp/core.c:1499:13: warning: Uninitialized variable: iter->rate 
[uninitvar]
drivers/opp/core.c:1533:14: warning: Uninitialized variable: temp->removed 
[uninitvar]
drivers/opp/core.c:2682:16: warning: Uninitialized variable: tmp_opp->rate 
[uninitvar]
drivers/opp/core.c:365:12: warning: Uninitialized variable: opp->available 
[uninitvar]
drivers/opp/core.c:442:17: warning: Uninitialized variable: temp_opp->available 
[uninitvar]
drivers/opp/core.c:491:17: warning: Uninitialized variable: temp_opp->level 
[uninitvar]
drivers/opp/core.c:60:26: warning: Uninitialized variables: opp_table.node, 
opp_table.lazy, opp_table.head, opp_table.dev_list, opp_table.opp_list, 
opp_table.kref, opp_table.lock, opp_table.np, opp_table.clock_latency_ns_max, 
opp_table.voltage_tolerance_v1, opp_table.parsed_static_opps, 
opp_table.shared_opp, opp_table.current_rate, opp_table.current_opp, 
opp_table.suspend_opp, opp_table.genpd_virt_dev_lock, 
opp_table.genpd_virt_devs, opp_table.required_opp_tables, 
opp_table.required_opp_count, opp_table.supported_hw, 
opp_table.supported_hw_count, opp_table.prop_name, opp_table.clk, 
opp_table.regulators, opp_table.regulator_count, opp_table.paths, 
opp_table.path_count, opp_table.enabled, opp_table.genpd_performance_state, 
opp_table.is_genpd, opp_table.set_opp, opp_table.sod_supplies, 
opp_table.set_opp_data [uninitvar]
kernel/bpf/verifier.c:5354 process_kptr_func() warn: passing zero to 'PTR_ERR'
make[1]: *** No rule to make target 'arch/h8300/Makefile'.
mm/shmem.c:1910 shmem_getpage_gfp() warn: should '(((1) << 12) / 512) << 
folio_order(folio)' be a 64 bit type?
{standard input}:1991: Error: unknown pseud

Re: [PATCH 2/3] drm/amdgpu: add AMDGPU_VM_NOALLOC

2022-05-16 Thread Marek Olšák
Dmesg doesn't contain anything. There is no backtrace because it's not a
crash. The VA map ioctl just fails with the new flag. It looks like the
flag is considered invalid.

Marek

On Mon., May 16, 2022, 12:13 Christian König, <
ckoenig.leichtzumer...@gmail.com> wrote:

> I don't have access to any gfx10 hardware.
>
> Can you give me a dmesg and/or backtrace, etc..?
>
> I can't push this unless it's working properly.
>
> Christian.
>
> Am 16.05.22 um 14:56 schrieb Marek Olšák:
>
> Reproduction steps:
> - use mesa/main on gfx10.3 (not sure what other GPUs do)
> - run: radeonsi_mall_noalloc=true glxgears
>
> Marek
>
> On Mon, May 16, 2022 at 7:53 AM Christian König <
> ckoenig.leichtzumer...@gmail.com> wrote:
>
>> Crap, do you have a link to the failure?
>>
>> Am 16.05.22 um 13:10 schrieb Marek Olšák:
>>
>> I forgot to say: The NOALLOC flag causes an allocation failure, so there
>> is a kernel bug somewhere.
>>
>> Marek
>>
>> On Mon, May 16, 2022 at 7:06 AM Marek Olšák  wrote:
>>
>>> FYI, I think it's time to merge this because the Mesa commits are going
>>> to be merged in ~30 minutes if Gitlab CI is green, and that includes
>>> updated amdgpu_drm.h.
>>>
>>> Marek
>>>
>>> On Wed, May 11, 2022 at 2:55 PM Marek Olšák  wrote:
>>>
 Ok sounds good.

 Marek

 On Wed., May 11, 2022, 03:43 Christian König, <
 ckoenig.leichtzumer...@gmail.com> wrote:

> It really *is* a NOALLOC feature. In other words there is no latency
> improvement on reads because the cache is always checked, even with the
> noalloc flag set.
>
> The only thing it affects is that misses not enter the cache and so
> don't cause any additional pressure on evicting cache lines.
>
> You might want to double check with the hardware guys, but I'm
> something like 95% sure that it works this way.
>
> Christian.
>
> Am 11.05.22 um 09:22 schrieb Marek Olšák:
>
> Bypass means that the contents of the cache are ignored, which
> decreases latency at the cost of no coherency between bypassed and normal
> memory requests. NOA (noalloc) means that the cache is checked and can 
> give
> you cache hits, but misses are not cached and the overall latency is
> higher. I don't know what the hw does, but I hope it was misnamed and it
> really means bypass because there is no point in doing cache lookups on
> every memory request if the driver wants to disable caching to *decrease*
> latency in the situations when the cache isn't helping.
>
> Marek
>
> On Wed, May 11, 2022 at 2:15 AM Lazar, Lijo 
> wrote:
>
>>
>>
>> On 5/11/2022 11:36 AM, Christian König wrote:
>> > Mhm, it doesn't really bypass MALL. It just doesn't allocate any
>> MALL
>> > entries on write.
>> >
>> > How about AMDGPU_VM_PAGE_NO_MALL ?
>>
>> One more - AMDGPU_VM_PAGE_LLC_* [ LLC = last level cache, * = some
>> sort
>> of attribute which decides LLC behaviour]
>>
>> Thanks,
>> Lijo
>>
>> >
>> > Christian.
>> >
>> > Am 10.05.22 um 23:21 schrieb Marek Olšák:
>> >> A better name would be:
>> >> AMDGPU_VM_PAGE_BYPASS_MALL
>> >>
>> >> Marek
>> >>
>> >> On Fri, May 6, 2022 at 7:23 AM Christian König
>> >>  wrote:
>> >>
>> >> Add the AMDGPU_VM_NOALLOC flag to let userspace control MALL
>> >> allocation.
>> >>
>> >> Only compile tested!
>> >>
>> >> Signed-off-by: Christian König 
>> >> ---
>> >>  drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 ++
>> >>  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 3 +++
>> >>  drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c  | 3 +++
>> >>  include/uapi/drm/amdgpu_drm.h   | 2 ++
>> >>  4 files changed, 10 insertions(+)
>> >>
>> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>> >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>> >> index bf97d8f07f57..d8129626581f 100644
>> >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>> >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>> >> @@ -650,6 +650,8 @@ uint64_t amdgpu_gem_va_map_flags(struct
>> >> amdgpu_device *adev, uint32_t flags)
>> >> pte_flag |= AMDGPU_PTE_WRITEABLE;
>> >> if (flags & AMDGPU_VM_PAGE_PRT)
>> >> pte_flag |= AMDGPU_PTE_PRT;
>> >> +   if (flags & AMDGPU_VM_PAGE_NOALLOC)
>> >> +   pte_flag |= AMDGPU_PTE_NOALLOC;
>> >>
>> >> if (adev->gmc.gmc_funcs->map_mtype)
>> >> pte_flag |= amdgpu_gmc_map_mtype(adev,
>> >> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
>> >> b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
>> >> index b8c79789e1e4..9077dfccaf3c 100644
>> >> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
>> >> +++ 

[PATCH v2 11/13] mm: handling Non-LRU pages returned by vm_normal_pages

2022-05-16 Thread Alex Sierra
With DEVICE_COHERENT, we'll soon have vm_normal_pages() return
device-managed anonymous pages that are not LRU pages. Although they
behave like normal pages for purposes of mapping in CPU page, and for
COW. They do not support LRU lists, NUMA migration or THP.

We also introduced a FOLL_LRU flag that adds the same behaviour to
follow_page and related APIs, to allow callers to specify that they
expect to put pages on an LRU list.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
---
 fs/proc/task_mmu.c | 2 +-
 include/linux/mm.h | 3 ++-
 mm/gup.c   | 2 ++
 mm/huge_memory.c   | 2 +-
 mm/khugepaged.c| 9 ++---
 mm/ksm.c   | 6 +++---
 mm/madvise.c   | 4 ++--
 mm/memory.c| 9 -
 mm/mempolicy.c | 2 +-
 mm/migrate.c   | 4 ++--
 mm/mlock.c | 2 +-
 mm/mprotect.c  | 2 +-
 12 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index f46060eb91b5..5d620733f173 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -1785,7 +1785,7 @@ static struct page *can_gather_numa_stats(pte_t pte, 
struct vm_area_struct *vma,
return NULL;
 
page = vm_normal_page(vma, addr, pte);
-   if (!page)
+   if (!page || is_zone_device_page(page))
return NULL;
 
if (PageReserved(page))
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 9f44254af8ce..d7f253a0c41e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -601,7 +601,7 @@ struct vm_operations_struct {
 #endif
/*
 * Called by vm_normal_page() for special PTEs to find the
-* page for @addr.  This is useful if the default behavior
+* page for @addr. This is useful if the default behavior
 * (using pte_page()) would not find the correct page.
 */
struct page *(*find_special_page)(struct vm_area_struct *vma,
@@ -2929,6 +2929,7 @@ struct page *follow_page(struct vm_area_struct *vma, 
unsigned long address,
 #define FOLL_NUMA  0x200   /* force NUMA hinting page fault */
 #define FOLL_MIGRATION 0x400   /* wait for page to replace migration entry */
 #define FOLL_TRIED 0x800   /* a retry, previous pass started an IO */
+#define FOLL_LRU0x1000  /* return only LRU (anon or page cache) */
 #define FOLL_REMOTE0x2000  /* we are working on non-current tsk/mm */
 #define FOLL_COW   0x4000  /* internal GUP flag */
 #define FOLL_ANON  0x8000  /* don't do file mappings */
diff --git a/mm/gup.c b/mm/gup.c
index a214c8df7140..13bf04bce132 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -479,6 +479,8 @@ static struct page *follow_page_pte(struct vm_area_struct 
*vma,
}
 
page = vm_normal_page(vma, address, pte);
+   if ((flags & FOLL_LRU) && page && is_zone_device_page(page))
+   page = NULL;
if (!page && pte_devmap(pte) && (flags & (FOLL_GET | FOLL_PIN))) {
/*
 * Only return device mapping pages in the FOLL_GET or FOLL_PIN
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 910a138e9859..eed80696c5fd 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2856,7 +2856,7 @@ static int split_huge_pages_pid(int pid, unsigned long 
vaddr_start,
}
 
/* FOLL_DUMP to ignore special (like zero) pages */
-   page = follow_page(vma, addr, FOLL_GET | FOLL_DUMP);
+   page = follow_page(vma, addr, FOLL_GET | FOLL_DUMP | FOLL_LRU);
 
if (IS_ERR(page))
continue;
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index a4e5eaf3eb01..eb3cfd679800 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -627,7 +627,7 @@ static int __collapse_huge_page_isolate(struct 
vm_area_struct *vma,
goto out;
}
page = vm_normal_page(vma, address, pteval);
-   if (unlikely(!page)) {
+   if (unlikely(!page) || unlikely(is_zone_device_page(page))) {
result = SCAN_PAGE_NULL;
goto out;
}
@@ -1276,7 +1276,7 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
writable = true;
 
page = vm_normal_page(vma, _address, pteval);
-   if (unlikely(!page)) {
+   if (unlikely(!page) || unlikely(is_zone_device_page(page))) {
result = SCAN_PAGE_NULL;
goto out_unmap;
}
@@ -1484,7 +1484,8 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, 
unsigned long addr)
goto abort;
 
page = vm_normal_page(vma, addr, *pte);
-
+   if (page && is_zone_device_page(page))
+   page = NULL;
/*
 * Note that uprobe, debugger, or MAP_PRIVATE may change the
 * page table, but the new page will not be a subpage of hpage.
@@ -1502,6 +1503,8 @@ void 

[PATCH v2 13/13] tools: add selftests to hmm for COW in device memory

2022-05-16 Thread Alex Sierra
The objective is to test device migration mechanism in pages marked
as COW, for private and coherent device type. In case of writing to
COW private page(s), a page fault will migrate pages back to system
memory first. Then, these pages will be duplicated. In case of COW
device coherent type, pages are duplicated directly from device
memory.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
---
 tools/testing/selftests/vm/hmm-tests.c | 80 ++
 1 file changed, 80 insertions(+)

diff --git a/tools/testing/selftests/vm/hmm-tests.c 
b/tools/testing/selftests/vm/hmm-tests.c
index 61a02a6a3dea..76570030ba5b 100644
--- a/tools/testing/selftests/vm/hmm-tests.c
+++ b/tools/testing/selftests/vm/hmm-tests.c
@@ -1871,4 +1871,84 @@ TEST_F(hmm, hmm_gup_test)
close(gup_fd);
hmm_buffer_free(buffer);
 }
+
+/*
+ * Test copy-on-write in device pages.
+ * In case of writing to COW private page(s), a page fault will migrate pages
+ * back to system memory first. Then, these pages will be duplicated. In case
+ * of COW device coherent type, pages are duplicated directly from device
+ * memory.
+ */
+TEST_F(hmm, hmm_cow_in_device)
+{
+   struct hmm_buffer *buffer;
+   unsigned long npages;
+   unsigned long size;
+   unsigned long i;
+   int *ptr;
+   int ret;
+   unsigned char *m;
+   pid_t pid;
+   int status;
+
+   npages = 4;
+   size = npages << self->page_shift;
+
+   buffer = malloc(sizeof(*buffer));
+   ASSERT_NE(buffer, NULL);
+
+   buffer->fd = -1;
+   buffer->size = size;
+   buffer->mirror = malloc(size);
+   ASSERT_NE(buffer->mirror, NULL);
+
+   buffer->ptr = mmap(NULL, size,
+  PROT_READ | PROT_WRITE,
+  MAP_PRIVATE | MAP_ANONYMOUS,
+  buffer->fd, 0);
+   ASSERT_NE(buffer->ptr, MAP_FAILED);
+
+   /* Initialize buffer in system memory. */
+   for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
+   ptr[i] = i;
+
+   /* Migrate memory to device. */
+
+   ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
+   ASSERT_EQ(ret, 0);
+   ASSERT_EQ(buffer->cpages, npages);
+
+   pid = fork();
+   if (pid == -1)
+   ASSERT_EQ(pid, 0);
+   if (!pid) {
+   /* Child process waitd for SIGTERM from the parent. */
+   while (1) {
+   }
+   perror("Should not reach this\n");
+   exit(0);
+   }
+   /* Parent process writes to COW pages(s) and gets a
+* new copy in system. In case of device private pages,
+* this write causes a migration to system mem first.
+*/
+   for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
+   ptr[i] = i;
+
+   /* Terminate child and wait */
+   EXPECT_EQ(0, kill(pid, SIGTERM));
+   EXPECT_EQ(pid, waitpid(pid, , 0));
+   EXPECT_NE(0, WIFSIGNALED(status));
+   EXPECT_EQ(SIGTERM, WTERMSIG(status));
+
+   /* Take snapshot to CPU pagetables */
+   ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
+   ASSERT_EQ(ret, 0);
+   ASSERT_EQ(buffer->cpages, npages);
+   m = buffer->mirror;
+   for (i = 0; i < npages; i++)
+   ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[i]);
+
+   hmm_buffer_free(buffer);
+}
 TEST_HARNESS_MAIN
-- 
2.32.0



[PATCH v2 08/13] lib: add support for device coherent type in test_hmm

2022-05-16 Thread Alex Sierra
Device Coherent type uses device memory that is coherently accesible by
the CPU. This could be shown as SP (special purpose) memory range
at the BIOS-e820 memory enumeration. If no SP memory is supported in
system, this could be faked by setting CONFIG_EFI_FAKE_MEMMAP.

Currently, test_hmm only supports two different SP ranges of at least
256MB size. This could be specified in the kernel parameter variable
efi_fake_mem. Ex. Two SP ranges of 1GB starting at 0x1 &
0x14000 physical address. Ex.
efi_fake_mem=1G@0x1:0x4,1G@0x14000:0x4

Private and coherent device mirror instances can be created in the same
probed. This is done by passing the module parameters spm_addr_dev0 &
spm_addr_dev1. In this case, it will create four instances of
device_mirror. The first two correspond to private device type, the
last two to coherent type. Then, they can be easily accessed from user
space through /dev/hmm_mirror. Usually num_device 0 and 1
are for private, and 2 and 3 for coherent types. If no module
parameters are passed, two instances of private type device_mirror will
be created only.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Poppple 
---
 lib/test_hmm.c  | 253 +---
 lib/test_hmm_uapi.h |  15 ++-
 2 files changed, 202 insertions(+), 66 deletions(-)

diff --git a/lib/test_hmm.c b/lib/test_hmm.c
index 15747f70c5bc..361a026c5d21 100644
--- a/lib/test_hmm.c
+++ b/lib/test_hmm.c
@@ -32,11 +32,22 @@
 
 #include "test_hmm_uapi.h"
 
-#define DMIRROR_NDEVICES   2
+#define DMIRROR_NDEVICES   4
 #define DMIRROR_RANGE_FAULT_TIMEOUT1000
 #define DEVMEM_CHUNK_SIZE  (256 * 1024 * 1024U)
 #define DEVMEM_CHUNKS_RESERVE  16
 
+/*
+ * For device_private pages, dpage is just a dummy struct page
+ * representing a piece of device memory. dmirror_devmem_alloc_page
+ * allocates a real system memory page as backing storage to fake a
+ * real device. zone_device_data points to that backing page. But
+ * for device_coherent memory, the struct page represents real
+ * physical CPU-accessible memory that we can use directly.
+ */
+#define BACKING_PAGE(page) (is_device_private_page((page)) ? \
+  (page)->zone_device_data : (page))
+
 static unsigned long spm_addr_dev0;
 module_param(spm_addr_dev0, long, 0644);
 MODULE_PARM_DESC(spm_addr_dev0,
@@ -125,6 +136,21 @@ static int dmirror_bounce_init(struct dmirror_bounce 
*bounce,
return 0;
 }
 
+static bool dmirror_is_private_zone(struct dmirror_device *mdevice)
+{
+   return (mdevice->zone_device_type ==
+   HMM_DMIRROR_MEMORY_DEVICE_PRIVATE) ? true : false;
+}
+
+static enum migrate_vma_direction
+dmirror_select_device(struct dmirror *dmirror)
+{
+   return (dmirror->mdevice->zone_device_type ==
+   HMM_DMIRROR_MEMORY_DEVICE_PRIVATE) ?
+   MIGRATE_VMA_SELECT_DEVICE_PRIVATE :
+   MIGRATE_VMA_SELECT_DEVICE_COHERENT;
+}
+
 static void dmirror_bounce_fini(struct dmirror_bounce *bounce)
 {
vfree(bounce->ptr);
@@ -575,16 +601,19 @@ static int dmirror_allocate_chunk(struct dmirror_device 
*mdevice,
 static struct page *dmirror_devmem_alloc_page(struct dmirror_device *mdevice)
 {
struct page *dpage = NULL;
-   struct page *rpage;
+   struct page *rpage = NULL;
 
/*
-* This is a fake device so we alloc real system memory to store
-* our device memory.
+* For ZONE_DEVICE private type, this is a fake device so we allocate
+* real system memory to store our device memory.
+* For ZONE_DEVICE coherent type we use the actual dpage to store the
+* data and ignore rpage.
 */
-   rpage = alloc_page(GFP_HIGHUSER);
-   if (!rpage)
-   return NULL;
-
+   if (dmirror_is_private_zone(mdevice)) {
+   rpage = alloc_page(GFP_HIGHUSER);
+   if (!rpage)
+   return NULL;
+   }
spin_lock(>lock);
 
if (mdevice->free_pages) {
@@ -603,7 +632,8 @@ static struct page *dmirror_devmem_alloc_page(struct 
dmirror_device *mdevice)
return dpage;
 
 error:
-   __free_page(rpage);
+   if (rpage)
+   __free_page(rpage);
return NULL;
 }
 
@@ -629,12 +659,16 @@ static void dmirror_migrate_alloc_and_copy(struct 
migrate_vma *args,
 * unallocated pte_none() or read-only zero page.
 */
spage = migrate_pfn_to_page(*src);
+   if (WARN(spage && is_zone_device_page(spage),
+"page already in device spage pfn: 0x%lx\n",
+page_to_pfn(spage)))
+   continue;
 
dpage = dmirror_devmem_alloc_page(mdevice);
if (!dpage)
continue;
 
-   rpage = dpage->zone_device_data;
+   rpage = BACKING_PAGE(dpage);
  

[PATCH v2 12/13] tools: add hmm gup tests for device coherent type

2022-05-16 Thread Alex Sierra
The intention is to test hmm device coherent type under different get
user pages paths. Also, test gup with FOLL_LONGTERM flag set in
device coherent pages. These pages should get migrated back to system
memory.

Signed-off-by: Alex Sierra 
Reviewed-by: Alistair Popple 
---
 tools/testing/selftests/vm/hmm-tests.c | 105 +
 1 file changed, 105 insertions(+)

diff --git a/tools/testing/selftests/vm/hmm-tests.c 
b/tools/testing/selftests/vm/hmm-tests.c
index 84ec8c4a1dc7..61a02a6a3dea 100644
--- a/tools/testing/selftests/vm/hmm-tests.c
+++ b/tools/testing/selftests/vm/hmm-tests.c
@@ -36,6 +36,7 @@
  * in the usual include/uapi/... directory.
  */
 #include "../../../../lib/test_hmm_uapi.h"
+#include "../../../../mm/gup_test.h"
 
 struct hmm_buffer {
void*ptr;
@@ -60,6 +61,8 @@ enum {
 #define NTIMES 10
 
 #define ALIGN(x, a) (((x) + (a - 1)) & (~((a) - 1)))
+/* Just the flags we need, copied from mm.h: */
+#define FOLL_WRITE 0x01/* check pte is writable */
 
 FIXTURE(hmm)
 {
@@ -1766,4 +1769,106 @@ TEST_F(hmm, exclusive_cow)
hmm_buffer_free(buffer);
 }
 
+static int gup_test_exec(int gup_fd, unsigned long addr,
+int cmd, int npages, int size)
+{
+   struct gup_test gup = {
+   .nr_pages_per_call  = npages,
+   .addr   = addr,
+   .gup_flags  = FOLL_WRITE,
+   .size   = size,
+   };
+
+   if (ioctl(gup_fd, cmd, )) {
+   perror("ioctl on error\n");
+   return errno;
+   }
+
+   return 0;
+}
+
+/*
+ * Test get user device pages through gup_test. Setting PIN_LONGTERM flag.
+ * This should trigger a migration back to system memory for both, private
+ * and coherent type pages.
+ * This test makes use of gup_test module. Make sure GUP_TEST_CONFIG is added
+ * to your configuration before you run it.
+ */
+TEST_F(hmm, hmm_gup_test)
+{
+   struct hmm_buffer *buffer;
+   int gup_fd;
+   unsigned long npages;
+   unsigned long size;
+   unsigned long i;
+   int *ptr;
+   int ret;
+   unsigned char *m;
+
+   gup_fd = open("/sys/kernel/debug/gup_test", O_RDWR);
+   if (gup_fd == -1)
+   SKIP(return, "Skipping test, could not find gup_test driver");
+
+   npages = 3;
+   size = npages << self->page_shift;
+
+   buffer = malloc(sizeof(*buffer));
+   ASSERT_NE(buffer, NULL);
+
+   buffer->fd = -1;
+   buffer->size = size;
+   buffer->mirror = malloc(size);
+   ASSERT_NE(buffer->mirror, NULL);
+
+   buffer->ptr = mmap(NULL, size,
+  PROT_READ | PROT_WRITE,
+  MAP_PRIVATE | MAP_ANONYMOUS,
+  buffer->fd, 0);
+   ASSERT_NE(buffer->ptr, MAP_FAILED);
+
+   /* Initialize buffer in system memory. */
+   for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
+   ptr[i] = i;
+
+   /* Migrate memory to device. */
+   ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
+   ASSERT_EQ(ret, 0);
+   ASSERT_EQ(buffer->cpages, npages);
+   /* Check what the device read. */
+   for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
+   ASSERT_EQ(ptr[i], i);
+
+   ASSERT_EQ(gup_test_exec(gup_fd,
+   (unsigned long)buffer->ptr,
+   GUP_BASIC_TEST, 1, self->page_size), 0);
+   ASSERT_EQ(gup_test_exec(gup_fd,
+   (unsigned long)buffer->ptr + 1 * 
self->page_size,
+   GUP_FAST_BENCHMARK, 1, self->page_size), 0);
+   ASSERT_EQ(gup_test_exec(gup_fd,
+   (unsigned long)buffer->ptr + 2 * 
self->page_size,
+   PIN_LONGTERM_BENCHMARK, 1, self->page_size), 0);
+
+   /* Take snapshot to CPU pagetables */
+   ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
+   ASSERT_EQ(ret, 0);
+   ASSERT_EQ(buffer->cpages, npages);
+   m = buffer->mirror;
+   if (hmm_is_coherent_type(variant->device_number)) {
+   ASSERT_EQ(HMM_DMIRROR_PROT_DEV_COHERENT_LOCAL | 
HMM_DMIRROR_PROT_WRITE, m[0]);
+   ASSERT_EQ(HMM_DMIRROR_PROT_DEV_COHERENT_LOCAL | 
HMM_DMIRROR_PROT_WRITE, m[1]);
+   } else {
+   ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[0]);
+   ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[1]);
+   }
+   ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[2]);
+   /*
+* Check again the content on the pages. Make sure there's no
+* corrupted data.
+*/
+   for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
+   ASSERT_EQ(ptr[i], i);
+
+   close(gup_fd);
+   hmm_buffer_free(buffer);
+}
 TEST_HARNESS_MAIN
-- 
2.32.0



[PATCH v2 10/13] tools: update test_hmm script to support SP config

2022-05-16 Thread Alex Sierra
Add two more parameters to set spm_addr_dev0 & spm_addr_dev1
addresses. These two parameters configure the start SP
addresses for each device in test_hmm driver.
Consequently, this configures zone device type as coherent.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Popple 
Signed-off-by: Christoph Hellwig 
---
 tools/testing/selftests/vm/test_hmm.sh | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/vm/test_hmm.sh 
b/tools/testing/selftests/vm/test_hmm.sh
index 0647b525a625..539c9371e592 100755
--- a/tools/testing/selftests/vm/test_hmm.sh
+++ b/tools/testing/selftests/vm/test_hmm.sh
@@ -40,11 +40,26 @@ check_test_requirements()
 
 load_driver()
 {
-   modprobe $DRIVER > /dev/null 2>&1
+   if [ $# -eq 0 ]; then
+   modprobe $DRIVER > /dev/null 2>&1
+   else
+   if [ $# -eq 2 ]; then
+   modprobe $DRIVER spm_addr_dev0=$1 spm_addr_dev1=$2
+   > /dev/null 2>&1
+   else
+   echo "Missing module parameters. Make sure pass"\
+   "spm_addr_dev0 and spm_addr_dev1"
+   usage
+   fi
+   fi
if [ $? == 0 ]; then
major=$(awk "\$2==\"HMM_DMIRROR\" {print \$1}" /proc/devices)
mknod /dev/hmm_dmirror0 c $major 0
mknod /dev/hmm_dmirror1 c $major 1
+   if [ $# -eq 2 ]; then
+   mknod /dev/hmm_dmirror2 c $major 2
+   mknod /dev/hmm_dmirror3 c $major 3
+   fi
fi
 }
 
@@ -58,7 +73,7 @@ run_smoke()
 {
echo "Running smoke test. Note, this test provides basic coverage."
 
-   load_driver
+   load_driver $1 $2
$(dirname "${BASH_SOURCE[0]}")/hmm-tests
unload_driver
 }
@@ -75,6 +90,9 @@ usage()
echo "# Smoke testing"
echo "./${TEST_NAME}.sh smoke"
echo
+   echo "# Smoke testing with SPM enabled"
+   echo "./${TEST_NAME}.sh smoke  "
+   echo
exit 0
 }
 
@@ -84,7 +102,7 @@ function run_test()
usage
else
if [ "$1" = "smoke" ]; then
-   run_smoke
+   run_smoke $2 $3
else
usage
fi
-- 
2.32.0



[PATCH v2 05/13] drm/amdkfd: add SPM support for SVM

2022-05-16 Thread Alex Sierra
When CPU is connected throug XGMI, it has coherent
access to VRAM resource. In this case that resource
is taken from a table in the device gmc aperture base.
This resource is used along with the device type, which could
be DEVICE_PRIVATE or DEVICE_COHERENT to create the device
page map region.
Also, MIGRATE_VMA_SELECT_DEVICE_COHERENT flag is selected for
coherent type case during migration to device.

Signed-off-by: Alex Sierra 
Reviewed-by: Felix Kuehling 
Signed-off-by: Christoph Hellwig 
---
 drivers/gpu/drm/amd/amdkfd/kfd_migrate.c | 33 +++-
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
index 7e3a7fcb9fe6..25c9f7a4325d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
@@ -673,9 +673,12 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct 
svm_range *prange,
migrate.vma = vma;
migrate.start = start;
migrate.end = end;
-   migrate.flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE;
migrate.pgmap_owner = SVM_ADEV_PGMAP_OWNER(adev);
 
+   if (adev->gmc.xgmi.connected_to_cpu)
+   migrate.flags = MIGRATE_VMA_SELECT_DEVICE_COHERENT;
+   else
+   migrate.flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE;
size = 2 * sizeof(*migrate.src) + sizeof(uint64_t) + sizeof(dma_addr_t);
size *= npages;
buf = kvmalloc(size, GFP_KERNEL | __GFP_ZERO);
@@ -948,7 +951,7 @@ int svm_migrate_init(struct amdgpu_device *adev)
 {
struct kfd_dev *kfddev = adev->kfd.dev;
struct dev_pagemap *pgmap;
-   struct resource *res;
+   struct resource *res = NULL;
unsigned long size;
void *r;
 
@@ -963,28 +966,34 @@ int svm_migrate_init(struct amdgpu_device *adev)
 * should remove reserved size
 */
size = ALIGN(adev->gmc.real_vram_size, 2ULL << 20);
-   res = devm_request_free_mem_region(adev->dev, _resource, size);
-   if (IS_ERR(res))
-   return -ENOMEM;
+   if (adev->gmc.xgmi.connected_to_cpu) {
+   pgmap->range.start = adev->gmc.aper_base;
+   pgmap->range.end = adev->gmc.aper_base + adev->gmc.aper_size - 
1;
+   pgmap->type = MEMORY_DEVICE_COHERENT;
+   } else {
+   res = devm_request_free_mem_region(adev->dev, _resource, 
size);
+   if (IS_ERR(res))
+   return -ENOMEM;
+   pgmap->range.start = res->start;
+   pgmap->range.end = res->end;
+   pgmap->type = MEMORY_DEVICE_PRIVATE;
+   }
 
-   pgmap->type = MEMORY_DEVICE_PRIVATE;
pgmap->nr_range = 1;
-   pgmap->range.start = res->start;
-   pgmap->range.end = res->end;
pgmap->ops = _migrate_pgmap_ops;
pgmap->owner = SVM_ADEV_PGMAP_OWNER(adev);
-   pgmap->flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE;
-
+   pgmap->flags = 0;
/* Device manager releases device-specific resources, memory region and
 * pgmap when driver disconnects from device.
 */
r = devm_memremap_pages(adev->dev, pgmap);
if (IS_ERR(r)) {
pr_err("failed to register HMM device memory\n");
-
/* Disable SVM support capability */
pgmap->type = 0;
-   devm_release_mem_region(adev->dev, res->start, 
resource_size(res));
+   if (pgmap->type == MEMORY_DEVICE_PRIVATE)
+   devm_release_mem_region(adev->dev, res->start,
+   res->end - res->start + 1);
return PTR_ERR(r);
}
 
-- 
2.32.0



[PATCH v2 09/13] tools: update hmm-test to support device coherent type

2022-05-16 Thread Alex Sierra
Test cases such as migrate_fault and migrate_multiple, were modified to
explicit migrate from device to sys memory without the need of page
faults, when using device coherent type.

Snapshot test case updated to read memory device type first and based
on that, get the proper returned results migrate_ping_pong test case
added to test explicit migration from device to sys memory for both
private and coherent zone types.

Helpers to migrate from device to sys memory and vicerversa
were also added.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Popple 
Signed-off-by: Christoph Hellwig 
---
 tools/testing/selftests/vm/hmm-tests.c | 123 -
 1 file changed, 102 insertions(+), 21 deletions(-)

diff --git a/tools/testing/selftests/vm/hmm-tests.c 
b/tools/testing/selftests/vm/hmm-tests.c
index 203323967b50..84ec8c4a1dc7 100644
--- a/tools/testing/selftests/vm/hmm-tests.c
+++ b/tools/testing/selftests/vm/hmm-tests.c
@@ -44,6 +44,14 @@ struct hmm_buffer {
int fd;
uint64_tcpages;
uint64_tfaults;
+   int zone_device_type;
+};
+
+enum {
+   HMM_PRIVATE_DEVICE_ONE,
+   HMM_PRIVATE_DEVICE_TWO,
+   HMM_COHERENCE_DEVICE_ONE,
+   HMM_COHERENCE_DEVICE_TWO,
 };
 
 #define TWOMEG (1 << 21)
@@ -60,6 +68,21 @@ FIXTURE(hmm)
unsigned intpage_shift;
 };
 
+FIXTURE_VARIANT(hmm)
+{
+   int device_number;
+};
+
+FIXTURE_VARIANT_ADD(hmm, hmm_device_private)
+{
+   .device_number = HMM_PRIVATE_DEVICE_ONE,
+};
+
+FIXTURE_VARIANT_ADD(hmm, hmm_device_coherent)
+{
+   .device_number = HMM_COHERENCE_DEVICE_ONE,
+};
+
 FIXTURE(hmm2)
 {
int fd0;
@@ -68,6 +91,24 @@ FIXTURE(hmm2)
unsigned intpage_shift;
 };
 
+FIXTURE_VARIANT(hmm2)
+{
+   int device_number0;
+   int device_number1;
+};
+
+FIXTURE_VARIANT_ADD(hmm2, hmm2_device_private)
+{
+   .device_number0 = HMM_PRIVATE_DEVICE_ONE,
+   .device_number1 = HMM_PRIVATE_DEVICE_TWO,
+};
+
+FIXTURE_VARIANT_ADD(hmm2, hmm2_device_coherent)
+{
+   .device_number0 = HMM_COHERENCE_DEVICE_ONE,
+   .device_number1 = HMM_COHERENCE_DEVICE_TWO,
+};
+
 static int hmm_open(int unit)
 {
char pathname[HMM_PATH_MAX];
@@ -81,12 +122,19 @@ static int hmm_open(int unit)
return fd;
 }
 
+static bool hmm_is_coherent_type(int dev_num)
+{
+   return (dev_num >= HMM_COHERENCE_DEVICE_ONE);
+}
+
 FIXTURE_SETUP(hmm)
 {
self->page_size = sysconf(_SC_PAGE_SIZE);
self->page_shift = ffs(self->page_size) - 1;
 
-   self->fd = hmm_open(0);
+   self->fd = hmm_open(variant->device_number);
+   if (self->fd < 0 && hmm_is_coherent_type(variant->device_number))
+   SKIP(exit(0), "DEVICE_COHERENT not available");
ASSERT_GE(self->fd, 0);
 }
 
@@ -95,9 +143,11 @@ FIXTURE_SETUP(hmm2)
self->page_size = sysconf(_SC_PAGE_SIZE);
self->page_shift = ffs(self->page_size) - 1;
 
-   self->fd0 = hmm_open(0);
+   self->fd0 = hmm_open(variant->device_number0);
+   if (self->fd0 < 0 && hmm_is_coherent_type(variant->device_number0))
+   SKIP(exit(0), "DEVICE_COHERENT not available");
ASSERT_GE(self->fd0, 0);
-   self->fd1 = hmm_open(1);
+   self->fd1 = hmm_open(variant->device_number1);
ASSERT_GE(self->fd1, 0);
 }
 
@@ -144,6 +194,7 @@ static int hmm_dmirror_cmd(int fd,
}
buffer->cpages = cmd.cpages;
buffer->faults = cmd.faults;
+   buffer->zone_device_type = cmd.zone_device_type;
 
return 0;
 }
@@ -211,6 +262,20 @@ static void hmm_nanosleep(unsigned int n)
nanosleep(, NULL);
 }
 
+static int hmm_migrate_sys_to_dev(int fd,
+  struct hmm_buffer *buffer,
+  unsigned long npages)
+{
+   return hmm_dmirror_cmd(fd, HMM_DMIRROR_MIGRATE_TO_DEV, buffer, npages);
+}
+
+static int hmm_migrate_dev_to_sys(int fd,
+  struct hmm_buffer *buffer,
+  unsigned long npages)
+{
+   return hmm_dmirror_cmd(fd, HMM_DMIRROR_MIGRATE_TO_SYS, buffer, npages);
+}
+
 /*
  * Simple NULL test of device open/close.
  */
@@ -875,7 +940,7 @@ TEST_F(hmm, migrate)
ptr[i] = i;
 
/* Migrate memory to device. */
-   ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_MIGRATE, buffer, npages);
+   ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
ASSERT_EQ(ret, 0);
ASSERT_EQ(buffer->cpages, npages);
 
@@ -923,7 +988,7 @@ TEST_F(hmm, migrate_fault)
ptr[i] = i;
 
/* Migrate memory to device. */
-   ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_MIGRATE, buffer, npages);
+   ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
ASSERT_EQ(ret, 0);
ASSERT_EQ(buffer->cpages, npages);
 
@@ -936,7 +1001,7 @@ TEST_F(hmm, migrate_fault)
ASSERT_EQ(ptr[i], i);
 

[PATCH v2 07/13] lib: test_hmm add module param for zone device type

2022-05-16 Thread Alex Sierra
In order to configure device coherent in test_hmm, two module parameters
should be passed, which correspond to the SP start address of each
device (2) spm_addr_dev0 & spm_addr_dev1. If no parameters are passed,
private device type is configured.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Poppple 
Signed-off-by: Christoph Hellwig 
---
 lib/test_hmm.c  | 73 -
 lib/test_hmm_uapi.h |  1 +
 2 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/lib/test_hmm.c b/lib/test_hmm.c
index 7a27584484ce..15747f70c5bc 100644
--- a/lib/test_hmm.c
+++ b/lib/test_hmm.c
@@ -37,6 +37,16 @@
 #define DEVMEM_CHUNK_SIZE  (256 * 1024 * 1024U)
 #define DEVMEM_CHUNKS_RESERVE  16
 
+static unsigned long spm_addr_dev0;
+module_param(spm_addr_dev0, long, 0644);
+MODULE_PARM_DESC(spm_addr_dev0,
+   "Specify start address for SPM (special purpose memory) used 
for device 0. By setting this Coherent device type will be used. Make sure 
spm_addr_dev1 is set too. Minimum SPM size should be DEVMEM_CHUNK_SIZE.");
+
+static unsigned long spm_addr_dev1;
+module_param(spm_addr_dev1, long, 0644);
+MODULE_PARM_DESC(spm_addr_dev1,
+   "Specify start address for SPM (special purpose memory) used 
for device 1. By setting this Coherent device type will be used. Make sure 
spm_addr_dev0 is set too. Minimum SPM size should be DEVMEM_CHUNK_SIZE.");
+
 static const struct dev_pagemap_ops dmirror_devmem_ops;
 static const struct mmu_interval_notifier_ops dmirror_min_ops;
 static dev_t dmirror_dev;
@@ -455,28 +465,44 @@ static int dmirror_write(struct dmirror *dmirror, struct 
hmm_dmirror_cmd *cmd)
return ret;
 }
 
-static bool dmirror_allocate_chunk(struct dmirror_device *mdevice,
+static int dmirror_allocate_chunk(struct dmirror_device *mdevice,
   struct page **ppage)
 {
struct dmirror_chunk *devmem;
-   struct resource *res;
+   struct resource *res = NULL;
unsigned long pfn;
unsigned long pfn_first;
unsigned long pfn_last;
void *ptr;
+   int ret = -ENOMEM;
 
devmem = kzalloc(sizeof(*devmem), GFP_KERNEL);
if (!devmem)
-   return false;
+   return ret;
 
-   res = request_free_mem_region(_resource, DEVMEM_CHUNK_SIZE,
- "hmm_dmirror");
-   if (IS_ERR(res))
+   switch (mdevice->zone_device_type) {
+   case HMM_DMIRROR_MEMORY_DEVICE_PRIVATE:
+   res = request_free_mem_region(_resource, 
DEVMEM_CHUNK_SIZE,
+ "hmm_dmirror");
+   if (IS_ERR_OR_NULL(res))
+   goto err_devmem;
+   devmem->pagemap.range.start = res->start;
+   devmem->pagemap.range.end = res->end;
+   devmem->pagemap.type = MEMORY_DEVICE_PRIVATE;
+   break;
+   case HMM_DMIRROR_MEMORY_DEVICE_COHERENT:
+   devmem->pagemap.range.start = (MINOR(mdevice->cdevice.dev) - 2) 
?
+   spm_addr_dev0 :
+   spm_addr_dev1;
+   devmem->pagemap.range.end = devmem->pagemap.range.start +
+   DEVMEM_CHUNK_SIZE - 1;
+   devmem->pagemap.type = MEMORY_DEVICE_COHERENT;
+   break;
+   default:
+   ret = -EINVAL;
goto err_devmem;
+   }
 
-   devmem->pagemap.type = MEMORY_DEVICE_PRIVATE;
-   devmem->pagemap.range.start = res->start;
-   devmem->pagemap.range.end = res->end;
devmem->pagemap.nr_range = 1;
devmem->pagemap.ops = _devmem_ops;
devmem->pagemap.owner = mdevice;
@@ -497,10 +523,14 @@ static bool dmirror_allocate_chunk(struct dmirror_device 
*mdevice,
mdevice->devmem_capacity = new_capacity;
mdevice->devmem_chunks = new_chunks;
}
-
ptr = memremap_pages(>pagemap, numa_node_id());
-   if (IS_ERR(ptr))
+   if (IS_ERR_OR_NULL(ptr)) {
+   if (ptr)
+   ret = PTR_ERR(ptr);
+   else
+   ret = -EFAULT;
goto err_release;
+   }
 
devmem->mdevice = mdevice;
pfn_first = devmem->pagemap.range.start >> PAGE_SHIFT;
@@ -529,15 +559,17 @@ static bool dmirror_allocate_chunk(struct dmirror_device 
*mdevice,
}
spin_unlock(>lock);
 
-   return true;
+   return 0;
 
 err_release:
mutex_unlock(>devmem_lock);
-   release_mem_region(devmem->pagemap.range.start, 
range_len(>pagemap.range));
+   if (res && devmem->pagemap.type == MEMORY_DEVICE_PRIVATE)
+   release_mem_region(devmem->pagemap.range.start,
+  range_len(>pagemap.range));
 err_devmem:
kfree(devmem);
 
-   return false;
+  

[PATCH v2 03/13] mm: remove the vma check in migrate_vma_setup()

2022-05-16 Thread Alex Sierra
From: Alistair Popple 

migrate_vma_setup() checks that a valid vma is passed so that the page
tables can be walked to find the pfns associated with a given address
range. However in some cases the pfns are already known, such as when
migrating device coherent pages during pin_user_pages() meaning a valid
vma isn't required.

Signed-off-by: Alistair Popple 
Acked-by: Felix Kuehling 
Signed-off-by: Christoph Hellwig 
---
 mm/migrate_device.c | 34 +-
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index a0b997935cf9..b399c498f0aa 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -467,24 +467,24 @@ int migrate_vma_setup(struct migrate_vma *args)
 
args->start &= PAGE_MASK;
args->end &= PAGE_MASK;
-   if (!args->vma || is_vm_hugetlb_page(args->vma) ||
-   (args->vma->vm_flags & VM_SPECIAL) || vma_is_dax(args->vma))
-   return -EINVAL;
-   if (nr_pages <= 0)
-   return -EINVAL;
-   if (args->start < args->vma->vm_start ||
-   args->start >= args->vma->vm_end)
-   return -EINVAL;
-   if (args->end <= args->vma->vm_start || args->end > args->vma->vm_end)
-   return -EINVAL;
if (!args->src || !args->dst)
return -EINVAL;
-
-   memset(args->src, 0, sizeof(*args->src) * nr_pages);
-   args->cpages = 0;
-   args->npages = 0;
-
-   migrate_vma_collect(args);
+   if (args->vma) {
+   if (is_vm_hugetlb_page(args->vma) ||
+   (args->vma->vm_flags & VM_SPECIAL) || vma_is_dax(args->vma))
+   return -EINVAL;
+   if (args->start < args->vma->vm_start ||
+   args->start >= args->vma->vm_end)
+   return -EINVAL;
+   if (args->end <= args->vma->vm_start ||
+   args->end > args->vma->vm_end)
+   return -EINVAL;
+   memset(args->src, 0, sizeof(*args->src) * nr_pages);
+   args->cpages = 0;
+   args->npages = 0;
+
+   migrate_vma_collect(args);
+   }
 
if (args->cpages)
migrate_vma_unmap(args);
@@ -666,7 +666,7 @@ void migrate_vma_pages(struct migrate_vma *migrate)
continue;
}
 
-   if (!page) {
+   if (!page && migrate->vma) {
if (!(migrate->src[i] & MIGRATE_PFN_MIGRATE))
continue;
if (!notified) {
-- 
2.32.0



[PATCH v2 06/13] lib: test_hmm add ioctl to get zone device type

2022-05-16 Thread Alex Sierra
new ioctl cmd added to query zone device type. This will be
used once the test_hmm adds zone device coherent type.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Poppple 
Signed-off-by: Christoph Hellwig 
---
 lib/test_hmm.c  | 23 +--
 lib/test_hmm_uapi.h |  8 
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/lib/test_hmm.c b/lib/test_hmm.c
index cfe632047839..7a27584484ce 100644
--- a/lib/test_hmm.c
+++ b/lib/test_hmm.c
@@ -87,6 +87,7 @@ struct dmirror_chunk {
 struct dmirror_device {
struct cdev cdevice;
struct hmm_devmem   *devmem;
+   unsigned intzone_device_type;
 
unsigned intdevmem_capacity;
unsigned intdevmem_count;
@@ -1026,6 +1027,15 @@ static int dmirror_snapshot(struct dmirror *dmirror,
return ret;
 }
 
+static int dmirror_get_device_type(struct dmirror *dmirror,
+   struct hmm_dmirror_cmd *cmd)
+{
+   mutex_lock(>mutex);
+   cmd->zone_device_type = dmirror->mdevice->zone_device_type;
+   mutex_unlock(>mutex);
+
+   return 0;
+}
 static long dmirror_fops_unlocked_ioctl(struct file *filp,
unsigned int command,
unsigned long arg)
@@ -1076,6 +1086,9 @@ static long dmirror_fops_unlocked_ioctl(struct file *filp,
ret = dmirror_snapshot(dmirror, );
break;
 
+   case HMM_DMIRROR_GET_MEM_DEV_TYPE:
+   ret = dmirror_get_device_type(dmirror, );
+   break;
default:
return -EINVAL;
}
@@ -1260,14 +1273,20 @@ static void dmirror_device_remove(struct dmirror_device 
*mdevice)
 static int __init hmm_dmirror_init(void)
 {
int ret;
-   int id;
+   int id = 0;
+   int ndevices = 0;
 
ret = alloc_chrdev_region(_dev, 0, DMIRROR_NDEVICES,
  "HMM_DMIRROR");
if (ret)
goto err_unreg;
 
-   for (id = 0; id < DMIRROR_NDEVICES; id++) {
+   memset(dmirror_devices, 0, DMIRROR_NDEVICES * 
sizeof(dmirror_devices[0]));
+   dmirror_devices[ndevices++].zone_device_type =
+   HMM_DMIRROR_MEMORY_DEVICE_PRIVATE;
+   dmirror_devices[ndevices++].zone_device_type =
+   HMM_DMIRROR_MEMORY_DEVICE_PRIVATE;
+   for (id = 0; id < ndevices; id++) {
ret = dmirror_device_init(dmirror_devices + id, id);
if (ret)
goto err_chrdev;
diff --git a/lib/test_hmm_uapi.h b/lib/test_hmm_uapi.h
index f14dea5dcd06..17f842f1aa02 100644
--- a/lib/test_hmm_uapi.h
+++ b/lib/test_hmm_uapi.h
@@ -19,6 +19,7 @@
  * @npages: (in) number of pages to read/write
  * @cpages: (out) number of pages copied
  * @faults: (out) number of device page faults seen
+ * @zone_device_type: (out) zone device memory type
  */
 struct hmm_dmirror_cmd {
__u64   addr;
@@ -26,6 +27,7 @@ struct hmm_dmirror_cmd {
__u64   npages;
__u64   cpages;
__u64   faults;
+   __u64   zone_device_type;
 };
 
 /* Expose the address space of the calling process through hmm device file */
@@ -35,6 +37,7 @@ struct hmm_dmirror_cmd {
 #define HMM_DMIRROR_SNAPSHOT   _IOWR('H', 0x03, struct hmm_dmirror_cmd)
 #define HMM_DMIRROR_EXCLUSIVE  _IOWR('H', 0x04, struct hmm_dmirror_cmd)
 #define HMM_DMIRROR_CHECK_EXCLUSIVE_IOWR('H', 0x05, struct hmm_dmirror_cmd)
+#define HMM_DMIRROR_GET_MEM_DEV_TYPE   _IOWR('H', 0x06, struct hmm_dmirror_cmd)
 
 /*
  * Values returned in hmm_dmirror_cmd.ptr for HMM_DMIRROR_SNAPSHOT.
@@ -62,4 +65,9 @@ enum {
HMM_DMIRROR_PROT_DEV_PRIVATE_REMOTE = 0x30,
 };
 
+enum {
+   /* 0 is reserved to catch uninitialized type fields */
+   HMM_DMIRROR_MEMORY_DEVICE_PRIVATE = 1,
+};
+
 #endif /* _LIB_TEST_HMM_UAPI_H */
-- 
2.32.0



[PATCH v2 04/13] mm/gup: migrate device coherent pages when pinning instead of failing

2022-05-16 Thread Alex Sierra
From: Alistair Popple 

Currently any attempts to pin a device coherent page will fail. This is
because device coherent pages need to be managed by a device driver, and
pinning them would prevent a driver from migrating them off the device.

However this is no reason to fail pinning of these pages. These are
coherent and accessible from the CPU so can be migrated just like
pinning ZONE_MOVABLE pages. So instead of failing all attempts to pin
them first try migrating them out of ZONE_DEVICE.

Signed-off-by: Alistair Popple 
Acked-by: Felix Kuehling 
[hch: rebased to the split device memory checks,
  moved migrate_device_page to migrate_device.c]
Signed-off-by: Christoph Hellwig 
---
 mm/gup.c| 47 +++-
 mm/internal.h   |  1 +
 mm/migrate_device.c | 53 +
 3 files changed, 96 insertions(+), 5 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index f598a037eb04..a214c8df7140 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1786,9 +1786,43 @@ static long check_and_migrate_movable_pages(unsigned 
long nr_pages,
continue;
prev_folio = folio;
 
-   if (folio_is_pinnable(folio))
+   /*
+* Device private pages will get faulted in during gup so it
+* shouldn't be possible to see one here.
+*/
+   if (WARN_ON_ONCE(folio_is_device_private(folio))) {
+   ret = -EFAULT;
+   goto unpin_pages;
+   }
+
+   /*
+* Device coherent pages are managed by a driver and should not
+* be pinned indefinitely as it prevents the driver moving the
+* page. So when trying to pin with FOLL_LONGTERM instead try
+* to migrate the page out of device memory.
+*/
+   if (folio_is_device_coherent(folio)) {
+   WARN_ON_ONCE(PageCompound(>page));
+
+   /*
+* Migration will fail if the page is pinned, so convert
+* the pin on the source page to a normal reference.
+*/
+   if (gup_flags & FOLL_PIN) {
+   get_page(>page);
+   unpin_user_page(>page);
+   }
+
+   pages[i] = migrate_device_page(>page, gup_flags);
+   if (!pages[i]) {
+   ret = -EBUSY;
+   goto unpin_pages;
+   }
continue;
+   }
 
+   if (folio_is_pinnable(folio))
+   continue;
/*
 * Try to move out any movable page before pinning the range.
 */
@@ -1824,10 +1858,13 @@ static long check_and_migrate_movable_pages(unsigned 
long nr_pages,
return nr_pages;
 
 unpin_pages:
-   if (gup_flags & FOLL_PIN) {
-   unpin_user_pages(pages, nr_pages);
-   } else {
-   for (i = 0; i < nr_pages; i++)
+   for (i = 0; i < nr_pages; i++) {
+   if (!pages[i])
+   continue;
+
+   if (gup_flags & FOLL_PIN)
+   unpin_user_page(pages[i]);
+   else
put_page(pages[i]);
}
 
diff --git a/mm/internal.h b/mm/internal.h
index cf16280ce132..32c621416966 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -750,6 +750,7 @@ int numa_migrate_prep(struct page *page, struct 
vm_area_struct *vma,
  unsigned long addr, int page_nid, int *flags);
 
 void free_zone_device_page(struct page *page);
+struct page *migrate_device_page(struct page *page, unsigned int gup_flags);
 
 /*
  * mm/gup.c
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index b399c498f0aa..1e74aa7ab580 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -775,3 +775,56 @@ void migrate_vma_finalize(struct migrate_vma *migrate)
}
 }
 EXPORT_SYMBOL(migrate_vma_finalize);
+
+/*
+ * Migrate a device coherent page back to normal memory.  The caller should 
have
+ * a reference on page which will be copied to the new page if migration is
+ * successful or dropped on failure.
+ */
+struct page *migrate_device_page(struct page *page, unsigned int gup_flags)
+{
+   unsigned long src_pfn, dst_pfn = 0;
+   struct migrate_vma args;
+   struct page *dpage;
+
+   lock_page(page);
+   src_pfn = migrate_pfn(page_to_pfn(page)) | MIGRATE_PFN_MIGRATE;
+   args.src = _pfn;
+   args.dst = _pfn;
+   args.cpages = 1;
+   args.npages = 1;
+   args.vma = NULL;
+   migrate_vma_setup();
+   if (!(src_pfn & MIGRATE_PFN_MIGRATE))
+   return NULL;
+
+   dpage = alloc_pages(GFP_USER | __GFP_NOWARN, 0);
+
+   /*
+* get/pin the new 

[PATCH v2 01/13] mm: add zone device coherent type memory support

2022-05-16 Thread Alex Sierra
Device memory that is cache coherent from device and CPU point of view.
This is used on platforms that have an advanced system bus (like CAPI
or CXL). Any page of a process can be migrated to such memory. However,
no one should be allowed to pin such memory so that it can always be
evicted.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Popple 
[hch: rebased ontop of the refcount changes,
  removed is_dev_private_or_coherent_page]
Signed-off-by: Christoph Hellwig 
---
 include/linux/memremap.h | 19 +++
 mm/memcontrol.c  |  7 ---
 mm/memory-failure.c  |  8 ++--
 mm/memremap.c| 10 ++
 mm/migrate_device.c  | 16 +++-
 mm/rmap.c|  5 +++--
 6 files changed, 49 insertions(+), 16 deletions(-)

diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index 8af304f6b504..9f752ebed613 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -41,6 +41,13 @@ struct vmem_altmap {
  * A more complete discussion of unaddressable memory may be found in
  * include/linux/hmm.h and Documentation/vm/hmm.rst.
  *
+ * MEMORY_DEVICE_COHERENT:
+ * Device memory that is cache coherent from device and CPU point of view. This
+ * is used on platforms that have an advanced system bus (like CAPI or CXL). A
+ * driver can hotplug the device memory using ZONE_DEVICE and with that memory
+ * type. Any page of a process can be migrated to such memory. However no one
+ * should be allowed to pin such memory so that it can always be evicted.
+ *
  * MEMORY_DEVICE_FS_DAX:
  * Host memory that has similar access semantics as System RAM i.e. DMA
  * coherent and supports page pinning. In support of coordinating page
@@ -61,6 +68,7 @@ struct vmem_altmap {
 enum memory_type {
/* 0 is reserved to catch uninitialized type fields */
MEMORY_DEVICE_PRIVATE = 1,
+   MEMORY_DEVICE_COHERENT,
MEMORY_DEVICE_FS_DAX,
MEMORY_DEVICE_GENERIC,
MEMORY_DEVICE_PCI_P2PDMA,
@@ -143,6 +151,17 @@ static inline bool folio_is_device_private(const struct 
folio *folio)
return is_device_private_page(>page);
 }
 
+static inline bool is_device_coherent_page(const struct page *page)
+{
+   return is_zone_device_page(page) &&
+   page->pgmap->type == MEMORY_DEVICE_COHERENT;
+}
+
+static inline bool folio_is_device_coherent(const struct folio *folio)
+{
+   return is_device_coherent_page(>page);
+}
+
 static inline bool is_pci_p2pdma_page(const struct page *page)
 {
return IS_ENABLED(CONFIG_PCI_P2PDMA) &&
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 598fece89e2b..3e1f97c9fdc6 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -5629,8 +5629,8 @@ static int mem_cgroup_move_account(struct page *page,
  *   2(MC_TARGET_SWAP): if the swap entry corresponding to this pte is a
  * target for charge migration. if @target is not NULL, the entry is stored
  * in target->ent.
- *   3(MC_TARGET_DEVICE): like MC_TARGET_PAGE  but page is 
MEMORY_DEVICE_PRIVATE
- * (so ZONE_DEVICE page and thus not on the lru).
+ *   3(MC_TARGET_DEVICE): like MC_TARGET_PAGE  but page is device memory and
+ *   thus not on the lru.
  * For now we such page is charge like a regular page would be as for all
  * intent and purposes it is just special memory taking the place of a
  * regular page.
@@ -5664,7 +5664,8 @@ static enum mc_target_type get_mctgt_type(struct 
vm_area_struct *vma,
 */
if (page_memcg(page) == mc.from) {
ret = MC_TARGET_PAGE;
-   if (is_device_private_page(page))
+   if (is_device_private_page(page) ||
+   is_device_coherent_page(page))
ret = MC_TARGET_DEVICE;
if (target)
target->page = page;
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index d4a4adcca01f..c8a0e9fcdf42 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -1695,12 +1695,16 @@ static int memory_failure_dev_pagemap(unsigned long 
pfn, int flags,
goto unlock;
}
 
-   if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
+   switch (pgmap->type) {
+   case MEMORY_DEVICE_PRIVATE:
+   case MEMORY_DEVICE_COHERENT:
/*
-* TODO: Handle HMM pages which may need coordination
+* TODO: Handle device pages which may need coordination
 * with device-side memory.
 */
goto unlock;
+   default:
+   break;
}
 
/*
diff --git a/mm/memremap.c b/mm/memremap.c
index af0223605e69..471ec84ed82b 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -314,6 +314,16 @@ void *memremap_pages(struct dev_pagemap *pgmap, int nid)
return ERR_PTR(-EINVAL);
}
break;
+   case 

[PATCH v2 02/13] mm: add device coherent vma selection for memory migration

2022-05-16 Thread Alex Sierra
This case is used to migrate pages from device memory, back to system
memory. Device coherent type memory is cache coherent from device and CPU
point of view.

Signed-off-by: Alex Sierra 
Acked-by: Felix Kuehling 
Reviewed-by: Alistair Poppple 
Signed-off-by: Christoph Hellwig 
---
 include/linux/migrate.h |  1 +
 mm/migrate_device.c | 12 +---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 90e75d5a54d6..a4a336fd81fc 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -138,6 +138,7 @@ static inline unsigned long migrate_pfn(unsigned long pfn)
 enum migrate_vma_direction {
MIGRATE_VMA_SELECT_SYSTEM = 1 << 0,
MIGRATE_VMA_SELECT_DEVICE_PRIVATE = 1 << 1,
+   MIGRATE_VMA_SELECT_DEVICE_COHERENT = 1 << 2,
 };
 
 struct migrate_vma {
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index 7e267142ea34..a0b997935cf9 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -148,15 +148,21 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
if (is_writable_device_private_entry(entry))
mpfn |= MIGRATE_PFN_WRITE;
} else {
-   if (!(migrate->flags & MIGRATE_VMA_SELECT_SYSTEM))
-   goto next;
pfn = pte_pfn(pte);
-   if (is_zero_pfn(pfn)) {
+   if (is_zero_pfn(pfn) &&
+   (migrate->flags & MIGRATE_VMA_SELECT_SYSTEM)) {
mpfn = MIGRATE_PFN_MIGRATE;
migrate->cpages++;
goto next;
}
page = vm_normal_page(migrate->vma, addr, pte);
+   if (page && !is_zone_device_page(page) &&
+   !(migrate->flags & MIGRATE_VMA_SELECT_SYSTEM))
+   goto next;
+   else if (page && is_device_coherent_page(page) &&
+   (!(migrate->flags & 
MIGRATE_VMA_SELECT_DEVICE_COHERENT) ||
+page->pgmap->owner != migrate->pgmap_owner))
+   goto next;
mpfn = migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE;
mpfn |= pte_write(pte) ? MIGRATE_PFN_WRITE : 0;
}
-- 
2.32.0



[PATCH v2 00/13] Add MEMORY_DEVICE_COHERENT for coherent device memory mapping

2022-05-16 Thread Alex Sierra
This is our MEMORY_DEVICE_COHERENT patch series rebased and updated
for current 5.18-rc7.

Changes since the last version:
- Fixed problems with migration during long-term pinning in
get_user_pages
- Open coded vm_normal_lru_pages as suggested in previous code review
- Update hmm_gup_test with more get_user_pages calls, include
hmm_cow_in_device in hmm-test.

This patch series introduces MEMORY_DEVICE_COHERENT, a type of memory
owned by a device that can be mapped into CPU page tables like
MEMORY_DEVICE_GENERIC and can also be migrated like
MEMORY_DEVICE_PRIVATE.

This patch series is mostly self-contained except for a few places where
it needs to update other subsystems to handle the new memory type.

System stability and performance are not affected according to our
ongoing testing, including xfstests.

How it works: The system BIOS advertises the GPU device memory
(aka VRAM) as SPM (special purpose memory) in the UEFI system address
map.

The amdgpu driver registers the memory with devmap as
MEMORY_DEVICE_COHERENT using devm_memremap_pages. The initial user for
this hardware page migration capability is the Frontier supercomputer
project. This functionality is not AMD-specific. We expect other GPU
vendors to find this functionality useful, and possibly other hardware
types in the future.

Our test nodes in the lab are similar to the Frontier configuration,
with .5 TB of system memory plus 256 GB of device memory split across
4 GPUs, all in a single coherent address space. Page migration is
expected to improve application efficiency significantly. We will
report empirical results as they become available.

Coherent device type pages at gup are now migrated back to system
memory if they are being pinned long-term (FOLL_LONGTERM). The reason
is, that long-term pinning would interfere with the device memory
manager owning the device-coherent pages (e.g. evictions in TTM).
These series incorporate Alistair Popple patches to do this
migration from pin_user_pages() calls. hmm_gup_test has been added to
hmm-test to test different get user pages calls.

This series includes handling of device-managed anonymous pages
returned by vm_normal_pages. Although they behave like normal pages
for purposes of mapping in CPU page tables and for COW, they do not
support LRU lists, NUMA migration or THP.

We also introduced a FOLL_LRU flag that adds the same behaviour to
follow_page and related APIs, to allow callers to specify that they
expect to put pages on an LRU list.

v2:
- Rebase to latest 5.18-rc7.
- Drop patch "mm: add device coherent checker to remove migration pte"
and modify try_to_migrate_one, to let DEVICE_COHERENT pages fall
through to normal page path. Based on Alistair Popple's comment.
- Fix comment formatting.
- Reword comment in vm_normal_page about pte_devmap().
- Merge "drm/amdkfd: coherent type as sys mem on migration to ram" to
"drm/amdkfd: add SPM support for SVM".

Alex Sierra (11):
  mm: add zone device coherent type memory support
  mm: add device coherent vma selection for memory migration
  drm/amdkfd: add SPM support for SVM
  lib: test_hmm add ioctl to get zone device type
  lib: test_hmm add module param for zone device type
  lib: add support for device coherent type in test_hmm
  tools: update hmm-test to support device coherent type
  tools: update test_hmm script to support SP config
  mm: handling Non-LRU pages returned by vm_normal_pages
  tools: add hmm gup tests for device coherent type
  tools: add selftests to hmm for COW in device memory

Alistair Popple (2):
  mm: remove the vma check in migrate_vma_setup()
  mm/gup: migrate device coherent pages when pinning instead of failing

 drivers/gpu/drm/amd/amdkfd/kfd_migrate.c |  33 ++-
 fs/proc/task_mmu.c   |   2 +-
 include/linux/memremap.h |  19 ++
 include/linux/migrate.h  |   1 +
 include/linux/mm.h   |   3 +-
 lib/test_hmm.c   | 349 +--
 lib/test_hmm_uapi.h  |  22 +-
 mm/gup.c |  49 +++-
 mm/huge_memory.c |   2 +-
 mm/internal.h|   1 +
 mm/khugepaged.c  |   9 +-
 mm/ksm.c |   6 +-
 mm/madvise.c |   4 +-
 mm/memcontrol.c  |   7 +-
 mm/memory-failure.c  |   8 +-
 mm/memory.c  |   9 +-
 mm/mempolicy.c   |   2 +-
 mm/memremap.c|  10 +
 mm/migrate.c |   4 +-
 mm/migrate_device.c  | 115 ++--
 mm/mlock.c   |   2 +-
 mm/mprotect.c|   2 +-
 mm/rmap.c|   5 +-
 tools/testing/selftests/vm/hmm-tests.c   | 308 ++--
 tools/testing/selftests/vm/test_hmm.sh   |  24 +-
 25 

[PATCH v2 27/27] dyndbg/drm: POC add tracebits sysfs-knob

2022-05-16 Thread Jim Cromie
clone DRM.debug interface to DRM.tracebits: ie map bits to
drm-debug-categories, except this interface enables messages to
tracefs, not to syslog.

This reuses dyndbg's register-classes API to add the new sysfs-knob:

drm_drv.h:

[A] 2nd use of DYNAMIC_DEBUG_CLASSES(drm_trace_classes), which
declares and initializes a known-classes map with the same literal
classnames as in the 1st use.  This "shares" the classnames for both
sysfs-knobs, which is necessary because they're manipulating a shared
dyndbg callsite, toggling "p" and "T" flags respectively.

This incurs a tiny waste of constant strings, but its worth it for the
simpler declarative macro.

drm_print.c:

1- declare and export a 2nd bit-vector: __drm_trace, like __drm_debug

2- declare and init a struct ddebug_classes_bitmap_param with:
   __drm_trace [1], drm_trace_classes [A].

3- module_param_cb([2]) - does the sysfs part

drm_drv.c:

register and unregister [A], and missed unregister on drm_debug_classes.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_drv.c   |  3 +++
 drivers/gpu/drm/drm_print.c | 10 ++
 include/drm/drm_drv.h   | 14 +-
 3 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 16683fb169aa..ad141c5e29ca 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -1039,6 +1039,8 @@ static void drm_core_exit(void)
drm_sysfs_destroy();
idr_destroy(_minors_idr);
drm_connector_ida_destroy();
+   dynamic_debug_unregister_classes(_debug_classes);
+   dynamic_debug_unregister_classes(_trace_classes);
 }
 
 static int __init drm_core_init(void)
@@ -1046,6 +1048,7 @@ static int __init drm_core_init(void)
int ret;
 
dynamic_debug_register_classes(_debug_classes);
+   dynamic_debug_register_classes(_trace_classes);
 
drm_connector_ida_init();
idr_init(_minors_idr);
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 9afb676bda4d..970b6dd46c42 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -44,6 +44,9 @@
 unsigned long __drm_debug;
 EXPORT_SYMBOL(__drm_debug);
 
+unsigned long __drm_trace;
+EXPORT_SYMBOL(__drm_trace);
+
 MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug 
category.\n"
 "\t\tBit 0 (0x01)  will enable CORE messages (drm core code)\n"
 "\t\tBit 1 (0x02)  will enable DRIVER messages (drm controller code)\n"
@@ -63,6 +66,13 @@ static struct ddebug_classes_bitmap_param drm_debug_bitmap = 
{
.map = _debug_classes,
 };
 module_param_cb(debug, _ops_dyndbg_classes, _debug_bitmap, 0600);
+
+static struct ddebug_classes_bitmap_param drm_trace_bitmap = {
+   .bits = &__drm_trace,
+   .flags = "T",
+   .map = _trace_classes,
+};
+module_param_cb(tracecats, _ops_dyndbg_classes, _trace_bitmap, 0600);
 #endif
 
 void __drm_puts_coredump(struct drm_printer *p, const char *str)
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index c2ffe12161b8..596de0addfd5 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -45,7 +45,19 @@ struct drm_printer;
 struct sg_table;
 
 /* these must comport with enum drm_debug_category values */
-DYNAMIC_DEBUG_CLASSES(drm_debug_classes, "*", 0,
+DYNAMIC_DEBUG_CLASSES(drm_debug_classes, 0,
+ "DRM_UT_CORE",
+ "DRM_UT_DRIVER",
+ "DRM_UT_KMS",
+ "DRM_UT_PRIME",
+ "DRM_UT_ATOMIC",
+ "DRM_UT_VBL",
+ "DRM_UT_STATE",
+ "DRM_UT_LEASE",
+ "DRM_UT_DP",
+ "DRM_UT_DRMRES");
+
+DYNAMIC_DEBUG_CLASSES(drm_trace_classes, 0,
  "DRM_UT_CORE",
  "DRM_UT_DRIVER",
  "DRM_UT_KMS",
-- 
2.35.3



[PATCH v2 21/27] drm_print: prefer bare printk KERN_DEBUG on generic fn

2022-05-16 Thread Jim Cromie
drm_print.c calls pr_debug() just once, from __drm_printfn_debug(),
which is a generic/service fn.  The callsite is compile-time enabled
by DEBUG in both DYNAMIC_DEBUG=y/n builds.

For dyndbg builds, reverting this callsite back to bare printk is
correcting a few anti-features:

1- callsite is generic, serves multiple drm users.
   its hardwired on currently
   could accidentally: #> echo -p > /proc/dynamic_debug/control

2- optional "decorations" by dyndbg are unhelpful/misleading
   they describe only the generic site, not end users

IOW, 1,2 are unhelpful at best, and possibly confusing.

reverting yields a nominal data and text shrink:

   textdata bss dec hex filename
 462583   36604   54592 553779   87333 /kernel/drivers/gpu/drm/drm.ko
 462515   36532   54592 553639   872a7 -dirty/kernel/drivers/gpu/drm/drm.ko

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 22b7ab1c5c40..1b11a15366b7 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -23,8 +23,6 @@
  * Rob Clark 
  */
 
-#define DEBUG /* for pr_debug() */
-
 #include 
 
 #include 
@@ -172,7 +170,8 @@ EXPORT_SYMBOL(__drm_printfn_info);
 
 void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf)
 {
-   pr_debug("%s %pV", p->prefix, vaf);
+   /* pr_debug callsite decorations are unhelpful here */
+   printk(KERN_DEBUG "%s %pV", p->prefix, vaf);
 }
 EXPORT_SYMBOL(__drm_printfn_debug);
 
-- 
2.35.3



[PATCH v2 24/27] dyndbg: add _DPRINTK_FLAGS_TRACE

2022-05-16 Thread Jim Cromie
add new flag, and OR it into _DPRINTK_FLAGS_ENABLED definition

CC: vincent.whitchu...@axis.com
Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 0a81a3582281..7581fe79980a 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -42,7 +42,9 @@ struct _ddebug {
(_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\
 _DPRINTK_FLAGS_INCL_LINENO  | _DPRINTK_FLAGS_INCL_TID)
 
-#define _DPRINTK_FLAGS_ENABLED _DPRINTK_FLAGS_PRINTK
+#define _DPRINTK_FLAGS_TRACE   (1 << 5)
+#define _DPRINTK_FLAGS_ENABLED (_DPRINTK_FLAGS_PRINTK | \
+_DPRINTK_FLAGS_TRACE)
 
 #if defined DEBUG
 #define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINTK
-- 
2.35.3



[PATCH v2 22/27] drm_print: add _ddebug desc to drm_*dbg prototypes

2022-05-16 Thread Jim Cromie
Add a struct _ddebug ptr to drm_dbg() and drm_dev_dbg() protos, and
upgrade their callers - the interposed macros added recently, to use
_dynamic_func_call_no_desc(); ie drop the '_no_desc', since the
factory macro's callees (these 2 functions) are now expecting the arg.

This makes those functions controllable like pr_debug().  It also
means that they don't get to use the decorations implemented by
pr_debug().  DRM already has standards for logging/messaging; tossing
optional decorations on top may not help.

For CONFIG_DRM_USE_DYNAMIC_DEBUG=N, just pass null.

Note: desc->class_id is redundant with category parameter, but its
availability is dependent on desc.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c | 23 +--
 include/drm/drm_print.h | 22 +++---
 2 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 1b11a15366b7..1752b40b0189 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -265,8 +265,8 @@ void drm_dev_printk(const struct device *dev, const char 
*level,
 }
 EXPORT_SYMBOL(drm_dev_printk);
 
-void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
-  const char *format, ...)
+void __drm_dev_dbg(struct _ddebug *desc, const struct device *dev,
+  enum drm_debug_category category, const char *format, ...)
 {
struct va_format vaf;
va_list args;
@@ -274,22 +274,25 @@ void __drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
if (!__drm_debug_enabled(category))
return;
 
+   /* we know we are printing for either syslog, tracefs, or both */
va_start(args, format);
vaf.fmt = format;
vaf.va = 
 
-   if (dev)
-   dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
-  __builtin_return_address(0), );
-   else
-   printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
-  __builtin_return_address(0), );
-
+   if (dev) {
+   if (desc->flags && _DPRINTK_FLAGS_PRINT)
+   dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
+  __builtin_return_address(0), );
+   } else {
+   if (desc->flags && _DPRINTK_FLAGS_PRINT)
+   printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
+  __builtin_return_address(0), );
+   }
va_end(args);
 }
 EXPORT_SYMBOL(__drm_dev_dbg);
 
-void ___drm_dbg(enum drm_debug_category category, const char *format, ...)
+void ___drm_dbg(struct _ddebug *desc, enum drm_debug_category category, const 
char *format, ...)
 {
struct va_format vaf;
va_list args;
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index ccd177236ab3..fc0f2f6c2b91 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -366,9 +366,9 @@ static inline bool drm_debug_enabled(enum 
drm_debug_category category)
 __printf(3, 4)
 void drm_dev_printk(const struct device *dev, const char *level,
const char *format, ...);
-__printf(3, 4)
-void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
-const char *format, ...);
+__printf(4, 5)
+void __drm_dev_dbg(struct _ddebug *desc, const struct device *dev,
+  enum drm_debug_category category, const char *format, ...);
 
 /**
  * DRM_DEV_ERROR() - Error output.
@@ -418,11 +418,11 @@ void __drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
 
 #if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
 #define drm_dev_dbg(dev, cat, fmt, ...)\
-   __drm_dev_dbg(dev, cat, fmt, ##__VA_ARGS__)
+   __drm_dev_dbg(NULL, dev, cat, fmt, ##__VA_ARGS__)
 #else
 #define drm_dev_dbg(dev, cat, fmt, ...)\
-   _dynamic_func_call_no_desc(fmt, __drm_dev_dbg,  \
-  dev, cat, fmt, ##__VA_ARGS__)
+   _dynamic_func_call_cls(cat, fmt, __drm_dev_dbg, \
+  dev, cat, fmt, ##__VA_ARGS__)
 #endif
 
 /**
@@ -525,17 +525,17 @@ void __drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
  * Prefer drm_device based logging over device or prink based logging.
  */
 
-__printf(2, 3)
-void ___drm_dbg(enum drm_debug_category category, const char *format, ...);
+__printf(3, 4)
+void ___drm_dbg(struct _ddebug *desc, enum drm_debug_category category, const 
char *format, ...);
 __printf(1, 2)
 void __drm_err(const char *format, ...);
 
 #if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
-#define __drm_dbg(fmt, ...)___drm_dbg(fmt, ##__VA_ARGS__)
+#define __drm_dbg(fmt, ...)___drm_dbg(NULL, fmt, ##__VA_ARGS__)
 #else
 #define __drm_dbg(cat, fmt, ...)   \
-   

[PATCH v2 25/27] dyndbg: add write-events-to-tracefs code

2022-05-16 Thread Jim Cromie
adds: ddebug_trace()
 uses trace_console() temporarily to issue printk:console event
 uses internal-ish __ftrace_trace_stack code:
  4-context buffer stack, barriers per Steve Rostedt

call it from new funcs:
  ddebug_printk() - print to both syslog/tracefs
  ddebug_dev_printk() - dev-print to both syslog/tracefs

These handle both _DPRINTK_FLAGS_PRINTK and _DPRINTK_FLAGS_TRACE
cases, allowing to vsnprintf the message once and use it for both,
skipping past the KERN_DEBUG character for tracing.

Finally, adjust the callers: __ddebug_{pr_debug,{,net,ib}dev_dbg},
replacing printk and dev_printk with the new funcs above.

The _DPRINTK_FLAGS_TRACE flag character is 'T', so the following finds
all callsites enabled for tracing:

  grep -P =p?T /proc/dynamic_debug/control

This patch,~1,~2 are basically copies of:
  
https://lore.kernel.org/lkml/20200825153338.17061-1-vincent.whitchu...@axis.com/

with a few differences:

- s/dynamic_/ddebug_/ on Vincent's additions
- __printf attrs on the _printk funcs
- reuses trace_console() event, not adding a new "printk:dyndbg" event.
  next patch replaces this with 2 new events

CC: vincent.whitchu...@axis.com
Signed-off-by: Jim Cromie 
---
 .../admin-guide/dynamic-debug-howto.rst   |   1 +
 drivers/gpu/drm/drm_print.c   |   4 +-
 lib/dynamic_debug.c   | 156 +++---
 3 files changed, 133 insertions(+), 28 deletions(-)

diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst 
b/Documentation/admin-guide/dynamic-debug-howto.rst
index 01ca6f635dcc..b8c6772b88ac 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -239,6 +239,7 @@ of the characters::
 The flags are::
 
   penables the pr_debug() callsite.
+  Tenables callsite to issue a dyndbg:* trace-event
   fInclude the function name in the printed message
   lInclude line number in the printed message
   mInclude module name in the printed message
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 77b56399147a..63125a507577 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -280,11 +280,11 @@ void __drm_dev_dbg(struct _ddebug *desc, const struct 
device *dev,
vaf.va = 
 
if (dev) {
-   if (desc->flags && _DPRINTK_FLAGS_PRINTK)
+   if (desc->flags & _DPRINTK_FLAGS_PRINTK)
dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
   __builtin_return_address(0), );
} else {
-   if (desc->flags && _DPRINTK_FLAGS_PRINTK)
+   if (desc->flags & _DPRINTK_FLAGS_PRINTK)
printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
   __builtin_return_address(0), );
}
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 5682ee477677..81cfe6e21d15 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -88,6 +89,7 @@ static inline const char *trim_prefix(const char *path)
 
 static struct { unsigned flag:8; char opt_char; } opt_array[] = {
{ _DPRINTK_FLAGS_PRINTK, 'p' },
+   { _DPRINTK_FLAGS_TRACE, 'T' },
{ _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
{ _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
{ _DPRINTK_FLAGS_INCL_LINENO, 'l' },
@@ -770,6 +772,98 @@ static inline char *dynamic_emit_prefix(struct _ddebug 
*desc, char *buf)
return buf;
 }
 
+/*
+ * This code is heavily based on __ftrace_trace_stack().
+ *
+ * Allow 4 levels of nesting: normal, softirq, irq, NMI.
+ */
+#define DYNAMIC_TRACE_NESTING  4
+
+struct ddebug_trace_buf {
+   char buf[256];
+};
+
+struct ddebug_trace_bufs {
+   struct ddebug_trace_buf bufs[DYNAMIC_TRACE_NESTING];
+};
+
+static DEFINE_PER_CPU(struct ddebug_trace_bufs, ddebug_trace_bufs);
+static DEFINE_PER_CPU(int, ddebug_trace_reserve);
+
+static void ddebug_trace(const char *fmt, va_list args)
+{
+   struct ddebug_trace_buf *buf;
+   int bufidx;
+   int len;
+
+   preempt_disable_notrace();
+
+   bufidx = __this_cpu_inc_return(ddebug_trace_reserve) - 1;
+
+   if (WARN_ON_ONCE(bufidx > DYNAMIC_TRACE_NESTING))
+   goto out;
+
+   /* For the same reasons as in __ftrace_trace_stack(). */
+   barrier();
+
+   buf = this_cpu_ptr(ddebug_trace_bufs.bufs) + bufidx;
+
+   len = vscnprintf(buf->buf, sizeof(buf->buf), fmt, args);
+   trace_console(buf->buf, len);
+
+out:
+   /* As above. */
+   barrier();
+   __this_cpu_dec(ddebug_trace_reserve);
+   preempt_enable_notrace();
+}
+
+__printf(2, 3)
+static void ddebug_printk(unsigned int flags, const char *fmt, ...)
+{
+   if (flags & _DPRINTK_FLAGS_TRACE) {
+   va_list args;
+
+   va_start(args, fmt);
+   /*
+* All callers include the KERN_DEBUG prefix 

[PATCH v2 23/27] dyndbg: add _DPRINTK_FLAGS_ENABLED

2022-05-16 Thread Jim Cromie
Distinguish the condition: _DPRINTK_FLAGS_ENABLED from the bit:
_DPRINTK_FLAGS_PRINT (and define former as latter), in preparation to
add another bit next: _DPRINTK_FLAGS_TRACE

And change JUMP_LABEL code block to use the more general
_DPRINTK_FLAGS_ENABLED symbol.  Also add a 'K' to get new symbol
_DPRINTK_FLAGS_PRINTK, in order to break any stale uses.

CC: vincent.whitchu...@axis.com
Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c   |  4 ++--
 include/linux/dynamic_debug.h | 10 ++
 lib/dynamic_debug.c   |  8 
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 1752b40b0189..77b56399147a 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -280,11 +280,11 @@ void __drm_dev_dbg(struct _ddebug *desc, const struct 
device *dev,
vaf.va = 
 
if (dev) {
-   if (desc->flags && _DPRINTK_FLAGS_PRINT)
+   if (desc->flags && _DPRINTK_FLAGS_PRINTK)
dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
   __builtin_return_address(0), );
} else {
-   if (desc->flags && _DPRINTK_FLAGS_PRINT)
+   if (desc->flags && _DPRINTK_FLAGS_PRINTK)
printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
   __builtin_return_address(0), );
}
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index abf43e28d8d3..0a81a3582281 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -32,7 +32,7 @@ struct _ddebug {
 * writes commands to /dynamic_debug/control
 */
 #define _DPRINTK_FLAGS_NONE0
-#define _DPRINTK_FLAGS_PRINT   (1<<0) /* printk() a message using the format */
+#define _DPRINTK_FLAGS_PRINTK  (1 << 0) /* printk() a message using the format 
*/
 #define _DPRINTK_FLAGS_INCL_MODNAME(1<<1)
 #define _DPRINTK_FLAGS_INCL_FUNCNAME   (1<<2)
 #define _DPRINTK_FLAGS_INCL_LINENO (1<<3)
@@ -42,8 +42,10 @@ struct _ddebug {
(_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\
 _DPRINTK_FLAGS_INCL_LINENO  | _DPRINTK_FLAGS_INCL_TID)
 
+#define _DPRINTK_FLAGS_ENABLED _DPRINTK_FLAGS_PRINTK
+
 #if defined DEBUG
-#define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT
+#define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINTK
 #else
 #define _DPRINTK_FLAGS_DEFAULT 0
 #endif
@@ -161,10 +163,10 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 
 #ifdef DEBUG
 #define DYNAMIC_DEBUG_BRANCH(descriptor) \
-   likely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
+   likely(descriptor.flags & _DPRINTK_FLAGS_ENABLED)
 #else
 #define DYNAMIC_DEBUG_BRANCH(descriptor) \
-   unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
+   unlikely(descriptor.flags & _DPRINTK_FLAGS_ENABLED)
 #endif
 
 #endif /* CONFIG_JUMP_LABEL */
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index f9c5bbf9d43b..5682ee477677 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -87,7 +87,7 @@ static inline const char *trim_prefix(const char *path)
 }
 
 static struct { unsigned flag:8; char opt_char; } opt_array[] = {
-   { _DPRINTK_FLAGS_PRINT, 'p' },
+   { _DPRINTK_FLAGS_PRINTK, 'p' },
{ _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
{ _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
{ _DPRINTK_FLAGS_INCL_LINENO, 'l' },
@@ -238,10 +238,10 @@ static int ddebug_change(const struct ddebug_query *query,
if (newflags == dp->flags)
continue;
 #ifdef CONFIG_JUMP_LABEL
-   if (dp->flags & _DPRINTK_FLAGS_PRINT) {
-   if (!(newflags & _DPRINTK_FLAGS_PRINT))
+   if (dp->flags & _DPRINTK_FLAGS_ENABLED) {
+   if (!(newflags & _DPRINTK_FLAGS_ENABLED))

static_branch_disable(>key.dd_key_true);
-   } else if (newflags & _DPRINTK_FLAGS_PRINT) {
+   } else if (newflags & _DPRINTK_FLAGS_ENABLED) {
static_branch_enable(>key.dd_key_true);
}
 #endif
-- 
2.35.3



[PATCH v2 26/27] dyndbg: 4 new trace-events: pr_debug, dev_dbg, drm_{, dev}debug

2022-05-16 Thread Jim Cromie
ddebug_trace() currently issues a single printk:console event.
Replace that, adding include/trace/events/dyndbg.h, which defines 2
new events:

- dyndbg:prdbg  - from trace_prdbg()  - if !dev
- dyndbg:devdbg - from trace_devdbg() - if !!dev

This links the legacy pr_debug API to tracefs, via dyndbg, allowing
pr_debug()s etc to add just a little more user-context to the
trace-logs, and then at users option, less syslog.

The 2 new trace_*() calls accept their caller's args respectively,
keeping the available info w/o alteration; we can't improve on
transparency.  The args:

 1- struct _ddebug *descriptor, giving tracefs all of dyndbg's info.
 2- struct device *dev, used by trace_devdbg(), if !!dev

The trace_*() calls need the descriptor arg, the callchain prototypes
above them are extended to provide it.

The existing category param in this callchain is partially redundant;
when descriptor is available, it has the class_id.

dev_dbg(desc, dev...), if dev is true, issues a trace_devdbg(),
otherwise trace_prdbg().  This way we dont consume buffer space
storing nulls.  Otherwise the events are equivalent.

Also add include/trace/events/drm.h, to create 2 events for use in
drm_dbg() and drm_devdbg(), and call them.  This recapitulates the
changes described above, connecting 3-10K drm.debug callsites to
tracefs.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c   |  9 +
 include/trace/events/drm.h| 68 
 include/trace/events/dyndbg.h | 74 +++
 lib/dynamic_debug.c   | 73 +-
 4 files changed, 188 insertions(+), 36 deletions(-)
 create mode 100644 include/trace/events/drm.h
 create mode 100644 include/trace/events/dyndbg.h

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 63125a507577..9afb676bda4d 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -34,6 +34,9 @@
 #include 
 #include 
 
+#define CREATE_TRACE_POINTS
+#include 
+
 /*
  * __drm_debug: Enable debug output.
  * Bitmask of DRM_UT_x. See include/drm/drm_print.h for details.
@@ -283,10 +286,14 @@ void __drm_dev_dbg(struct _ddebug *desc, const struct 
device *dev,
if (desc->flags & _DPRINTK_FLAGS_PRINTK)
dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
   __builtin_return_address(0), );
+   if (desc->flags & _DPRINTK_FLAGS_TRACE)
+   trace_drm_devdbg(dev, category, );
} else {
if (desc->flags & _DPRINTK_FLAGS_PRINTK)
printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
   __builtin_return_address(0), );
+   if (desc->flags & _DPRINTK_FLAGS_TRACE)
+   trace_drm_debug(category, );
}
va_end(args);
 }
@@ -307,6 +314,8 @@ void ___drm_dbg(struct _ddebug *desc, enum 
drm_debug_category category, const ch
printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
   __builtin_return_address(0), );
 
+   trace_drm_debug(category, );
+
va_end(args);
 }
 EXPORT_SYMBOL(___drm_dbg);
diff --git a/include/trace/events/drm.h b/include/trace/events/drm.h
new file mode 100644
index ..6de80dd68620
--- /dev/null
+++ b/include/trace/events/drm.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM drm
+
+#if !defined(_TRACE_DRM_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_DRM_H
+
+#include 
+
+/* drm_debug() was called, pass its args */
+TRACE_EVENT(drm_debug,
+   TP_PROTO(int drm_debug_category, struct va_format *vaf),
+
+   TP_ARGS(drm_debug_category, vaf),
+
+   TP_STRUCT__entry(
+   __field(int, drm_debug_category)
+   __dynamic_array(char, msg, 256)
+   ),
+
+   TP_fast_assign(
+   int len;
+
+   __entry->drm_debug_category = drm_debug_category;
+   vsnprintf(__get_str(msg), 256, vaf->fmt, *vaf->va);
+
+   len = strlen(__get_str(msg));
+   if (len > 0 && (__get_str(msg)[len - 1] == '\n'))
+   len -= 1;
+   __get_str(msg)[len] = 0;
+   ),
+
+   TP_printk("%s", __get_str(msg))
+);
+
+/* drm_devdbg() was called, pass its args, preserving order */
+TRACE_EVENT(drm_devdbg,
+   TP_PROTO(const struct device *dev, int drm_debug_category, struct 
va_format *vaf),
+
+   TP_ARGS(dev, drm_debug_category, vaf),
+
+   TP_STRUCT__entry(
+   __field(const struct device*, dev)
+   __field(int, drm_debug_category)
+   __dynamic_array(char, msg, 256)
+   ),
+
+   TP_fast_assign(
+   int len;
+
+   __entry->drm_debug_category = drm_debug_category;
+   

[PATCH v2 20/27] drm_print: refine drm_debug_enabled for jump-label

2022-05-16 Thread Jim Cromie
In order to use dynamic-debug's jump-label optimization in drm-debug,
its clarifying to refine drm_debug_enabled into 3 uses:

1.   drm_debug_enabled - legacy, public
2. __drm_debug_enabled - optimized for dyndbg jump-label enablement.
3.  _drm_debug_enabled - pr_debug instrumented, observable

1. The legacy version always checks the bits.

2. is privileged, for use by __drm_dbg(), __drm_dev_dbg(), which do an
early return unless the category is enabled (free of call/NOOP side
effects).  For dyndbg builds, debug callsites are selectively
"pre-enabled", so __drm_debug_enabled() short-circuits to true there.
Remaining callers of 1 may be able to use 2, case by case.

3. is 1st wrapped in a macro, with a pr_debug, which reports each
usage in /proc/dynamic_debug/control, making it observable in the
logs.  The macro lets the pr_debug see the real caller, not an inline
function.

When plugged into 1, it identified ~10 remaining callers of the
function, leading to the follow-on cleanup patch, and would allow
activating the pr_debugs, estimating the callrate, and the potential
savings by using the wrapper macro.  It is unused ATM, but it fills
out the picture.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c |  4 ++--
 include/drm/drm_print.h | 28 
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 5192533794a2..22b7ab1c5c40 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -272,7 +272,7 @@ void __drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
struct va_format vaf;
va_list args;
 
-   if (!drm_debug_enabled(category))
+   if (!__drm_debug_enabled(category))
return;
 
va_start(args, format);
@@ -295,7 +295,7 @@ void ___drm_dbg(enum drm_debug_category category, const 
char *format, ...)
struct va_format vaf;
va_list args;
 
-   if (!drm_debug_enabled(category))
+   if (!__drm_debug_enabled(category))
return;
 
va_start(args, format);
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 5c39bacac2b3..ccd177236ab3 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -324,11 +324,39 @@ enum drm_debug_category {
DRM_UT_DRMRES
 };
 
+/*
+ * 3 name flavors of drm_debug_enabled:
+ *   drm_debug_enabled - public/legacy, always checks bits
+ *  _drm_debug_enabled - instrumented to observe call-rates, est overheads.
+ * __drm_debug_enabled - privileged - knows jump-label state, can short-circuit
+ */
 static inline bool drm_debug_enabled(enum drm_debug_category category)
 {
return unlikely(__drm_debug & BIT(category));
 }
 
+/*
+ * Wrap fn in macro, so that the pr_debug sees the actual caller, not
+ * the inline fn.  Using this name creates a callsite entry / control
+ * point in /proc/dynamic_debug/control.
+ */
+#define _drm_debug_enabled(category)   \
+   ({  \
+   pr_debug("todo: maybe avoid via dyndbg\n"); \
+   drm_debug_enabled(category);\
+   })
+
+#if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
+/*
+ * dyndbg is wrapping the drm.debug API, so as to avoid the runtime
+ * bit-test overheads of drm_debug_enabled() in those api calls.
+ * In this case, executed callsites are known enabled, so true.
+ */
+#define __drm_debug_enabled(category)  true
+#else
+#define __drm_debug_enabled(category)  drm_debug_enabled(category)
+#endif
+
 /*
  * struct device based logging
  *
-- 
2.35.3



[PATCH v2 18/27] drm_print: interpose drm_*dbg with forwarding macros

2022-05-16 Thread Jim Cromie
change drm_dev_dbg & drm_dbg to macros, which forward to the renamed
functions (with __ prefix added).

Those functions sit below the categorized layer of macros implementing
the DRM debug.category API, and implement most of it.  These are good
places to insert dynamic-debug jump-label mechanics, which will allow
DRM to avoid the runtime cost of drm_debug_enabled().

no functional changes.

memory cost baseline: (unchanged)
bash-5.1# drms_load
[9.220389] dyndbg:   1 debug prints in module drm
[9.224426] ACPI: bus type drm_connector registered
[9.302192] dyndbg:   2 debug prints in module ttm
[9.305033] dyndbg:   8 debug prints in module video
[9.627563] dyndbg: 127 debug prints in module i915
[9.721505] AMD-Vi: AMD IOMMUv2 functionality not available on this system - 
This is not a bug.
[   10.091345] dyndbg: 2196 debug prints in module amdgpu
[   10.106589] [drm] amdgpu kernel modesetting enabled.
[   10.107270] amdgpu: CRAT table not found
[   10.107926] amdgpu: Virtual CRAT table created for CPU
[   10.108398] amdgpu: Topology: Add CPU node
[   10.168507] dyndbg:   3 debug prints in module wmi
[   10.329587] dyndbg:   3 debug prints in module nouveau

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c | 10 +-
 include/drm/drm_print.h |  9 +++--
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index e49ffda0a47e..e77b49c7725b 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -266,8 +266,8 @@ void drm_dev_printk(const struct device *dev, const char 
*level,
 }
 EXPORT_SYMBOL(drm_dev_printk);
 
-void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
-const char *format, ...)
+void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
+  const char *format, ...)
 {
struct va_format vaf;
va_list args;
@@ -288,9 +288,9 @@ void drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
 
va_end(args);
 }
-EXPORT_SYMBOL(drm_dev_dbg);
+EXPORT_SYMBOL(__drm_dev_dbg);
 
-void __drm_dbg(enum drm_debug_category category, const char *format, ...)
+void ___drm_dbg(enum drm_debug_category category, const char *format, ...)
 {
struct va_format vaf;
va_list args;
@@ -307,7 +307,7 @@ void __drm_dbg(enum drm_debug_category category, const char 
*format, ...)
 
va_end(args);
 }
-EXPORT_SYMBOL(__drm_dbg);
+EXPORT_SYMBOL(___drm_dbg);
 
 void __drm_err(const char *format, ...)
 {
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index a157485bf573..383feb0d34fe 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -339,7 +339,7 @@ __printf(3, 4)
 void drm_dev_printk(const struct device *dev, const char *level,
const char *format, ...);
 __printf(3, 4)
-void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
+void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 const char *format, ...);
 
 /**
@@ -388,6 +388,9 @@ void drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
}   \
 })
 
+#define drm_dev_dbg(dev, cat, fmt, ...)\
+   __drm_dev_dbg(dev, cat, fmt, ##__VA_ARGS__)
+
 /**
  * DRM_DEV_DEBUG() - Debug output for generic drm code
  *
@@ -489,10 +492,12 @@ void drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
  */
 
 __printf(2, 3)
-void __drm_dbg(enum drm_debug_category category, const char *format, ...);
+void ___drm_dbg(enum drm_debug_category category, const char *format, ...);
 __printf(1, 2)
 void __drm_err(const char *format, ...);
 
+#define __drm_dbg(fmt, ...)___drm_dbg(fmt, ##__VA_ARGS__)
+
 /* Macros to make printk easier */
 
 #define _DRM_PRINTK(once, level, fmt, ...) \
-- 
2.35.3



[PATCH v2 17/27] drm_print: condense enum drm_debug_category

2022-05-16 Thread Jim Cromie
enum drm_debug_category has 10 categories, but is initialized with
bitmasks which require 10 bits of underlying storage.  By using
natural enumeration, and moving the BIT(cat) into drm_debug_enabled(),
the enum fits in 4 bits, allowing the category to be represented
directly in pr_debug callsites, via the ddebug.class_id field.

While this slightly pessimizes the bit-test in drm_debug_enabled(),
using dyndbg with JUMP_LABEL will avoid the function entirely.

NOTE: this change forecloses the possibility of doing:

  drm_dbg(DRM_UT_CORE|DRM_UT_KMS, "weird 2-cat experiment")

but thats already strongly implied by the use of the enum itself; its
not a normal enum if it can be 2 values simultaneously.

Signed-off-by: Jim Cromie 
---
 include/drm/drm_print.h | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 0597137bac75..a157485bf573 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -284,49 +284,49 @@ enum drm_debug_category {
 * @DRM_UT_CORE: Used in the generic drm code: drm_ioctl.c, drm_mm.c,
 * drm_memory.c, ...
 */
-   DRM_UT_CORE = 0x01,
+   DRM_UT_CORE,
/**
 * @DRM_UT_DRIVER: Used in the vendor specific part of the driver: i915,
 * radeon, ... macro.
 */
-   DRM_UT_DRIVER   = 0x02,
+   DRM_UT_DRIVER,
/**
 * @DRM_UT_KMS: Used in the modesetting code.
 */
-   DRM_UT_KMS  = 0x04,
+   DRM_UT_KMS,
/**
 * @DRM_UT_PRIME: Used in the prime code.
 */
-   DRM_UT_PRIME= 0x08,
+   DRM_UT_PRIME,
/**
 * @DRM_UT_ATOMIC: Used in the atomic code.
 */
-   DRM_UT_ATOMIC   = 0x10,
+   DRM_UT_ATOMIC,
/**
 * @DRM_UT_VBL: Used for verbose debug message in the vblank code.
 */
-   DRM_UT_VBL  = 0x20,
+   DRM_UT_VBL,
/**
 * @DRM_UT_STATE: Used for verbose atomic state debugging.
 */
-   DRM_UT_STATE= 0x40,
+   DRM_UT_STATE,
/**
 * @DRM_UT_LEASE: Used in the lease code.
 */
-   DRM_UT_LEASE= 0x80,
+   DRM_UT_LEASE,
/**
 * @DRM_UT_DP: Used in the DP code.
 */
-   DRM_UT_DP   = 0x100,
+   DRM_UT_DP,
/**
 * @DRM_UT_DRMRES: Used in the drm managed resources code.
 */
-   DRM_UT_DRMRES   = 0x200,
+   DRM_UT_DRMRES
 };
 
 static inline bool drm_debug_enabled(enum drm_debug_category category)
 {
-   return unlikely(__drm_debug & category);
+   return unlikely(__drm_debug & BIT(category));
 }
 
 /*
-- 
2.35.3



[PATCH v2 15/27] drm: POC drm on dyndbg - map class-names to drm_debug_category's

2022-05-16 Thread Jim Cromie
Invoke DYNAMIC_DEBUG_CLASSES from drm_drv.h.  This declares a
maybe-unused struct ddebug_known_classes_map var, initialized with:

. var: passed to dynamic_debug_register_classes()
. class-names: "DRM_UT_CORE", "DRM_UT_DRIVER", "DRM_UT_KMS", etc.
  These names map to .class_id's by their index, ie: 0-30.

Then in 4 test-case drm-drivers (drm, i915, amdgpu, nouveau); call
dynamic_debug_register_classes(var).  i915 also gets an adaptor func,
and calls it 1st in the array of initialization helpers, since early
logging might be valuable for diagnosing setup problems.

Since these modules all use the same class-names, they all will
respond together to class FOO changes:

  #> echo class DRM_UT_KMS +p > /proc/dynamic_debug/control

NOTES:

DRM uses enum drm_debug_category across modules and common core, so
our class-names => index map must apply across them too, hence
drm_drv.h invokes the macro once for everyone.

DRM's enum drm_debug_category values need to sync with the index of
their respective class-names here.  Then .class_id == category, and
dyndbg's class FOO mechanisms will work.  Once enum drm_debug_category
is naturalized (value inits dropped, yielding 0..N), then this
condition holds true:

 assert(!strcmp(classes[DRM_UT_KMS],"DRM_UT_KMS"));

Though DRM needs consistent categories across all modules, thats not
generally needed; modules X and Y could define FOO differently (ie
different corresponding .class_id) and things would work.

No callsites are actually selected here, since none are class'd yet.

bash-5.1# dmesg | grep register_class
[7.095579] dyndbg: register_classes: drm
[7.557109] dyndbg: register_classes: i915
[8.096818] dyndbg: register_classes: amdgpu

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  3 +++
 drivers/gpu/drm/drm_drv.c   |  2 ++
 drivers/gpu/drm/i915/i915_module.c  | 11 +++
 drivers/gpu/drm/nouveau/nouveau_drm.c   |  4 
 include/drm/drm_drv.h   | 14 ++
 include/drm/drm_print.h |  4 
 6 files changed, 38 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 7fd0277b2805..addb991b4663 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2765,6 +2765,8 @@ static int __init amdgpu_init(void)
if (r)
goto error_fence;
 
+   dynamic_debug_register_classes(_debug_classes);
+
DRM_INFO("amdgpu kernel modesetting enabled.\n");
amdgpu_register_atpx_handler();
amdgpu_acpi_detect();
@@ -2787,6 +2789,7 @@ static void __exit amdgpu_exit(void)
amdgpu_amdkfd_fini();
pci_unregister_driver(_kms_pci_driver);
amdgpu_unregister_atpx_handler();
+   dynamic_debug_unregister_classes(_debug_classes);
amdgpu_sync_fini();
amdgpu_fence_slab_fini();
mmu_notifier_synchronize();
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 8214a0b1ab7f..16683fb169aa 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -1045,6 +1045,8 @@ static int __init drm_core_init(void)
 {
int ret;
 
+   dynamic_debug_register_classes(_debug_classes);
+
drm_connector_ida_init();
idr_init(_minors_idr);
drm_memcpy_init_early();
diff --git a/drivers/gpu/drm/i915/i915_module.c 
b/drivers/gpu/drm/i915/i915_module.c
index 65acd7bf75d0..31f00f973866 100644
--- a/drivers/gpu/drm/i915/i915_module.c
+++ b/drivers/gpu/drm/i915/i915_module.c
@@ -44,10 +44,21 @@ static int i915_check_nomodeset(void)
return 0;
 }
 
+static int i915_ddebug_classes_register(void)
+{
+   return dynamic_debug_register_classes(_debug_classes);
+}
+static void i915_ddebug_classes_unregister(void)
+{
+   dynamic_debug_unregister_classes(_debug_classes);
+}
+
 static const struct {
int (*init)(void);
void (*exit)(void);
 } init_funcs[] = {
+   { .init = i915_ddebug_classes_register,
+ .exit = i915_ddebug_classes_unregister },
{ .init = i915_check_nomodeset },
{ .init = i915_active_module_init,
  .exit = i915_active_module_exit },
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c 
b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 561309d447e0..9a780b6d4796 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -1355,6 +1355,8 @@ nouveau_drm_init(void)
driver_pci = driver_stub;
driver_platform = driver_stub;
 
+   dynamic_debug_register_classes(_debug_classes);
+
nouveau_display_options();
 
if (nouveau_modeset == -1) {
@@ -1391,6 +1393,8 @@ nouveau_drm_exit(void)
nouveau_backlight_dtor();
nouveau_unregister_dsm_handler();
 
+   dynamic_debug_unregister_classes(_debug_classes);
+
 #ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER
platform_driver_unregister(_platform_driver);
 #endif
diff --git 

[PATCH v2 19/27] drm_print: wrap drm_*_dbg in dyndbg descriptor factory macro

2022-05-16 Thread Jim Cromie
For CONFIG_DRM_USE_DYNAMIC_DEBUG=y, wrap __drm_dbg() & __drm_dev_dbg()
in one of dyndbg's Factory macros: _dynamic_func_call_no_desc().

Next, those functions are adapted to accept a descriptor arg, and we
drop the _no_desc suffix, then the (~4000) drm.debug callsites will be
controllable by their class-names:

  #> echo class DRM_UT_ATOMIC +p > /proc/dynamic_debug/control

CONFIG_DRM_USE_DYNAMIC_DEBUG=y/n is configurable because of the .data
footprint cost of per-callsite control; 56 bytes/site * ~2k for i915,
~4k callsites for amdgpu.  This is large enough that a kernel builder
might not want it.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/Kconfig | 12 
 drivers/gpu/drm/Makefile|  2 ++
 drivers/gpu/drm/drm_print.c |  2 +-
 include/drm/drm_print.h | 12 
 4 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index f1422bee3dcc..5ab31753c25d 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -63,6 +63,18 @@ config DRM_DEBUG_MM
 
  If in doubt, say "N".
 
+config DRM_USE_DYNAMIC_DEBUG
+   bool "use dynamic debug to implement drm.debug"
+   default y
+   depends on DRM
+   depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE
+   depends on JUMP_LABEL
+   help
+ Use dynamic-debug to avoid drm_debug_enabled() runtime overheads.
+ Due to callsite counts in DRM drivers (~4k in amdgpu) and 56
+ bytes per callsite, the .data costs can be substantial, and
+ are therefore configurable.
+
 config DRM_DEBUG_SELFTEST
tristate "kselftests for DRM"
depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index c2ef5f9fce54..e93b7902994a 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -3,6 +3,8 @@
 # Makefile for the drm device driver.  This driver provides support for the
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
+CFLAGS-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += -DDYNAMIC_DEBUG_MODULE
+
 drm-y   := drm_aperture.o drm_auth.o drm_cache.o \
drm_file.o drm_gem.o drm_ioctl.o \
drm_drv.o \
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index e77b49c7725b..5192533794a2 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -53,7 +53,7 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit 
enables a debug cat
 "\t\tBit 7 (0x80)  will enable LEASE messages (leasing code)\n"
 "\t\tBit 8 (0x100) will enable DP messages (displayport code)");
 
-#if !defined(CONFIG_DYNAMIC_DEBUG_CORE)
+#if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
 module_param_named(debug, __drm_debug, ulong, 0600);
 #else
 static struct ddebug_classes_bitmap_param drm_debug_bitmap = {
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 383feb0d34fe..5c39bacac2b3 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -388,8 +388,14 @@ void __drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
}   \
 })
 
+#if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
 #define drm_dev_dbg(dev, cat, fmt, ...)\
__drm_dev_dbg(dev, cat, fmt, ##__VA_ARGS__)
+#else
+#define drm_dev_dbg(dev, cat, fmt, ...)\
+   _dynamic_func_call_no_desc(fmt, __drm_dev_dbg,  \
+  dev, cat, fmt, ##__VA_ARGS__)
+#endif
 
 /**
  * DRM_DEV_DEBUG() - Debug output for generic drm code
@@ -496,7 +502,13 @@ void ___drm_dbg(enum drm_debug_category category, const 
char *format, ...);
 __printf(1, 2)
 void __drm_err(const char *format, ...);
 
+#if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
 #define __drm_dbg(fmt, ...)___drm_dbg(fmt, ##__VA_ARGS__)
+#else
+#define __drm_dbg(cat, fmt, ...)   \
+   _dynamic_func_call_no_desc(fmt, ___drm_dbg, \
+  cat, fmt, ##__VA_ARGS__)
+#endif
 
 /* Macros to make printk easier */
 
-- 
2.35.3



[PATCH v2 16/27] drm/print: POC drm on dyndbg - use bitmap

2022-05-16 Thread Jim Cromie
POC: adapt drm_print to use/test the bitmap callback support.

with dynamic_debug.verbose=1:

bash-5.1# echo 1 > /sys/module/drm/parameters/debug
[   33.697039] dyndbg: set_dyndbg_classes: new 0x1 current 0x0
[   33.697571] dyndbg: query 0: "class DRM_UT_CORE +p" mod:*
[   33.698072] dyndbg: no matches for query
[   33.698498] dyndbg: total matches: 0
bash-5.1# echo 2 > /sys/module/drm/parameters/debug
[   46.687012] dyndbg: set_dyndbg_classes: new 0x2 current 0x1
[   46.687655] dyndbg: query 0: "class DRM_UT_CORE -p" mod:*
[   46.688280] dyndbg: no matches for query
[   46.688632] dyndbg: query 0: "class DRM_UT_DRIVER +p" mod:*
[   46.689122] dyndbg: no matches for query
[   46.689441] dyndbg: total matches: 0

This changes typeof __drm_debug to unsigned long from unsigned int,
which dyndbg requires so it can use BIT().

It is currently dependent on CONFIG_DYNAMIC_DEBUG_CORE, which is only
aproximately correct, it will need proper DRM dependence too.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c | 14 --
 include/drm/drm_print.h |  3 ++-
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index f783d4963d4b..e49ffda0a47e 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -40,7 +40,7 @@
  * __drm_debug: Enable debug output.
  * Bitmask of DRM_UT_x. See include/drm/drm_print.h for details.
  */
-unsigned int __drm_debug;
+unsigned long __drm_debug;
 EXPORT_SYMBOL(__drm_debug);
 
 MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug 
category.\n"
@@ -52,7 +52,17 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit 
enables a debug cat
 "\t\tBit 5 (0x20)  will enable VBL messages (vblank code)\n"
 "\t\tBit 7 (0x80)  will enable LEASE messages (leasing code)\n"
 "\t\tBit 8 (0x100) will enable DP messages (displayport code)");
-module_param_named(debug, __drm_debug, int, 0600);
+
+#if !defined(CONFIG_DYNAMIC_DEBUG_CORE)
+module_param_named(debug, __drm_debug, ulong, 0600);
+#else
+static struct ddebug_classes_bitmap_param drm_debug_bitmap = {
+   .bits = &__drm_debug,
+   .flags = "p",
+   .map = _debug_classes,
+};
+module_param_cb(debug, _ops_dyndbg_classes, _debug_bitmap, 0600);
+#endif
 
 void __drm_puts_coredump(struct drm_printer *p, const char *str)
 {
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 5b7eedb0f477..0597137bac75 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -31,11 +31,12 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
 /* Do *not* use outside of drm_print.[ch]! */
-extern unsigned int __drm_debug;
+extern unsigned long __drm_debug;
 
 /**
  * DOC: print
-- 
2.35.3



[PATCH v2 14/27] dyndbg: add test_dynamic_debug module

2022-05-16 Thread Jim Cromie
Demonstrate dyndbg's "class FOO" and bitmap-to-classes support.  This
support is meant to plug into drm.debug system, and largely replace
the use of drm_debug_enabled(category) with JUMP_LABELs.

Recap:
  #> echo class DRM_UT_CORE +p > /proc/dynamic_debug/control

This is made "safe" because dyndbg skips it for any modules which
don't know that class (havent called dynamic_debug_register_classes).

Other modules may use the same .class_id for a separate classified
debug scheme.

Use the API:

- DYNAMIC_DEBUG_CLASSES(_var, classes), to declare static _var by name
- dynamic_debug_register_classes(_var)
- dynamic_debug_unregister_classes(_var)

Use these 3 times; with base = 0,8,16 respectively, to demonstrate the
segmenting of the module's .class_id range [0..30]

For each of those 3 class-name-sets, add 2 sysfs-node-bitmaps, one
each for p-syslog, and T-tracefs, the latter will work once dyndbg
gets that patchset.

  #> modprobe test_dynamic_debug dyndbg=+pfm
  #> cat /sys/module/test_dynamic_debug/parameters/do_prints
  #> echo class FOO +pf  > /proc/dynamic_debug/control
  #> echo class Foo +pfm > /proc/dynamic_debug/control
  #> cat /sys/module/test_dynamic_debug/parameters/do_prints

RFC:

This use case exposes a weak point in the api; the 2nd query command
given in the dyndbg option will not work like the 1st:

  #> modprobe test_dynamic_debug dyndbg='+pfm; class FOO +pfm'

This is because the option is processed early in module-load, well
before the registration can attach the class-map to the module's
ddebug_table entry.

Signed-off-by: Jim Cromie 
---
 MAINTAINERS  |   1 +
 lib/Kconfig.debug|  11 +++
 lib/Makefile |   1 +
 lib/test_dynamic_debug.c | 172 +++
 4 files changed, 185 insertions(+)
 create mode 100644 lib/test_dynamic_debug.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e8c52d0192a6..bf615853be47 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6918,6 +6918,7 @@ M:Jason Baron 
 S: Maintained
 F: include/linux/dynamic_debug.h
 F: lib/dynamic_debug.c
+F: lib/test_dynamic_debug.c
 
 DYNAMIC INTERRUPT MODERATION
 M: Tal Gilboa 
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 075cd25363ac..c88d691d3df1 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2601,6 +2601,17 @@ config TEST_STATIC_KEYS
 
  If unsure, say N.
 
+config TEST_DYNAMIC_DEBUG
+   tristate "Test DYNAMIC_DEBUG"
+   depends on m
+   depends on DYNAMIC_DEBUG
+   help
+ This module registers a tracer callback to count enabled
+ pr_debugs in a 'do_debugging' function, then alters their
+ enablements, calls the function, and compares counts.
+
+ If unsure, say N.
+
 config TEST_KMOD
tristate "kmod stress tester"
depends on m
diff --git a/lib/Makefile b/lib/Makefile
index 6b9ffc1bd1ee..e5727fbbfc7d 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_TEST_SORT) += test_sort.o
 obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o
 obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o
 obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o
+obj-$(CONFIG_TEST_DYNAMIC_DEBUG) += test_dynamic_debug.o
 obj-$(CONFIG_TEST_PRINTF) += test_printf.o
 obj-$(CONFIG_TEST_SCANF) += test_scanf.o
 obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o
diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
new file mode 100644
index ..65c37ba6c0da
--- /dev/null
+++ b/lib/test_dynamic_debug.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Kernel module for testing dynamic_debug
+ *
+ * Authors:
+ *  Jim Cromie 
+ */
+
+#define pr_fmt(fmt) "test_dd: " fmt
+
+#include 
+
+static void do_prints(void); /* device under test */
+
+/* run tests by reading or writing sysfs node */
+
+int param_set_do_prints(const char *instr, const struct kernel_param *kp)
+{
+   do_prints();
+   return 0;
+}
+EXPORT_SYMBOL(param_set_do_prints);
+
+int param_get_do_prints(char *buffer, const struct kernel_param *kp)
+{
+   do_prints();
+   return scnprintf(buffer, PAGE_SIZE, "did do_prints\n");
+}
+EXPORT_SYMBOL(param_get_do_prints);
+
+const struct kernel_param_ops param_ops_do_prints = {
+   .set = param_set_do_prints,
+   .get = param_get_do_prints,
+};
+EXPORT_SYMBOL(param_ops_do_prints);
+
+module_param_cb(do_prints, _ops_do_prints, NULL, 0600);
+
+/*
+ * Declare 3 groups of classes, with different .class_id[] ranges,
+ * each with 2 sysfs-node bitmaps controlling p,T flags respectively
+ * for those named classes.  This example is rather more involved than
+ * anyone will likely use.
+
+ * The T-bitmap sysfs-node functionality will need a few patches which
+ * add trace-events to dyndbg.
+
+ * Rules:
+ * - enum symbols must match/correlate with class-name strings
+ * - base must equal enum's 1st value
+ */
+
+enum cat1 { FOO, BAR, BUZZ };
+DYNAMIC_DEBUG_CLASSES(ddt_classes1, 0,
+ "FOO", 

[PATCH v2 13/27] dyndbg: add __pr_debug_cls(class, fmt, ...)

2022-05-16 Thread Jim Cromie
For selftest purposes, add __pr_debug_cls(class, fmt, ...)

I didn't think we'd need to define this, since DRM effectively has it
already.  But test_dynamic_debug needs it in order to demonstrate all
the moving parts.

Note the __ prefix; its not intended for general use, and doesn't
include any builtin-constant checks that could pertain.  I'd prefer to
see a use-case where copying the drm.debug model isn't better.

Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index e9e6d0f503f3..abf43e28d8d3 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -216,6 +216,10 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
_DPRINTK_CLASS_DFLT,\
fmt, func, ##__VA_ARGS__)
 
+#define dynamic_pr_debug_cls(cls, fmt, ...)\
+   _dynamic_func_call_cls(cls, fmt, __dynamic_pr_debug,\
+  pr_fmt(fmt), ##__VA_ARGS__)
+
 #define dynamic_pr_debug(fmt, ...) \
_dynamic_func_call(fmt, __dynamic_pr_debug, \
   pr_fmt(fmt), ##__VA_ARGS__)
@@ -246,6 +250,9 @@ struct kernel_param;
 int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp);
 int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp);
 
+#define __pr_debug_cls(cls, fmt, ...)  \
+   dynamic_pr_debug_cls(cls, fmt, ##__VA_ARGS__)
+
 #else /* !CONFIG_DYNAMIC_DEBUG_CORE */
 
 #include 
-- 
2.35.3



[PATCH v2 12/27] dyndbg: change zero-or-one classes-map to maps list

2022-05-16 Thread Jim Cromie
Upgrade single classes-map to list of them:

This allows multiple DYNAMIC_DEBUG_CLASSES(class-map)s per module,
using _base to segment the 0..30 classid space.

alter struct ddebug table:
 replace .classes (a ) with maps (list-head)

dynamic_debug_register_classes(map) - adds new map to maps list.

dynamic_debug_unregister_classes(map) - deletes map after ID-check.

ddebug_validate_classname() - check all maps in list before failing.

ddebug_class_name() - which supports ```cat control``` now walks maps
list, finds the map whose sub-range of .class_id's spans the one in
the callsite, and returns that class-name.

Signed-off-by: Jim Cromie 
---
. split out validate_classnames()
. fold in fixes for multi class-maps
---
 lib/dynamic_debug.c | 76 +++--
 1 file changed, 52 insertions(+), 24 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 8e1b9159e881..f9c5bbf9d43b 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -43,10 +43,8 @@ extern struct _ddebug __start___dyndbg[];
 extern struct _ddebug __stop___dyndbg[];
 
 struct ddebug_table {
-   struct list_head link;
+   struct list_head link, maps;
const char *mod_name;
-   /* a module can have multiple class-sets eventually, but not yet */
-   struct ddebug_known_classes_map const *map;
unsigned int num_ddebugs;
struct _ddebug *ddebugs;
 };
@@ -149,28 +147,18 @@ static void vpr_info_dq(const struct ddebug_query *query, 
const char *msg)
 /* return <0 if class-name is unknown/invalid, 0..CLASS_DFLT otherwise */
 static int ddebug_validate_classname(struct ddebug_table *dt, const char 
*class_string)
 {
-   int query_class = -ENOENT;
+   struct ddebug_known_classes_map *map;
int idx;
 
if (!class_string)
-   /* all queries w/o class given work only on default class */
return _DPRINTK_CLASS_DFLT;
 
-   /*
-* XXX single list will need to be a for-list
-* so that modules can have 2 sets of class-decls
-*/
-   if (!dt->map)
-   return -ENOENT;
-
-   idx = match_string(dt->map->classes, dt->map->length, class_string);
-   if (idx < 0) {
-   v3pr_info("class: %s.%s unknown\n", dt->mod_name, class_string);
-   return -ENOENT;
+   list_for_each_entry(map, >maps, link) {
+   idx = match_string(map->classes, map->length, class_string);
+   if (idx >= 0)
+   return idx + map->base;
}
-   query_class = idx + dt->map->base;
-
-   return query_class;
+   return -ENOENT;
 }
 
 /*
@@ -1032,8 +1020,14 @@ static void *ddebug_proc_next(struct seq_file *m, void 
*p, loff_t *pos)
 
 static const char *ddebug_class_name(struct ddebug_iter *iter, struct _ddebug 
*dp)
 {
-   if (iter->table->map)
-   return iter->table->map->classes[dp->class_id];
+   struct ddebug_known_classes_map *map;
+
+   list_for_each_entry(map, >table->maps, link) {
+   if (dp->class_id < map->base ||
+   dp->class_id >= map->base + map->length)
+   continue;
+   return map->classes[dp->class_id - map->base];
+   }
return NULL;
 }
 
@@ -1124,6 +1118,7 @@ int dynamic_debug_register_classes(struct 
ddebug_known_classes_map *map)
struct ddebug_table *dt;
int rc = -ENOENT;
 
+   INIT_LIST_HEAD(>link);
mutex_lock(_lock);
 #ifdef CONFIG_MODULES
if (map->mod) {
@@ -1131,7 +1126,7 @@ int dynamic_debug_register_classes(struct 
ddebug_known_classes_map *map)
list_for_each_entry(dt, _tables, link) {
if (dt->mod_name == map->mod->name) {
rc = 0;
-   dt->map = map;
+   list_add(>link, >maps);
break;
}
}
@@ -1142,7 +1137,7 @@ int dynamic_debug_register_classes(struct 
ddebug_known_classes_map *map)
list_for_each_entry(dt, _tables, link) {
if (!strcmp(dt->mod_name, map->mod_name)) {
rc = 0;
-   dt->map = map;
+   list_add(>link, >maps);
break;
}
}
@@ -1159,8 +1154,38 @@ EXPORT_SYMBOL(dynamic_debug_register_classes);
 
 void dynamic_debug_unregister_classes(struct ddebug_known_classes_map *map)
 {
-   vpr_info("unregister_classes: %s\n", map->mod_name);
+   int rc = -ENOENT;
+
+   mutex_lock(_lock);
+#ifdef CONFIG_MODULES
+   if (map->mod) {
+   struct ddebug_known_classes_map *dmap;
+   struct ddebug_table *dt;
+
+   list_for_each_entry(dt, _tables, link) {
+   if (dt->mod_name != map->mod->name)
+   

[PATCH v2 10/27] dyndbg: let query-modname override defaulting modname

2022-05-16 Thread Jim Cromie
dyndbg's control-parser: ddebug_parse_query(), requires that search
terms: module, func, file, lineno, are not used 2x in a query; a thing
cannot be named both foo and bar (not even wildcards, no OR is
contemplated).

Amend the treatment of module; while still enforcing the 2x rule on
it, set the default module at end, if none was given in the query
itself, so the preset doesn't spoil the check.

Background:

ddebug_parse_query() got a modname arg to support boot-args with
compound queries, all with "module aMod" added by default.

  aMod.dyndbg="func foo +p; func bar +p"

With default module at end, this becomes possible; "module *" in the
query overrides the default "module aMod".

  aMod.dyndbg="module * class FOO +p"

This means aMod can modify (by explicit means) any FOO class'd
pr_debugs in other modules.  It is intended for use by DRM, which
generally would want sub-system wide coordination.

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

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index b67bf9efec07..42dce2e76014 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -425,10 +425,6 @@ static int ddebug_parse_query(char *words[], int nwords,
return -EINVAL;
}
 
-   if (modname)
-   /* support $modname.dyndbg= */
-   query->module = modname;
-
for (i = 0; i < nwords; i += 2) {
char *keyword = words[i];
char *arg = words[i+1];
@@ -471,6 +467,13 @@ static int ddebug_parse_query(char *words[], int nwords,
if (rc)
return rc;
}
+   if (!query->module && modname)
+   /*
+* support $modname.dyndbg=,
+* allowing query.module to override $modname
+*/
+   query->module = modname;
+
vpr_info_dq(query, "parsed");
return 0;
 }
-- 
2.35.3



[PATCH v2 11/27] dyndbg: support symbolic class-names in bitmap

2022-05-16 Thread Jim Cromie
Extend the sysfs-node bitmap support to accept class-names
registered by the module, allowing:

   #> echo DRM_UT_CORE,-DRM_UT_ATOMIC,+DRM_UT_KMS \
 > /sys/module/drm/parameters/debug

Do this in param_set_dyndbg_class_strings(), which is called from
param_set_dyndbg_classes() when the input string isn't a integer.

Signed-off-by: Jim Cromie 

---
. continue/skip on unknown class, so following symbols are processed.
. better loadable module handling, no more KP_MOD_NAME
. add do_callback_changes
---
 lib/dynamic_debug.c | 63 ++---
 1 file changed, 59 insertions(+), 4 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 42dce2e76014..8e1b9159e881 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -618,6 +618,61 @@ static int do_callback_changes(const struct 
ddebug_classes_bitmap_param *dcp,
return matches;
 }
 
+/* support for [+-] symbolic-name boolean list */
+static int param_set_dyndbg_class_strings(const char *instr, const struct 
kernel_param *kp)
+{
+   const struct ddebug_classes_bitmap_param *dcp = kp->arg;
+   unsigned long inbits;
+   int idx_rc, totct = 0;
+   bool wanted;
+   char *cls, *p;
+
+   if (!dcp || !dcp->map) {
+   pr_err("set_dyndbg_classes: no bits=>queries map\n");
+   return -EINVAL;
+   }
+
+   cls = kstrdup(instr, GFP_KERNEL);
+   p = strchr(cls, '\n');
+   if (p)
+   *p = '\0';
+
+   inbits = *dcp->bits;
+   vpr_info("set_dyndbg_class_strings: %s on 0x%lx\n", cls, inbits);
+
+   for (; cls; cls = p) {
+   p = strchr(cls, ',');
+   if (p)
+   *p++ = '\0';
+
+   if (*cls == '-') {
+   wanted = false;
+   cls++;
+   } else {
+   wanted = true;
+   if (*cls == '+')
+   cls++;
+   }
+   idx_rc = match_string(dcp->map->classes, dcp->map->length, cls);
+   if (idx_rc < 0) {
+   pr_err("%s not found for module: %s\n", cls, 
dcp->map->mod_name);
+   continue;
+   }
+   if (test_bit(idx_rc, ) == wanted) {
+   v3pr_info("no change on %s\n", cls);
+   continue;
+   }
+
+   vpr_info("set_dyndbg_classes: bit %d: %s\n", idx_rc, 
dcp->map->classes[idx_rc]);
+   inbits ^= BIT(idx_rc);
+   totct += do_callback_changes(dcp, idx_rc, );
+   }
+   kfree(cls);
+   *dcp->bits = inbits;
+   vpr_info("total matches: %d\n", totct);
+   return 0;
+}
+
 /**
  * param_set_dyndbg_classes - bits => categories >control setter
  * @instr: string echo>d to sysfs
@@ -639,10 +694,9 @@ int param_set_dyndbg_classes(const char *instr, const 
struct kernel_param *kp)
return -EINVAL;
}
rc = kstrtoul(instr, 0, );
-   if (rc) {
-   pr_err("set_dyndbg_classes: expecting bits/integer\n");
-   return -EINVAL;
-   }
+   if (rc)
+   return param_set_dyndbg_class_strings(instr, kp);
+
vpr_info("set_dyndbg_classes: new 0x%lx current 0x%lx\n", inbits, 
*dcp->bits);
 
for (i = 0; i < dcp->map->length; i++) {
@@ -650,6 +704,7 @@ int param_set_dyndbg_classes(const char *instr, const 
struct kernel_param *kp)
if (test_bit(i, ) == test_bit(i, dcp->bits))
continue;
 
+   vpr_info("set_dyndbg_classes: bit %d: %s\n", i, 
dcp->map->classes[i]);
totct += do_callback_changes(dcp, i, );
}
*dcp->bits = inbits;
-- 
2.35.3



[PATCH v2 08/27] dyndbg: add drm.debug style bitmap support

2022-05-16 Thread Jim Cromie
Add kernel_param_ops and callbacks to implement a bitmap in a
sysfs-node.  IE, add these:

 - int param_set_dyndbg_classes()
 - int param_get_dyndbg_classes()
 - struct kernel_param_ops param_ops_dyndbg_classes

Following the model of kernel/params.c STANDARD_PARAM_DEFS, these are
non-static and exported.

get/set use an augmented kernel_param; the arg refs a new struct
dyndbg_classes_param, initialized by the macro, containing:

BITS: a pointer to the user module's ulong holding the bits/state.
By ref'g the client's bit-state, we coordinate with existing code that
uses it, so it works unchanged; for example drm_debug_enabled().  The
change to ulong allows use of BIT() etc.

FLAGS: dyndbg.flags toggled by bit-changes. Usually just "p".

MAP: a pointer to struct ddebug_known_classes, which maps those
class-names to pr_debug.class_ids 0..N.

Using the sys-node, with dynamic_debug.verbose=1:

bash-5.1# echo 1 > /sys/module/drm/parameters/debug
[   29.821298] dyndbg: set_dyndbg_classes: new 0x1 current 0x0
[   29.822841] dyndbg: query 0: "class DRM_UT_CORE +p" mod:*
[   29.824348] dyndbg: no matches for query
[   29.825428] dyndbg: total matches: 0

Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h | 17 
 lib/dynamic_debug.c   | 81 +++
 2 files changed, 98 insertions(+)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 328722ba2d8e..e9e6d0f503f3 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -85,6 +85,11 @@ struct ddebug_known_classes_map {
.classes = { __VA_ARGS__ }  \
}
 
+struct ddebug_classes_bitmap_param {
+   unsigned long *bits;
+   char flags[8];
+   const struct ddebug_known_classes_map *map;
+};
 
 #if defined(CONFIG_DYNAMIC_DEBUG_CORE)
 
@@ -237,6 +242,10 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 int  dynamic_debug_register_classes(struct ddebug_known_classes_map *map);
 void dynamic_debug_unregister_classes(struct ddebug_known_classes_map *map);
 
+struct kernel_param;
+int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp);
+int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp);
+
 #else /* !CONFIG_DYNAMIC_DEBUG_CORE */
 
 #include 
@@ -283,6 +292,14 @@ static inline int dynamic_debug_register_classes(const 
struct ddebug_known_class
 static inline void dynamic_debug_unregister_classes(struct 
ddebug_known_classes_map *map)
 {}
 
+struct kernel_param;
+static inline int param_set_dyndbg_classes(const char *instr, const struct 
kernel_param *kp)
+{ return 0; }
+static inline int param_get_dyndbg_classes(char *buffer, const struct 
kernel_param *kp)
+{ return 0; }
+
 #endif /* !CONFIG_DYNAMIC_DEBUG_CORE */
 
+extern const struct kernel_param_ops param_ops_dyndbg_classes;
+
 #endif
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index b1aaf8893cdf..b67bf9efec07 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -597,6 +597,87 @@ static int ddebug_exec_queries(char *query, const char 
*modname)
return nfound;
 }
 
+static int do_callback_changes(const struct ddebug_classes_bitmap_param *dcp,
+  int bitpos, unsigned long *inbits)
+{
+#define QUERY_SIZE 128
+   char query[QUERY_SIZE];
+   int matches;
+
+   snprintf(query, QUERY_SIZE, "class %s %c%s", dcp->map->classes[bitpos],
+test_bit(bitpos, inbits) ? '+' : '-', dcp->flags);
+
+   matches = ddebug_exec_queries(query, NULL);
+
+   v2pr_info("bit-%d: %d matches on class:%s\n", bitpos,
+ matches, dcp->map->classes[bitpos]);
+
+   return matches;
+}
+
+/**
+ * param_set_dyndbg_classes - bits => categories >control setter
+ * @instr: string echo>d to sysfs
+ * @kp:kp->arg has state: bits, map
+ *
+ * Enable/disable prdbgs by their "category", as specified in the
+ * arguments to DEFINE_DYNAMIC_DEBUG_CLASSES.
+ *
+ * Returns: 0 or <0 if error.
+ */
+int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp)
+{
+   const struct ddebug_classes_bitmap_param *dcp = kp->arg;
+   unsigned long inbits;
+   int rc, i, totct = 0;
+
+   if (!dcp || !dcp->map) {
+   pr_err("set_dyndbg_classes: no bits=>queries map\n");
+   return -EINVAL;
+   }
+   rc = kstrtoul(instr, 0, );
+   if (rc) {
+   pr_err("set_dyndbg_classes: expecting bits/integer\n");
+   return -EINVAL;
+   }
+   vpr_info("set_dyndbg_classes: new 0x%lx current 0x%lx\n", inbits, 
*dcp->bits);
+
+   for (i = 0; i < dcp->map->length; i++) {
+
+   if (test_bit(i, ) == test_bit(i, dcp->bits))
+   continue;
+
+   totct += do_callback_changes(dcp, i, );
+   }
+   *dcp->bits = inbits;
+   vpr_info("total matches: %d\n", totct);
+   return 0;
+}
+EXPORT_SYMBOL(param_set_dyndbg_classes);
+

[PATCH v2 07/27] dyndbg: validate class FOO on module

2022-05-16 Thread Jim Cromie
Add module-to-class validation, in

  #> echo class DRM_UT_KMS +p > /proc/dynamic_debug/control

If a query has "class FOO", ddebug_validate_classname (called from
ddebug_change) requires that FOO is known to module X, otherwize X is
skipped entirely.

The choice of FOO is highly selective, giving isolation and/or
coordinated sharing of FOOs.  For example, only DRM modules should
know and respond to DRM_UT_KMS.

So this, combined with module's opt-in declaration of known classes,
effectively privatizes the .class_id space for each module (or
coordinated set of modules).

Ignoring a bad query, with dynamic_debug.verbose=3:
(lots of modules will not know other module's classes)

bash-5.1# echo module drm class FOO +p > /proc/dynamic_debug/control
[   54.507983] dyndbg: read 24 bytes from userspace
[   54.509549] dyndbg: query 0: "module drm class FOO +p" mod:*
[   54.511502] dyndbg: split into words: "module" "drm" "class" "FOO" "+p"
[   54.513672] dyndbg: op='+'
[   54.514575] dyndbg: flags=0x1
[   54.515547] dyndbg: *flagsp=0x1 *maskp=0x
[   54.517112] dyndbg: parsed: func="" file="" module="drm" format="" 
lineno=0-0 class=FOO
[   54.519707] dyndbg: class: drm.FOO unknown
[   54.521302] dyndbg: no matches for query
[   54.522581] dyndbg: no-match: func="" file="" module="drm" format="" 
lineno=0-0 class=FOO
[   54.525236] dyndbg: processed 1 queries, with 0 matches, 0 errs

Also add a new column to control-file output, displaying the
class-name when its not default.  If a module has pr_debugs with
non-default .class_id's, and has not registered them, ""
is issued.

Signed-off-by: Jim Cromie 
---
. split out validate_classnames()
---
 lib/dynamic_debug.c | 70 +++--
 1 file changed, 62 insertions(+), 8 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 8f600c13048a..b1aaf8893cdf 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -56,6 +56,7 @@ struct ddebug_query {
const char *module;
const char *function;
const char *format;
+   const char *class_string;
unsigned int first_lineno, last_lineno;
 };
 
@@ -136,13 +137,40 @@ static void vpr_info_dq(const struct ddebug_query *query, 
const char *msg)
fmtlen--;
}
 
-   v3pr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" 
lineno=%u-%u\n",
-msg,
-query->function ?: "",
-query->filename ?: "",
-query->module ?: "",
-fmtlen, query->format ?: "",
-query->first_lineno, query->last_lineno);
+   v3pr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" 
lineno=%u-%u class=%s\n",
+ msg,
+ query->function ?: "",
+ query->filename ?: "",
+ query->module ?: "",
+ fmtlen, query->format ?: "",
+ query->first_lineno, query->last_lineno, query->class_string);
+}
+
+/* return <0 if class-name is unknown/invalid, 0..CLASS_DFLT otherwise */
+static int ddebug_validate_classname(struct ddebug_table *dt, const char 
*class_string)
+{
+   int query_class = -ENOENT;
+   int idx;
+
+   if (!class_string)
+   /* all queries w/o class given work only on default class */
+   return _DPRINTK_CLASS_DFLT;
+
+   /*
+* XXX single list will need to be a for-list
+* so that modules can have 2 sets of class-decls
+*/
+   if (!dt->map)
+   return -ENOENT;
+
+   idx = match_string(dt->map->classes, dt->map->length, class_string);
+   if (idx < 0) {
+   v3pr_info("class: %s.%s unknown\n", dt->mod_name, class_string);
+   return -ENOENT;
+   }
+   query_class = idx + dt->map->base;
+
+   return query_class;
 }
 
 /*
@@ -159,6 +187,7 @@ static int ddebug_change(const struct ddebug_query *query,
unsigned int newflags;
unsigned int nfound = 0;
struct flagsbuf fbuf, nbuf;
+   int query_class;
 
/* search for matching ddebugs */
mutex_lock(_lock);
@@ -169,9 +198,18 @@ static int ddebug_change(const struct ddebug_query *query,
!match_wildcard(query->module, dt->mod_name))
continue;
 
+   /* validate class-string against module's known classes */
+   query_class = ddebug_validate_classname(dt, 
query->class_string);
+   if (query_class < 0)
+   continue;
+
for (i = 0; i < dt->num_ddebugs; i++) {
struct _ddebug *dp = >ddebugs[i];
 
+   /* match against query-class, either valid input or 
default */
+   if (query_class != dp->class_id)
+   continue;
+
/* match against the source filename */
if (query->filename &&

[PATCH v2 09/27] Doc/dyndbg: document new class class_name query support

2022-05-16 Thread Jim Cromie
The added paragraph is slightly process oriented, rather than in
language of guarantees; I thought the implications were clear enough.

It does perhaps undersell the selectivity gained with string
class_names; only drm/* would sanely register DRM_UT_CORE etc, so
doing multiple "module {drm*,amdgpu,i915}" queries is unnecessary.

Signed-off-by: Jim Cromie 
---
 Documentation/admin-guide/dynamic-debug-howto.rst | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst 
b/Documentation/admin-guide/dynamic-debug-howto.rst
index a89cfa083155..01ca6f635dcc 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -35,6 +35,7 @@ Dynamic debug has even more useful features:
- line number (including ranges of line numbers)
- module name
- format string
+   - class string (as known by each module)
 
  * Provides a debugfs control file: ``/dynamic_debug/control``
which can be read to display the complete list of known debug
@@ -142,6 +143,7 @@ against.  Possible keywords are:::
 'file' string |
 'module' string |
 'format' string |
+'class' string |
 'line' line-range
 
   line-range ::= lineno |
@@ -203,6 +205,15 @@ format
format "nfsd: SETATTR"  // a neater way to match a format with 
whitespace
format 'nfsd: SETATTR'  // yet another way to match a format with 
whitespace
 
+class
+The given class_name is validated against each module, which may
+have registered a list of known class_names.  If the class_name is
+found for a module, callsite matching and adjustment proceeds.
+Examples::
+
+   class DRM_UT_KMS# unless DRM wants different
+   class JUNK  # silent non-match
+
 line
 The given line number or range of line numbers is compared
 against the line number of each ``pr_debug()`` callsite.  A single
-- 
2.35.3



[PATCH v2 05/27] dyndbg: add exclusive class_id to pr_debug callsites

2022-05-16 Thread Jim Cromie
DRM issues ~10 exclusive categories of debug messages; to represent
this directly in dyndbg, add a new field: struct _ddebug.class_id:5.

We only need 4 bits for drm, and with that reserved, we have 2 to
spare on 32 bit builds; lets take one extra (5 bits total), and keep a
spare bit.  32 classes-per-bitmap is a practical usability limit
anyway with a bitmap interface:

  #> echo 0x012345678 > /sys/module/drm/parameters/debug

All existing callsites are initialized with _DPRINTK_CLASS_DFLT, which
is 2^5-1.  This reserves 0-30 for use in new categorized/class'd
pr_debugs, which fits perfectly with natural enums (ints: 0..N).

To achieve this, DEFINE_DYNAMIC_DEBUG_METADATA_CLS(cls,...) is added,
and DEFINE_DYNAMIC_DEBUG_METADATA is altered to call it with the
default.  The factory macro chain between there and pr_debug is
adjusted similarly.

No behavior change.

Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h | 54 ++-
 1 file changed, 41 insertions(+), 13 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index dd20e825c36f..39550fefcf0f 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -6,6 +6,8 @@
 #include 
 #endif
 
+#include 
+
 /*
  * An instance of this structure is created in a special
  * ELF section at every dynamic debug callsite.  At runtime,
@@ -21,6 +23,9 @@ struct _ddebug {
const char *filename;
const char *format;
unsigned int lineno:18;
+#define CLS_BITS 5
+   unsigned int class_id:CLS_BITS;
+#define _DPRINTK_CLASS_DFLT((1 << CLS_BITS) - 1)
/*
 * The flags field controls the behaviour at the callsite.
 * The bits here are changed dynamically when the user
@@ -84,7 +89,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 const struct ib_device *ibdev,
 const char *fmt, ...);
 
-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)   \
+#define DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, cls, fmt)  \
static struct _ddebug  __aligned(8) \
__section("__dyndbg") name = {  \
.modname = KBUILD_MODNAME,  \
@@ -93,8 +98,14 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
.format = (fmt),\
.lineno = __LINE__, \
.flags = _DPRINTK_FLAGS_DEFAULT,\
+   .class_id = cls,\
_DPRINTK_KEY_INIT   \
-   }
+   };  \
+   BUILD_BUG_ON_MSG(cls > _DPRINTK_CLASS_DFLT, \
+"classid value overflow")
+
+#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)   \
+   DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, _DPRINTK_CLASS_DFLT, fmt)
 
 #ifdef CONFIG_JUMP_LABEL
 
@@ -125,18 +136,26 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 
 #endif /* CONFIG_JUMP_LABEL */
 
-#define __dynamic_func_call(id, fmt, func, ...) do {   \
-   DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
-   if (DYNAMIC_DEBUG_BRANCH(id))   \
-   func(, ##__VA_ARGS__);   \
+#define __dynamic_func_call_cls(id, cls, fmt, func, ...) do {  \
+   DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt);\
+   if (DYNAMIC_DEBUG_BRANCH(id))   \
+   func(, ##__VA_ARGS__);   \
 } while (0)
 
-#define __dynamic_func_call_no_desc(id, fmt, func, ...) do {   \
-   DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
-   if (DYNAMIC_DEBUG_BRANCH(id))   \
-   func(__VA_ARGS__);  \
+#define __dynamic_func_call_no_desc_cls(id, cls, fmt, func, ...) do {  \
+   DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt);\
+   if (DYNAMIC_DEBUG_BRANCH(id))   \
+   func(__VA_ARGS__);  \
 } while (0)
 
+#define __dynamic_func_call(id, fmt, func, ...)
\
+   __dynamic_func_call_cls(id, _DPRINTK_CLASS_DFLT,\
+   fmt, func, ##__VA_ARGS__)
+
+#define __dynamic_func_call_no_desc(id, fmt, func, ...)
\
+   __dynamic_func_call_no_desc_cls(id, _DPRINTK_CLASS_DFLT,\
+   fmt, func, ##__VA_ARGS__)
+
 /*
  * "Factory macro" for generating a call to func, guarded by a
  * DYNAMIC_DEBUG_BRANCH. The dynamic debug descriptor will be
@@ -145,15 +164,24 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
  * the varargs. Note that fmt is repeated in invocations of this
  * macro.
  */
+#define 

[PATCH v2 06/27] dyndbg: add dynamic_debug_(un)register_classes

2022-05-16 Thread Jim Cromie
Add dynamic_debug_register_classes() to API, allowing user modules
(builtin and loadable) to register class_names for the .class_id's
they are using.  Knowing classes is 1st step to validating with them.
Add dynamic_debug_unregister_classes() also.

Add struct ddebug_known_classes_map: maps known class_name strings to
.class_id[0..N], where N<31.  .base allows sharing of that range.

A wrapper macro: DYNAMIC_DEBUG_CLASSES(_var, _modmatch, _base,
classes) defines and initializes that struct var, _maybe_unused is
added so the decl doesn't draw warnings when dyndbg is not enabled; a
small list of classnames is tolerable wasted space.

_var: user passes this into dynamic_debug_register_classes(var).

_base: usually 0, it allows splitting 31 classes into subranges, so
that multiple sysfs-nodes can share the module's class-id space.

classes: list of strings with classnames, mapped to class-id=idx(+_base)

mod_name: KBUILD_MODNAME, available for builtins, loadables
mod:  ref to loadable module. allows ==, distinguishing loadables.

When modules register known classnames, they opt-in to permit dyndbg
to allow "class " queries to manipulate their class'd pr_debugs
(if any), default class_id pr_debugs are still controllable as before.

dynamic_debug_register_classes() finds the module's ddebug_table
record, and attaches the map to it.  This makes it available to
ddebug_change(), which will use it to validate class'd commands.

Sharing class-names across multiple modules is how those modules
coordinate; all drm* and drivers would respond to:

  #> echo class DRM_UT_CORE +p > /proc/dynamic_debug/control

Therefore no class-name uniqueness check is useful.

TODO: Eventually we need a list of registered classes, not just the
zero-or-one implemented here.  This will support multiple sysfs-nodes,
one each for print-to-syslog, print-to-tracefs, or subranges using
_base.

Signed-off-by: Jim Cromie 
---
. fix register_classes() for !CONFIG_MODULES
. add maybe-unused to var decl in DYNAMIC_DEBUG_CLASSES
. kdoc for DYNAMIC_DEBUG_CLASSES
. add dynamic_debug_unregister_classes
---
 include/linux/dynamic_debug.h | 36 
 lib/dynamic_debug.c   | 53 +++
 2 files changed, 89 insertions(+)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 39550fefcf0f..328722ba2d8e 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -56,6 +56,34 @@ struct _ddebug {
 #endif
 } __attribute__((aligned(8)));
 
+struct ddebug_known_classes_map {
+   struct list_head link;
+   struct module *mod;
+   const char *mod_name;   /* needed for builtins */
+   const int base; /* index of 1st .class_id, allows split/shared 
space */
+   const int length;
+   const char *classes[];  /* index maps .class_id */
+};
+
+#define NUM_TYPE_ARGS(eltype, ...) \
+   (sizeof((eltype[]) {__VA_ARGS__}) / sizeof(eltype))
+/**
+ * DYNAMIC_DEBUG_CLASSES - declare classnames known by a module
+ * @_var: passed to dynamic_debug_register_classes(_var)
+ * @_base: offset of 1st class-name. splits .class_id space
+ * @classes: class-names known/used by of .class_ids[_base.._base+length]
+ *
+ * @classes specifies names for the classids used by a module; dyndbg
+ * accepts "class " commands if  is known and registered.
+ */
+#define DYNAMIC_DEBUG_CLASSES(_var, _base, ...)
\
+   static __maybe_unused struct ddebug_known_classes_map _var = {  \
+   .mod = THIS_MODULE, \
+   .mod_name = KBUILD_MODNAME, \
+   .base = _base,  \
+   .length = NUM_TYPE_ARGS(char*, __VA_ARGS__),\
+   .classes = { __VA_ARGS__ }  \
+   }
 
 
 #if defined(CONFIG_DYNAMIC_DEBUG_CORE)
@@ -206,6 +234,9 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
   KERN_DEBUG, prefix_str, prefix_type, \
   rowsize, groupsize, buf, len, ascii)
 
+int  dynamic_debug_register_classes(struct ddebug_known_classes_map *map);
+void dynamic_debug_unregister_classes(struct ddebug_known_classes_map *map);
+
 #else /* !CONFIG_DYNAMIC_DEBUG_CORE */
 
 #include 
@@ -247,6 +278,11 @@ static inline int ddebug_dyndbg_module_param_cb(char 
*param, char *val,
} while (0)
 
 
+static inline int dynamic_debug_register_classes(const struct 
ddebug_known_classes_map *map)
+{ return 0; }
+static inline void dynamic_debug_unregister_classes(struct 
ddebug_known_classes_map *map)
+{}
+
 #endif /* !CONFIG_DYNAMIC_DEBUG_CORE */
 
 #endif
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index cdc0b03b1148..8f600c13048a 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -45,6 +45,8 @@ extern struct _ddebug __stop___dyndbg[];
 struct ddebug_table {
struct 

[PATCH v2 03/27] dyndbg: fix module.dyndbg handling

2022-05-16 Thread Jim Cromie
For CONFIG_DYNAMIC_DEBUG=N, the ddebug_dyndbg_module_param_cb()
stub-fn is too permissive:

bash-5.1# modprobe drm JUNKdyndbg
bash-5.1# modprobe drm dyndbgJUNK
[   42.933220] dyndbg param is supported only in CONFIG_DYNAMIC_DEBUG builds
[   42.937484] ACPI: bus type drm_connector registered

This caused no ill effects, because unknown parameters are either
ignored by default (with an "unknown parameter" warning, see below),
or ignored because dyndbg allows its no-effect use on non-dyndbg builds.

That said, the code has an explicit feedback message, which should be
issued accurately.  Fix with strcmp, for exact param-name match.

Here is fixed behavior:

bash-5.1# modprobe drm dyndbgJUNK
[   20.127473] drm: unknown parameter 'dyndbgJUNK' ignored
[   20.128835] ACPI: bus type drm_connector registered
bash-5.1# rmmod drm
[   37.961656] ACPI: bus type drm_connector unregistered
bash-5.1# modprobe drm dyndbg
[   42.933220] dyndbg param is supported only in CONFIG_DYNAMIC_DEBUG builds
[   42.937484] ACPI: bus type drm_connector registered

Reported-by: Rasmus Villemoes 
Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index dce631e678dd..f30b01aa9fa4 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -201,7 +201,7 @@ static inline int ddebug_remove_module(const char *mod)
 static inline int ddebug_dyndbg_module_param_cb(char *param, char *val,
const char *modname)
 {
-   if (strstr(param, "dyndbg")) {
+   if (!strcmp(param, "dyndbg")) {
/* avoid pr_warn(), which wants pr_fmt() fully defined */
printk(KERN_WARNING "dyndbg param is supported only in "
"CONFIG_DYNAMIC_DEBUG builds\n");
-- 
2.35.3



[PATCH v2 04/27] dyndbg: drop EXPORTed dynamic_debug_exec_queries

2022-05-16 Thread Jim Cromie
This exported fn is unused, and is effectively obsoleted by a
forthcoming commit, so remove it.

The export was added to let drm control pr_debugs, as part of using
them to avoid drm_debug_enabled overheads.  But following patches
implement the drm.debug interface, and adapt drm to just use it, so
nobody will never need the export.

This also drops the CONFIG_DYNAMIC_DEBUG=N stub-func, and its
pr_warn(), which I avoided in 2012, then added in 2020 :-/

Fixes: a2d375eda771 ("dyndbg: refine export, rename to 
dynamic_debug_exec_queries()")
Fixes: 4c0d77828d4f ("dyndbg: export ddebug_exec_queries")
Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h |  8 
 lib/dynamic_debug.c   | 29 -
 2 files changed, 37 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index f30b01aa9fa4..dd20e825c36f 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -55,9 +55,6 @@ struct _ddebug {
 
 #if defined(CONFIG_DYNAMIC_DEBUG_CORE)
 
-/* exported for module authors to exercise >control */
-int dynamic_debug_exec_queries(const char *query, const char *modname);
-
 int ddebug_add_module(struct _ddebug *tab, unsigned int n,
const char *modname);
 extern int ddebug_remove_module(const char *mod_name);
@@ -221,11 +218,6 @@ static inline int ddebug_dyndbg_module_param_cb(char 
*param, char *val,
rowsize, groupsize, buf, len, ascii);   \
} while (0)
 
-static inline int dynamic_debug_exec_queries(const char *query, const char 
*modname)
-{
-   pr_warn("kernel not built with CONFIG_DYNAMIC_DEBUG_CORE\n");
-   return 0;
-}
 
 #endif /* !CONFIG_DYNAMIC_DEBUG_CORE */
 
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index ca2a28f1d51c..cdc0b03b1148 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -555,35 +555,6 @@ static int ddebug_exec_queries(char *query, const char 
*modname)
return nfound;
 }
 
-/**
- * dynamic_debug_exec_queries - select and change dynamic-debug prints
- * @query: query-string described in admin-guide/dynamic-debug-howto
- * @modname: string containing module name, usually _name
- *
- * This uses the >/proc/dynamic_debug/control reader, allowing module
- * authors to modify their dynamic-debug callsites. The modname is
- * canonically struct module.mod_name, but can also be null or a
- * module-wildcard, for example: "drm*".
- */
-int dynamic_debug_exec_queries(const char *query, const char *modname)
-{
-   int rc;
-   char *qry; /* writable copy of query */
-
-   if (!query) {
-   pr_err("non-null query/command string expected\n");
-   return -EINVAL;
-   }
-   qry = kstrndup(query, PAGE_SIZE, GFP_KERNEL);
-   if (!qry)
-   return -ENOMEM;
-
-   rc = ddebug_exec_queries(qry, modname);
-   kfree(qry);
-   return rc;
-}
-EXPORT_SYMBOL_GPL(dynamic_debug_exec_queries);
-
 #define PREFIX_SIZE 64
 
 static int remaining(int wrote)
-- 
2.35.3



[PATCH v2 02/27] dyndbg: show both old and new in change-info

2022-05-16 Thread Jim Cromie
print "old -> new" flag values in the info("change") message.

no functional change.

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

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index a56c1286ffa4..ca2a28f1d51c 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -156,7 +156,7 @@ static int ddebug_change(const struct ddebug_query *query,
struct ddebug_table *dt;
unsigned int newflags;
unsigned int nfound = 0;
-   struct flagsbuf fbuf;
+   struct flagsbuf fbuf, nbuf;
 
/* search for matching ddebugs */
mutex_lock(_lock);
@@ -217,11 +217,12 @@ static int ddebug_change(const struct ddebug_query *query,
static_branch_enable(>key.dd_key_true);
}
 #endif
+   v4pr_info("changed %s:%d [%s]%s %s -> %s\n",
+ trim_prefix(dp->filename), dp->lineno,
+ dt->mod_name, dp->function,
+ ddebug_describe_flags(dp->flags, ),
+ ddebug_describe_flags(newflags, ));
dp->flags = newflags;
-   v4pr_info("changed %s:%d [%s]%s =%s\n",
-trim_prefix(dp->filename), dp->lineno,
-dt->mod_name, dp->function,
-ddebug_describe_flags(dp->flags, ));
}
}
mutex_unlock(_lock);
-- 
2.35.3



[PATCH v2 01/27] dyndbg: fix static_branch manipulation

2022-05-16 Thread Jim Cromie
In https://lore.kernel.org/lkml/20211209150910.ga23...@axis.com/

Vincent's patch commented on, and worked around, a bug toggling
static_branch's, when a 2nd PRINTK-ish flag was added.  The bug
results in a premature static_branch_disable when the 1st of 2 flags
was disabled.

The cited commit computed newflags, but then in the JUMP_LABEL block,
failed to use that result, instead using just one of the terms in it.
Using newflags instead made the code work properly.

This is Vincents test-case, reduced.  It needs the 2nd flag to
demonstrate the bug, but it's explanatory here.

pt_test() {
echo 5 > /sys/module/dynamic_debug/verbose

site="module tcp" # just one callsite
echo " $site =_ " > /proc/dynamic_debug/control # clear it

# A B ~A ~B
for flg in +T +p "-T #broke here" -p; do
echo " $site $flg " > /proc/dynamic_debug/control
done;

# A B ~B ~A
for flg in +T +p "-p #broke here" -T; do
echo " $site $flg " > /proc/dynamic_debug/control
done
}
pt_test

Fixes: 84da83a6ffc0 dyndbg: combine flags & mask into a struct, simplify with it
CC: vincent.whitchu...@axis.com
Signed-off-by: Jim Cromie 
Acked-by: Jason Baron 
---
.drop @stable, no exposed bug.
.add jbaron ack
---
 lib/dynamic_debug.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index dd7f56af9aed..a56c1286ffa4 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -211,10 +211,11 @@ static int ddebug_change(const struct ddebug_query *query,
continue;
 #ifdef CONFIG_JUMP_LABEL
if (dp->flags & _DPRINTK_FLAGS_PRINT) {
-   if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT))
+   if (!(newflags & _DPRINTK_FLAGS_PRINT))

static_branch_disable(>key.dd_key_true);
-   } else if (modifiers->flags & _DPRINTK_FLAGS_PRINT)
+   } else if (newflags & _DPRINTK_FLAGS_PRINT) {
static_branch_enable(>key.dd_key_true);
+   }
 #endif
dp->flags = newflags;
v4pr_info("changed %s:%d [%s]%s =%s\n",
-- 
2.35.3



[RFC PATCH v2 00/27] DRM.debug on DYNAMIC_DEBUG, add trace events

2022-05-16 Thread Jim Cromie
DRM.debug API is 23 macros, issuing 10 exclusive categories of debug
messages.  By rough count, they are used 5140 times in the kernel.
These all call drm_dbg or drm_devdbg, which call drm_debug_enabled(),
which checks bits in global __drm_debug.  Some of these are page-flips
and vblanks, and get called often.

DYNAMIC_DEBUG (with CONFIG_JUMP_LABEL) is built to avoid this kind of
work, with NOOPd jump/callsites.

This patchset is RFC because:
- it touches 2.5 subsystems: dyndbg, drm, tracefs (new events)
- dyndbg class support is built for drm, needs it for validation
- new api, used by drm
- big memory impact, with 5100 new pr-debug callsites.
- drm class bikeshedding opportunities
- others, names etc.

DYNAMIC_DEBUG:

Adapt to directly represent 32 exclusive classes / categories.
All existing users get _CLASS_DFLT:31, reserving 0-30 for opt-in.

dynamic_debug_register_classes(): Tells dyndbg that caller/client is
using .class_id's 0..N, and wants them exposed and manipulatable with
names: DRM_UT_KMS etc.

Client invokes DYNAMIC_DEBUG_CLASSES to define the name->id map,
then registers it during its initialization.

Then, when a dyndbg command-query has "class FOO":

 echo class DRM_UT_KMS +p > /proc/dynamic_debug/control

ddebug_change() will 1st ddebug_validate_classname() for each module,
using its registered class-maps; only modules which know DRM_UT_KMS
will get those callsite adjustments.  This "protects" each module's
class-id space, unlike "class 4" query syntax.

Add bitmap support for:
  echo 0x02 > /sys/module/drm/parameters/debug

Add symbolic bitmap, because we have the class-names:
  echo +DRM_UT_KMS,+DRM_UT_ATOMIC > /sys/module/drm/parameters/debug

Add test_dynamic_debug, to prove out the API.

 which is (used 3x to prove class-id ranges):
  - DYNAMIC_DEBUG_CLASSES(var, ... [3 class-name-literals each])
  - dynamic_debug_register_classes(var)
  - dynamic_debug_unregister_classes(var)
 also (6x):
  +module_param_cb(, _ops_dyndbg_classes, /[pt][123]_bitmap/, 
0600);

Bits 0,1,2 of each of the 6 bitmaps control the 3 named classes in
each of 3 groups, toggling their p,T bits respectively.

RFC:

dynamic_debug_register_classes() cannot act early enough to be in
effect at module-load.  So this will not work as you'd reasonably
expect:

  modprobe test_dynamic_debug dyndbg='+pfm; class FOO +pfmlt'

The 1st query:+pfm will be enabled during load, but in the 2nd query,
"class FOO" will be unknown at load time.  Early class enablement
would be nice.  DYNAMIC_DEBUG_CLASSES is a static initializer, which
is certainly early enough, but Im missing a trick, suggestions?

Wildcarding on classname is possible, maybe useful:

   echo +DRM_UT_\* > /sys/module/drm/parameters/debug

If contemplated in earnest, it should consider the difference between
"DRM_*" and "*_KMS", wrt observing across class hierarchies, as well
as decide whether that echo means 1st match, or all matching names.

__pr_debug_cls(cls, fmt,...) is just for testing, drm doesnt need it.


DRM adaptation:

Basically, these patches add another layer of macro indirection, which
by CONFIG_DRM_USE_DYNAMIC_DEBUG=y, wraps drm_*dbg() in dyndbg's callsite
Factory macro, and adds the new descriptor arg to the funcs.

With these patches, drm.debugs appear as controllable *pr-dbg* callsites:

[   11.804352] dyndbg: register_classes: drm
[   11.920715] dyndbg: 234 debug prints in module drm_kms_helper
[   11.932135] dyndbg:   2 debug prints in module ttm
[   11.936119] dyndbg:   8 debug prints in module video
[   12.537543] dyndbg: 1756 debug prints in module i915
[   12.555045] dyndbg: register_classes: i915
[   12.666727] AMD-Vi: AMD IOMMUv2 functionality not available on this ..
[   13.735310] dyndbg: 3859 debug prints in module amdgpu

amdgpu's large count includes:
   582  direct uses/mentions of pr_debug
43  defns of DC_LOG_*, which use either pr_debug or DRM_DEBUG_*
 ~1000  uses of DC_LOG_*
  1116  uses of dml_print in drivers/gpu/drm/amd
15  drm_dbg_\\w+ drivers/gpu/drm/amd
   273  DRM_DEBUG_\\w+ drivers/gpu/drm/amd

i915 has:
  1072  drm_dbg_\\w+ drivers/gpu/drm/i915/ | wc  -l
   200  DRM_DEBUG_\\w+ drivers/gpu/drm/i915/
46  pr_debug drivers/gpu/drm/i915/
   144  gvt_dbg_\\w+ drivers/gpu/drm/i915/gvt, using pr_debug

This impacts the data footprint, so everything new/drm is dependent on
DRM_USE_DYNAMIC_DEBUG=y.

RFC for DRM:

- decoration flags "fmlt" do not work on drm_*dbg().
  (drm_*dbg() dont use pr_debug, they *become* one flavor of them)
  this could (should?) be added, and maybe tailored for drm.
  some of the device prefixes are very long, a "d" flag could optionalize them.

- api use needs review wrt drm life-cycle.
  enum drm_debug_category and DYNAMIC_DEBUG_CLASSES could be together?

- class-names could stand review, perhaps extension
  "drm:core:" etc have appeared (maybe just from me)
  or a "plan" to look at it later

- i915 & amdgpu have pr_debugs (DC_LOG_*, gvt_dbg_*) that have
class-ish prefixes that are 

[PATCH] drm/amdgpu: Unmap legacy queue when MES is enabled

2022-05-16 Thread Luben Tuikov
This fixes a kernel oops when MES is not enabled.

Reported-by: Kenny Ho 
Suggested-by: Jack Xiao 
Reviewed-by: Alex Deucher 
Signed-off-by: Luben Tuikov 
Fixes: d69e773ca75b8f ("drm/amdgpu: add mes unmap legacy queue routine")
Fixes: 36d7a7094750fc ("drm/amdgpu: add init support for GFX11 (v2)")
---
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 2 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index 4b66b9c93754ba..65a4126135b0e2 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -3568,7 +3568,7 @@ static void gfx10_kiq_unmap_queues(struct amdgpu_ring 
*kiq_ring,
struct amdgpu_device *adev = kiq_ring->adev;
uint32_t eng_sel = ring->funcs->type == AMDGPU_RING_TYPE_GFX ? 4 : 0;
 
-   if (!adev->gfx.kiq.ring.sched.ready) {
+   if (adev->enable_mes && !adev->gfx.kiq.ring.sched.ready) {
amdgpu_mes_unmap_legacy_queue(adev, ring, action, gpu_addr, 
seq);
return;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index 8a1bec70c71932..8773cbd1f03b54 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -191,7 +191,7 @@ static void gfx11_kiq_unmap_queues(struct amdgpu_ring 
*kiq_ring,
struct amdgpu_device *adev = kiq_ring->adev;
uint32_t eng_sel = ring->funcs->type == AMDGPU_RING_TYPE_GFX ? 4 : 0;
 
-   if (!adev->gfx.kiq.ring.sched.ready) {
+   if (adev->enable_mes && !adev->gfx.kiq.ring.sched.ready) {
amdgpu_mes_unmap_legacy_queue(adev, ring, action, gpu_addr, 
seq);
return;
}

base-commit: 2092fd3ff7e91c9f408c98799f4cdcaa93a06c3d
-- 
2.36.1.74.g277cf0bc36



Re: [PATCH] drm/amdkfd: simplify cpu hive assignment

2022-05-16 Thread Felix Kuehling

Am 2022-05-16 um 10:43 schrieb Jonathan Kim:

CPU hive assignment currently assumes when a GPU hive is connected_to_cpu,
there is only one hive in the system.

Only assign CPUs to the hive if they are explicitly directly connected to
the GPU hive to get rid of the need for this assumption.

It's more efficient to do this when querying IO links since other non-CRAT
info has to be filled in anyways.  Also, stop re-assigning the
same CPU to the same GPU hive if it has already been done before.

Signed-off-by: Jonathan Kim 


Reviewed-by: Felix Kuehling 



---
  drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 22 ++
  1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index 2e20f54bb147..8d50d207cf66 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -1271,6 +1271,12 @@ static void kfd_fill_iolink_non_crat_info(struct 
kfd_topology_device *dev)
if (!peer_dev)
continue;
  
+		/* Include the CPU peer in GPU hive if connected over xGMI. */

+   if (!peer_dev->gpu && !peer_dev->node_props.hive_id &&
+   dev->node_props.hive_id &&
+   dev->gpu->adev->gmc.xgmi.connected_to_cpu)
+   peer_dev->node_props.hive_id = dev->node_props.hive_id;
+
list_for_each_entry(inbound_link, _dev->io_link_props,
list) {
if (inbound_link->node_to != link->node_from)
@@ -1302,22 +1308,6 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
  
  	pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id);
  
-	/* Include the CPU in xGMI hive if xGMI connected by assigning it the hive ID. */

-   if (gpu->hive_id && gpu->adev->gmc.xgmi.connected_to_cpu) {
-   struct kfd_topology_device *top_dev;
-
-   down_read(_lock);
-
-   list_for_each_entry(top_dev, _device_list, list) {
-   if (top_dev->gpu)
-   break;
-
-   top_dev->node_props.hive_id = gpu->hive_id;
-   }
-
-   up_read(_lock);
-   }
-
/* Check to see if this gpu device exists in the topology_device_list.
 * If so, assign the gpu to that device,
 * else create a Virtual CRAT for this gpu device and then parse that


Re: VCN_INFO_TABLE_MAX_NUM_INSTANCES vs AMDGPU_MAX_VCN_INSTANCES

2022-05-16 Thread Christian König

Am 16.05.22 um 20:15 schrieb Alex Deucher:

On Mon, May 16, 2022 at 2:10 PM Christian König
 wrote:

Am 16.05.22 um 19:49 schrieb Ernst Sjöstrand:

Den mån 16 maj 2022 kl 17:13 skrev Alex Deucher :

On Sun, May 15, 2022 at 11:46 AM Ernst Sjöstrand  wrote:

smatch found this problem on amd-staging-drm-next:

drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c:1443 amdgpu_discovery_get_vcn_info() 
error: buffer overflow 'adev->vcn.vcn_codec_disable_mask' 2 <= 3

This is caused by:
#define AMDGPU_MAX_VCN_INSTANCES 2
#define VCN_INFO_TABLE_MAX_NUM_INSTANCES 4

Can we just drop VCN_INFO_TABLE_MAX_NUM_INSTANCES completely and use 
AMDGPU_MAX_VCN_INSTANCES everywhere instead (and bump it to 4)?

We should be able to bump AMDGPU_MAX_VCN_INSTANCES to 4 (although it
would waste some memory in the places it is used at this point).
VCN_INFO_TABLE_MAX_NUM_INSTANCES is part of a firmware structure so we
can't change that without breaking the firmware structure.

Alex


It would be nice to get rid of this pattern and make sure it doesn't happen 
again when the VCN info table is raised to 5.
It's very similar to the HWIP_MAX_INSTANCE issue.


No, as Alex explained that distinction is intentional.

The firmware definition is 4 for future extensions, that doesn't mean that this 
is currently used.

There is currently simply no need to set AMDGPU_MAX_VCN_INSTANCES to more than 
2.

Right.  The attached patch should protect against the scenario you are
envisioning.


Acked-by: Christian König 



Alex


Regards,
Christian.


//E






[PATCH 1/2] drm/amdkfd: port cwsr trap handler from dkms branch

2022-05-16 Thread Eric Huang
It is to simplify trap handler support for new asics in
the future.

Signed-off-by: Eric Huang 
---
 .../gpu/drm/amd/amdkfd/cwsr_trap_handler.h| 2527 +
 .../amd/amdkfd/cwsr_trap_handler_gfx10.asm|  325 ++-
 .../drm/amd/amdkfd/cwsr_trap_handler_gfx9.asm |  244 +-
 3 files changed, 1596 insertions(+), 1500 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h 
b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
index 475f89700c74..8cbdc7f519c6 100644
--- a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
+++ b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
@@ -166,7 +166,7 @@ static const uint32_t cwsr_trap_gfx8_hex[] = {
0x807c847c, 0x806eff6e,
0x0400, 0xbf0a757c,
0xbf85ffef, 0xbf9c,
-   0xbf8200cd, 0xbef8007e,
+   0xbf8200ce, 0xbef8007e,
0x8679ff7f, 0x,
0x8779ff79, 0x0004,
0xbefa0080, 0xbefb00ff,
@@ -212,304 +212,310 @@ static const uint32_t cwsr_trap_gfx8_hex[] = {
0x761e, 0xe0524100,
0x761e0100, 0xe0524200,
0x761e0200, 0xe0524300,
-   0x761e0300, 0xb8f22a05,
-   0x80728172, 0x8e728a72,
-   0xb8f61605, 0x80768176,
-   0x8e768676, 0x80727672,
-   0x80f2c072, 0xb8f31605,
-   0x80738173, 0x8e738473,
-   0x8e7a8273, 0xbefa00ff,
-   0x0100, 0xbefc0073,
-   0xc031003c, 0x0072,
-   0x80f2c072, 0xbf8c007f,
-   0x80fc907c, 0xbe802d00,
-   0xbe822d02, 0xbe842d04,
-   0xbe862d06, 0xbe882d08,
-   0xbe8a2d0a, 0xbe8c2d0c,
-   0xbe8e2d0e, 0xbf06807c,
-   0xbf84fff1, 0xb8f22a05,
-   0x80728172, 0x8e728a72,
-   0xb8f61605, 0x80768176,
-   0x8e768676, 0x80727672,
-   0xbefa0084, 0xbefa00ff,
-   0x0100, 0xc0211cfc,
+   0x761e0300, 0xbf8c0f70,
+   0xb8f22a05, 0x80728172,
+   0x8e728a72, 0xb8f61605,
+   0x80768176, 0x8e768676,
+   0x80727672, 0x80f2c072,
+   0xb8f31605, 0x80738173,
+   0x8e738473, 0x8e7a8273,
+   0xbefa00ff, 0x0100,
+   0xbefc0073, 0xc031003c,
+   0x0072, 0x80f2c072,
+   0xbf8c007f, 0x80fc907c,
+   0xbe802d00, 0xbe822d02,
+   0xbe842d04, 0xbe862d06,
+   0xbe882d08, 0xbe8a2d0a,
+   0xbe8c2d0c, 0xbe8e2d0e,
+   0xbf06807c, 0xbf84fff1,
+   0xb8f22a05, 0x80728172,
+   0x8e728a72, 0xb8f61605,
+   0x80768176, 0x8e768676,
+   0x80727672, 0xbefa0084,
+   0xbefa00ff, 0x0100,
+   0xc0211cfc, 0x0072,
+   0x80728472, 0xc0211c3c,
0x0072, 0x80728472,
-   0xc0211c3c, 0x0072,
-   0x80728472, 0xc0211c7c,
+   0xc0211c7c, 0x0072,
+   0x80728472, 0xc0211bbc,
0x0072, 0x80728472,
-   0xc0211bbc, 0x0072,
-   0x80728472, 0xc0211bfc,
+   0xc0211bfc, 0x0072,
+   0x80728472, 0xc0211d3c,
0x0072, 0x80728472,
-   0xc0211d3c, 0x0072,
-   0x80728472, 0xc0211d7c,
+   0xc0211d7c, 0x0072,
+   0x80728472, 0xc0211a3c,
0x0072, 0x80728472,
-   0xc0211a3c, 0x0072,
-   0x80728472, 0xc0211a7c,
+   0xc0211a7c, 0x0072,
+   0x80728472, 0xc0211dfc,
0x0072, 0x80728472,
-   0xc0211dfc, 0x0072,
-   0x80728472, 0xc0211b3c,
+   0xc0211b3c, 0x0072,
+   0x80728472, 0xc0211b7c,
0x0072, 0x80728472,
-   0xc0211b7c, 0x0072,
-   0x80728472, 0xbf8c007f,
-   0xbefc0073, 0xbefe006e,
-   0xbeff006f, 0x867375ff,
-   0x03ff, 0xb9734803,
-   0x867375ff, 0xf800,
-   0x8f738b73, 0xb973a2c3,
-   0xb977f801, 0x8673ff71,
-   0xf000, 0x8f739c73,
-   0x8e739073, 0xbef60080,
-   0x87767376, 0x8673ff71,
-   0x0800, 0x8f739b73,
-   0x8e738f73, 0x87767376,
-   0x8673ff74, 0x0080,
-   0x8f739773, 0xb976f807,
-   0x8671ff71, 0x,
-   0x86fe7e7e, 0x86ea6a6a,
-   0x8f768374, 0xb976e0c2,
-   0xbf82, 0xb9740002,
-   0xbf8a, 0x95807370,
-   0xbf81, 0x,
+   0xbf8c007f, 0xbefc0073,
+   0xbefe006e, 0xbeff006f,
+   0x867375ff, 0x03ff,
+   0xb9734803, 0x867375ff,
+   0xf800, 0x8f738b73,
+   0xb973a2c3, 0xb977f801,
+   0x8673ff71, 0xf000,
+   0x8f739c73, 0x8e739073,
+   0xbef60080, 0x87767376,
+   0x8673ff71, 0x0800,
+   0x8f739b73, 0x8e738f73,
+   0x87767376, 0x8673ff74,
+   0x0080, 0x8f739773,
+   0xb976f807, 0x8671ff71,
+   0x, 0x86fe7e7e,
+   0x86ea6a6a, 0x8f768374,
+   0xb976e0c2, 0xbf82,
+   0xb9740002, 0xbf8a,
+   0x95807370, 0xbf81,
 };
 
 
 static const uint32_t cwsr_trap_gfx9_hex[] = {
-   0xbf820001, 0xbf820248,
-   0xb8f8f802, 0x89788678,
-   0xb8eef801, 0x866eff6e,
-   0x0800, 0xbf840003,
+   0xbf820001, 0xbf820254,
+   0xb8f8f802, 0x8978ff78,
+   0x00020006, 0xb8fbf803,
0x866eff78, 0x2000,
-   0xbf840016, 0xb8fbf803,
+   0xbf840009, 0x866eff6d,
+   

[PATCH 2/2] drm/amdkfd: Add gfx11 trap handler

2022-05-16 Thread Eric Huang
From: Jay Cornwall 

Based on gfx10 with following changes:

- GPR_ALLOC.VGPR_SIZE field moved (and size corrected in gfx10)
- s_sendmsg_rtn_b64 replaces some s_sendmsg/s_getreg
- Buffer instructions no longer have direct-to-LDS modifier

Signed-off-by: Jay Cornwall 
Reviewed-by: Laurent Morichetti 
---
 .../gpu/drm/amd/amdkfd/cwsr_trap_handler.h| 463 +-
 .../amd/amdkfd/cwsr_trap_handler_gfx10.asm|  69 ++-
 drivers/gpu/drm/amd/amdkfd/kfd_device.c   |   6 +-
 3 files changed, 507 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h 
b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
index 8cbdc7f519c6..60a81649cf12 100644
--- a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
+++ b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
@@ -776,7 +776,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
0xe0704100, 0x705d0100,
0xe0704200, 0x705d0200,
0xe0704300, 0x705d0300,
-   0xb9702a05, 0x80708170,
+   0xb9703a05, 0x80708170,
0xbf0d9973, 0xbf850002,
0x8f708970, 0xbf820001,
0x8f708a70, 0xb97a1e06,
@@ -855,7 +855,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
0x877aff6d, 0x8000,
0xbf840040, 0x8f7b867b,
0x8f7b827b, 0xbef6037b,
-   0xb9702a05, 0x80708170,
+   0xb9703a05, 0x80708170,
0xbf0d9973, 0xbf850002,
0x8f708970, 0xbf820001,
0x8f708a70, 0xb97a1e06,
@@ -891,7 +891,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
0xbef003ff, 0x0200,
0xbeff0380, 0xbf820003,
0xbef003ff, 0x0400,
-   0xbeff03c1, 0xb97b2a05,
+   0xbeff03c1, 0xb97b3a05,
0x807b817b, 0x8f7b827b,
0x907c9973, 0x877c817c,
0xbf06817c, 0xbf850017,
@@ -939,7 +939,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
0xb96f4306, 0x876fc16f,
0xbf840029, 0x8f6f866f,
0x8f6f826f, 0xbef6036f,
-   0xb9782a05, 0x80788178,
+   0xb9783a05, 0x80788178,
0xbf0d9972, 0xbf850002,
0x8f788978, 0xbf820001,
0x8f788a78, 0xb96e1e06,
@@ -962,7 +962,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
0x907c9972, 0x877c817c,
0xbf06817c, 0xbf850002,
0xbeff0380, 0xbf820001,
-   0xbeff03c1, 0xb96f2a05,
+   0xbeff03c1, 0xb96f3a05,
0x806f816f, 0x8f6f826f,
0x907c9972, 0x877c817c,
0xbf06817c, 0xbf850024,
@@ -1010,7 +1010,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
0x6e5d0100, 0xe0304200,
0x6e5d0200, 0xe0304300,
0x6e5d0300, 0xbf8c3f70,
-   0xb9782a05, 0x80788178,
+   0xb9783a05, 0x80788178,
0xbf0d9972, 0xbf850002,
0x8f788978, 0xbf820001,
0x8f788a78, 0xb96e1e06,
@@ -1037,7 +1037,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
0xbe8c310c, 0xbe8e310e,
0xbf06807c, 0xbf84fff0,
0xba80f801, 0x,
-   0xbf8a, 0xb9782a05,
+   0xbf8a, 0xb9783a05,
0x80788178, 0xbf0d9972,
0xbf850002, 0x8f788978,
0xbf820001, 0x8f788a78,
@@ -2261,7 +2261,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
0xbf8a, 0x877aff6d,
0x8000, 0xbf840040,
0x8f7b867b, 0x8f7b827b,
-   0xbef6037b, 0xb9702a05,
+   0xbef6037b, 0xb9703a05,
0x80708170, 0xbf0d9973,
0xbf850002, 0x8f708970,
0xbf820001, 0x8f708a70,
@@ -2298,7 +2298,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
0x0200, 0xbeff0380,
0xbf820003, 0xbef003ff,
0x0400, 0xbeff03c1,
-   0xb97b2a05, 0x807b817b,
+   0xb97b3a05, 0x807b817b,
0x8f7b827b, 0x907c9973,
0x877c817c, 0xbf06817c,
0xbf850017, 0xbef603ff,
@@ -2345,7 +2345,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
0xbeff03c1, 0xb96f4306,
0x876fc16f, 0xbf840029,
0x8f6f866f, 0x8f6f826f,
-   0xbef6036f, 0xb9782a05,
+   0xbef6036f, 0xb9783a05,
0x80788178, 0xbf0d9972,
0xbf850002, 0x8f788978,
0xbf820001, 0x8f788a78,
@@ -2369,7 +2369,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
0x877c817c, 0xbf06817c,
0xbf850002, 0xbeff0380,
0xbf820001, 0xbeff03c1,
-   0xb96f2a05, 0x806f816f,
+   0xb96f3a05, 0x806f816f,
0x8f6f826f, 0x907c9972,
0x877c817c, 0xbf06817c,
0xbf850024, 0xbef603ff,
@@ -2416,7 +2416,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
0xe0304100, 0x6e5d0100,
0xe0304200, 0x6e5d0200,
0xe0304300, 0x6e5d0300,
-   0xbf8c3f70, 0xb9782a05,
+   0xbf8c3f70, 0xb9783a05,
0x80788178, 0xbf0d9972,
0xbf850002, 0x8f788978,
0xbf820001, 0x8f788a78,
@@ -2444,7 +2444,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
0xbe8e310e, 0xbf06807c,
0xbf84fff0, 0xba80f801,
0x, 0xbf8a,
-   0xb9782a05, 0x80788178,
+   0xb9783a05, 0x80788178,
0xbf0d9972, 0xbf850002,
0x8f788978, 0xbf820001,

Re: [linux-next:master] BUILD REGRESSION 1e1b28b936aed946122b4e0991e7144fdbbfd77e

2022-05-16 Thread Jakub Kicinski
On Sun, 15 May 2022 21:00:21 +0800 kernel test robot wrote:
> tree/branch: 
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
> branch HEAD: 1e1b28b936aed946122b4e0991e7144fdbbfd77e  Add linux-next 
> specific files for 20220513
> 
> Error/Warning reports:
> 
> https://lore.kernel.org/linux-mm/202204181931.klac6fwo-...@intel.com
> https://lore.kernel.org/linux-mm/202204291924.vtgzmeri-...@intel.com
> https://lore.kernel.org/linux-mm/202205031017.4twman3l-...@intel.com
> https://lore.kernel.org/linux-mm/202205041248.wgcwpcev-...@intel.com
> https://lore.kernel.org/linux-mm/202205122113.ulkzd3sz-...@intel.com
> https://lore.kernel.org/linux-mm/202205150051.3rzuooag-...@intel.com
> https://lore.kernel.org/linux-mm/202205150117.sd6hzbvm-...@intel.com
> https://lore.kernel.org/lkml/202205100617.5uum3uet-...@intel.com
> https://lore.kernel.org/llvm/202204210555.dnvfhvib-...@intel.com
> https://lore.kernel.org/llvm/202205060132.uhqyux1l-...@intel.com
> https://lore.kernel.org/llvm/202205120010.zwbednzm-...@intel.com
> https://lore.kernel.org/llvm/202205141122.qihfguem-...@intel.com
> 
> Error/Warning: (recently discovered and may have been fixed)
> 
> : fatal error: ./include/generated/utsrelease.h: No such file 
> or directory
> arch/arm/mach-versatile/versatile.c:56:14: warning: no previous prototype for 
> function 'mmc_status' [-Wmissing-prototypes]
> arch/x86/kvm/pmu.h:20:32: warning: 'vmx_icl_pebs_cpu' defined but not used 
> [-Wunused-const-variable=]
> drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_link_dp.c:5102:7: warning: 
> variable 'allow_lttpr_non_transparent_mode' set but not used 
> [-Wunused-but-set-variable]
> drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_link_dp.c:5147:6: warning: 
> no previous prototype for function 'dp_parse_lttpr_mode' 
> [-Wmissing-prototypes]
> drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c:1364:5: warning: no previous 
> prototype for 'amdgpu_discovery_get_mall_info' [-Wmissing-prototypes]
> drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:1983:6: warning: no previous prototype 
> for function 'gfx_v11_0_rlc_stop' [-Wmissing-prototypes]
> drivers/gpu/drm/amd/amdgpu/soc21.c:171:6: warning: no previous prototype for 
> 'soc21_grbm_select' [-Wmissing-prototypes]
> drivers/gpu/drm/solomon/ssd130x-spi.c:154:35: warning: 'ssd130x_spi_table' 
> defined but not used [-Wunused-const-variable=]
> drivers/hwmon/nct6775-platform.c:199:9: sparse:unsigned char
> drivers/hwmon/nct6775-platform.c:199:9: sparse:void
> drivers/video/fbdev/omap/hwa742.c:492:5: warning: no previous prototype for 
> 'hwa742_update_window_async' [-Wmissing-prototypes]
> fs/buffer.c:2254:5: warning: stack frame size (2144) exceeds limit (1024) in 
> 'block_read_full_folio' [-Wframe-larger-than]
> fs/ntfs/aops.c:378:12: warning: stack frame size (2224) exceeds limit (1024) 
> in 'ntfs_read_folio' [-Wframe-larger-than]
> kernel/trace/fgraph.c:37:12: warning: no previous prototype for 
> 'ftrace_enable_ftrace_graph_caller' [-Wmissing-prototypes]
> kernel/trace/fgraph.c:46:12: warning: no previous prototype for 
> 'ftrace_disable_ftrace_graph_caller' [-Wmissing-prototypes]

Is this report CCed everywhere or there's a reason why netdev@ is CCed?
I'm trying to figure out we need to care and it's not obvious..


Re: [PATCH] drm/amdgpu: Clean up of initializing doorbells for gfx_v9 and gfx_v10

2022-05-16 Thread Alex Deucher
Applied.  Thanks!

Alex

On Mon, May 16, 2022 at 8:01 AM  wrote:
>
> From: Haohui Mai 
>
> Clean up redundant, copy-paste code blocks during the intialization of
> the doorbells in mqd_init().
>
> Signed-off-by: Haohui Mai 
> ---
>  drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 17 -
>  drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c  | 17 -
>  2 files changed, 34 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
> index 4b66b9c93754..12f63d6aab12 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
> @@ -6919,23 +6919,6 @@ static int gfx_v10_0_compute_mqd_init(struct 
> amdgpu_device *adev, void *m,
> mqd->cp_hqd_pq_wptr_poll_addr_lo = wb_gpu_addr & 0xfffc;
> mqd->cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits(wb_gpu_addr) & 
> 0x;
>
> -   tmp = 0;
> -   /* enable the doorbell if requested */
> -   if (prop->use_doorbell) {
> -   tmp = RREG32_SOC15(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL);
> -   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
> -   DOORBELL_OFFSET, prop->doorbell_index);
> -
> -   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
> -   DOORBELL_EN, 1);
> -   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
> -   DOORBELL_SOURCE, 0);
> -   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
> -   DOORBELL_HIT, 0);
> -   }
> -
> -   mqd->cp_hqd_pq_doorbell_control = tmp;
> -
> /* reset read and write pointers, similar to CP_RB0_WPTR/_RPTR */
> mqd->cp_hqd_pq_rptr = RREG32_SOC15(GC, 0, mmCP_HQD_PQ_RPTR);
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> index 83639b5ea6a9..f49a2dd89ee7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> @@ -3535,23 +3535,6 @@ static int gfx_v9_0_mqd_init(struct amdgpu_ring *ring)
> mqd->cp_hqd_pq_wptr_poll_addr_lo = wb_gpu_addr & 0xfffc;
> mqd->cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits(wb_gpu_addr) & 
> 0x;
>
> -   tmp = 0;
> -   /* enable the doorbell if requested */
> -   if (ring->use_doorbell) {
> -   tmp = RREG32_SOC15(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL);
> -   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
> -   DOORBELL_OFFSET, ring->doorbell_index);
> -
> -   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
> -DOORBELL_EN, 1);
> -   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
> -DOORBELL_SOURCE, 0);
> -   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
> -DOORBELL_HIT, 0);
> -   }
> -
> -   mqd->cp_hqd_pq_doorbell_control = tmp;
> -
> /* reset read and write pointers, similar to CP_RB0_WPTR/_RPTR */
> ring->wptr = 0;
> mqd->cp_hqd_pq_rptr = RREG32_SOC15(GC, 0, mmCP_HQD_PQ_RPTR);
> --
> 2.25.1
>


Re: VCN_INFO_TABLE_MAX_NUM_INSTANCES vs AMDGPU_MAX_VCN_INSTANCES

2022-05-16 Thread Ernst Sjöstrand
Looks good to me!

Den mån 16 maj 2022 kl 20:15 skrev Alex Deucher :

> On Mon, May 16, 2022 at 2:10 PM Christian König
>  wrote:
> >
> > Am 16.05.22 um 19:49 schrieb Ernst Sjöstrand:
> >
> > Den mån 16 maj 2022 kl 17:13 skrev Alex Deucher :
> >>
> >> On Sun, May 15, 2022 at 11:46 AM Ernst Sjöstrand 
> wrote:
> >> >
> >> > smatch found this problem on amd-staging-drm-next:
> >> >
> >> > drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c:1443
> amdgpu_discovery_get_vcn_info() error: buffer overflow
> 'adev->vcn.vcn_codec_disable_mask' 2 <= 3
> >> >
> >> > This is caused by:
> >> > #define AMDGPU_MAX_VCN_INSTANCES 2
> >> > #define VCN_INFO_TABLE_MAX_NUM_INSTANCES 4
> >> >
> >> > Can we just drop VCN_INFO_TABLE_MAX_NUM_INSTANCES completely and use
> AMDGPU_MAX_VCN_INSTANCES everywhere instead (and bump it to 4)?
> >>
> >> We should be able to bump AMDGPU_MAX_VCN_INSTANCES to 4 (although it
> >> would waste some memory in the places it is used at this point).
> >> VCN_INFO_TABLE_MAX_NUM_INSTANCES is part of a firmware structure so we
> >> can't change that without breaking the firmware structure.
> >>
> >> Alex
> >
> >
> > It would be nice to get rid of this pattern and make sure it doesn't
> happen again when the VCN info table is raised to 5.
> > It's very similar to the HWIP_MAX_INSTANCE issue.
> >
> >
> > No, as Alex explained that distinction is intentional.
> >
> > The firmware definition is 4 for future extensions, that doesn't mean
> that this is currently used.
> >
> > There is currently simply no need to set AMDGPU_MAX_VCN_INSTANCES to
> more than 2.
>
> Right.  The attached patch should protect against the scenario you are
> envisioning.
>
> Alex
>
> >
> > Regards,
> > Christian.
> >
> >
> > //E
> >
> >
>


[PATCH] drm/amdgpu/discovery: validate VCN and SDMA instances

2022-05-16 Thread Alex Deucher
Validate the VCN and SDMA instances against the driver
structure sizes to make sure we don't get into a
situation where the firmware reports more instances than
the driver supports.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 1f4e07a32445..2c4f1adb5343 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -1137,13 +1137,24 @@ static int amdgpu_discovery_reg_base_init(struct 
amdgpu_device *adev)
adev->vcn.vcn_config[adev->vcn.num_vcn_inst] =
ip->revision & 0xc0;
ip->revision &= ~0xc0;
-   adev->vcn.num_vcn_inst++;
+   if (adev->vcn.num_vcn_inst < 
AMDGPU_MAX_VCN_INSTANCES)
+   adev->vcn.num_vcn_inst++;
+   else
+   dev_err(adev->dev, "Too many VCN 
instances: %d vs %d\n",
+   adev->vcn.num_vcn_inst + 1,
+   AMDGPU_MAX_VCN_INSTANCES);
}
if (le16_to_cpu(ip->hw_id) == SDMA0_HWID ||
le16_to_cpu(ip->hw_id) == SDMA1_HWID ||
le16_to_cpu(ip->hw_id) == SDMA2_HWID ||
-   le16_to_cpu(ip->hw_id) == SDMA3_HWID)
-   adev->sdma.num_instances++;
+   le16_to_cpu(ip->hw_id) == SDMA3_HWID) {
+   if (adev->sdma.num_instances < 
AMDGPU_MAX_SDMA_INSTANCES)
+   adev->sdma.num_instances++;
+   else
+   dev_err(adev->dev, "Too many SDMA 
instances: %d vs %d\n",
+   adev->sdma.num_instances + 1,
+   AMDGPU_MAX_SDMA_INSTANCES);
+   }
 
if (le16_to_cpu(ip->hw_id) == UMC_HWID)
adev->gmc.num_umc++;
-- 
2.35.3



Re: VCN_INFO_TABLE_MAX_NUM_INSTANCES vs AMDGPU_MAX_VCN_INSTANCES

2022-05-16 Thread Alex Deucher
On Mon, May 16, 2022 at 2:10 PM Christian König
 wrote:
>
> Am 16.05.22 um 19:49 schrieb Ernst Sjöstrand:
>
> Den mån 16 maj 2022 kl 17:13 skrev Alex Deucher :
>>
>> On Sun, May 15, 2022 at 11:46 AM Ernst Sjöstrand  wrote:
>> >
>> > smatch found this problem on amd-staging-drm-next:
>> >
>> > drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c:1443 
>> > amdgpu_discovery_get_vcn_info() error: buffer overflow 
>> > 'adev->vcn.vcn_codec_disable_mask' 2 <= 3
>> >
>> > This is caused by:
>> > #define AMDGPU_MAX_VCN_INSTANCES 2
>> > #define VCN_INFO_TABLE_MAX_NUM_INSTANCES 4
>> >
>> > Can we just drop VCN_INFO_TABLE_MAX_NUM_INSTANCES completely and use 
>> > AMDGPU_MAX_VCN_INSTANCES everywhere instead (and bump it to 4)?
>>
>> We should be able to bump AMDGPU_MAX_VCN_INSTANCES to 4 (although it
>> would waste some memory in the places it is used at this point).
>> VCN_INFO_TABLE_MAX_NUM_INSTANCES is part of a firmware structure so we
>> can't change that without breaking the firmware structure.
>>
>> Alex
>
>
> It would be nice to get rid of this pattern and make sure it doesn't happen 
> again when the VCN info table is raised to 5.
> It's very similar to the HWIP_MAX_INSTANCE issue.
>
>
> No, as Alex explained that distinction is intentional.
>
> The firmware definition is 4 for future extensions, that doesn't mean that 
> this is currently used.
>
> There is currently simply no need to set AMDGPU_MAX_VCN_INSTANCES to more 
> than 2.

Right.  The attached patch should protect against the scenario you are
envisioning.

Alex

>
> Regards,
> Christian.
>
>
> //E
>
>
From 6fecd3c86fbb7b89d59d16cffea438e5b2a5915c Mon Sep 17 00:00:00 2001
From: Alex Deucher 
Date: Mon, 16 May 2022 14:12:33 -0400
Subject: [PATCH] drm/amdgpu/discovery: validate VCN and SDMA instances

Validate the VCN and SDMA instances against the driver
structure sizes to make sure we don't get into a
situation where the firmware reports more instances than
the driver supports.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 1f4e07a32445..2c4f1adb5343 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -1137,13 +1137,24 @@ static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
 adev->vcn.vcn_config[adev->vcn.num_vcn_inst] =
 	ip->revision & 0xc0;
 ip->revision &= ~0xc0;
-adev->vcn.num_vcn_inst++;
+if (adev->vcn.num_vcn_inst < AMDGPU_MAX_VCN_INSTANCES)
+	adev->vcn.num_vcn_inst++;
+else
+	dev_err(adev->dev, "Too many VCN instances: %d vs %d\n",
+		adev->vcn.num_vcn_inst + 1,
+		AMDGPU_MAX_VCN_INSTANCES);
 			}
 			if (le16_to_cpu(ip->hw_id) == SDMA0_HWID ||
 			le16_to_cpu(ip->hw_id) == SDMA1_HWID ||
 			le16_to_cpu(ip->hw_id) == SDMA2_HWID ||
-			le16_to_cpu(ip->hw_id) == SDMA3_HWID)
-adev->sdma.num_instances++;
+			le16_to_cpu(ip->hw_id) == SDMA3_HWID) {
+if (adev->sdma.num_instances < AMDGPU_MAX_SDMA_INSTANCES)
+	adev->sdma.num_instances++;
+else
+	dev_err(adev->dev, "Too many SDMA instances: %d vs %d\n",
+		adev->sdma.num_instances + 1,
+		AMDGPU_MAX_SDMA_INSTANCES);
+			}
 
 			if (le16_to_cpu(ip->hw_id) == UMC_HWID)
 adev->gmc.num_umc++;
-- 
2.35.3



Re: VCN_INFO_TABLE_MAX_NUM_INSTANCES vs AMDGPU_MAX_VCN_INSTANCES

2022-05-16 Thread Christian König

Am 16.05.22 um 19:49 schrieb Ernst Sjöstrand:

Den mån 16 maj 2022 kl 17:13 skrev Alex Deucher :

On Sun, May 15, 2022 at 11:46 AM Ernst Sjöstrand
 wrote:
>
> smatch found this problem on amd-staging-drm-next:
>
> drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c:1443
amdgpu_discovery_get_vcn_info() error: buffer overflow
'adev->vcn.vcn_codec_disable_mask' 2 <= 3
>
> This is caused by:
> #define AMDGPU_MAX_VCN_INSTANCES 2
> #define VCN_INFO_TABLE_MAX_NUM_INSTANCES 4
>
> Can we just drop VCN_INFO_TABLE_MAX_NUM_INSTANCES completely and
use AMDGPU_MAX_VCN_INSTANCES everywhere instead (and bump it to 4)?

We should be able to bump AMDGPU_MAX_VCN_INSTANCES to 4 (although it
would waste some memory in the places it is used at this point).
VCN_INFO_TABLE_MAX_NUM_INSTANCES is part of a firmware structure so we
can't change that without breaking the firmware structure.

Alex


It would be nice to get rid of this pattern and make sure it doesn't 
happen again when the VCN info table is raised to 5.

It's very similar to the HWIP_MAX_INSTANCE issue.


No, as Alex explained that distinction is intentional.

The firmware definition is 4 for future extensions, that doesn't mean 
that this is currently used.


There is currently simply no need to set AMDGPU_MAX_VCN_INSTANCES to 
more than 2.


Regards,
Christian.



//E



Re: VCN_INFO_TABLE_MAX_NUM_INSTANCES vs AMDGPU_MAX_VCN_INSTANCES

2022-05-16 Thread Ernst Sjöstrand
Den mån 16 maj 2022 kl 17:13 skrev Alex Deucher :

> On Sun, May 15, 2022 at 11:46 AM Ernst Sjöstrand  wrote:
> >
> > smatch found this problem on amd-staging-drm-next:
> >
> > drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c:1443
> amdgpu_discovery_get_vcn_info() error: buffer overflow
> 'adev->vcn.vcn_codec_disable_mask' 2 <= 3
> >
> > This is caused by:
> > #define AMDGPU_MAX_VCN_INSTANCES 2
> > #define VCN_INFO_TABLE_MAX_NUM_INSTANCES 4
> >
> > Can we just drop VCN_INFO_TABLE_MAX_NUM_INSTANCES completely and use
> AMDGPU_MAX_VCN_INSTANCES everywhere instead (and bump it to 4)?
>
> We should be able to bump AMDGPU_MAX_VCN_INSTANCES to 4 (although it
> would waste some memory in the places it is used at this point).
> VCN_INFO_TABLE_MAX_NUM_INSTANCES is part of a firmware structure so we
> can't change that without breaking the firmware structure.
>
> Alex
>

It would be nice to get rid of this pattern and make sure it doesn't happen
again when the VCN info table is raised to 5.
It's very similar to the HWIP_MAX_INSTANCE issue.

//E


Re: [PATCH v2 00/19] DC/DM changes needed for amdgpu PSR-SU

2022-05-16 Thread Daniel Vetter
On Mon, 16 May 2022 at 18:23, Leo Li  wrote:
>
>
>
> On 2022-05-12 13:39, Daniel Vetter wrote:
> > On Thu, 12 May 2022 at 19:22, Zhang, Dingchen (David)
> >  wrote:
> >>
> >> [AMD Official Use Only - General]
> >>
> >> Hi Daniel
> >>
> >> Thanks for your comments and explanations. I replied in-line and look 
> >> forward to more discussion.
> >>
> >> regards
> >> David
> >>
> >>
> >> From: Daniel Vetter 
> >> Sent: Thursday, May 12, 2022 7:22 AM
> >> To: Alex Deucher 
> >> Cc: Zhang, Dingchen (David) ; amd-gfx list 
> >> ; Wang, Chao-kai (Stylon) 
> >> ; Li, Sun peng (Leo) ; Wentland, 
> >> Harry ; Zhuo, Qingqing (Lillian) 
> >> ; Siqueira, Rodrigo ; Li, 
> >> Roman ; Chiu, Solomon ; Zuo, Jerry 
> >> ; Pillai, Aurabindo ; Lin, 
> >> Wayne ; Lakha, Bhawanpreet ; 
> >> Gutierrez, Agustin ; Kotarac, Pavle 
> >> 
> >> Subject: Re: [PATCH v2 00/19] DC/DM changes needed for amdgpu PSR-SU
> >>
> >> On Wed, 11 May 2022 at 17:35, Alex Deucher  wrote:
> >>>
> >>> On Tue, May 10, 2022 at 4:45 PM David Zhang  
> >>> wrote:
> 
>  changes in v2:
>  ---
>  - set vsc_packet_rev2 for PSR1 which is safer
>  - add exposure of AMD specific DPCD regs for PSR-SU-RC (rate-control)
>  - add DC/DM change related to amdgpu PSR-SU-RC
> 
> 
>  David Zhang (18):
> drm/amd/display: align dmub cmd header to latest dmub FW to support
>   PSR-SU
> drm/amd/display: feed PSR-SU as psr version to dmub FW
> drm/amd/display: combine dirty rectangles in DMUB FW
> drm/amd/display: update GSP1 generic info packet for PSRSU
> drm/amd/display: revise Start/End SDP data
> drm/amd/display: program PSR2 DPCD Configuration
> drm/amd/display: Passing Y-granularity to dmub fw
> drm/amd/display: Set default value of line_capture_indication
> drm/amd/display: add vline time in micro sec to PSR context
> drm/amd/display: fix system hang when PSR exits
> drm/amd/display: Set PSR level to enable ALPM by default
> drm/amd/display: use HW lock mgr for PSR-SU
> drm/amd/display: PSRSU+DSC WA for specific TCON
> drm/amd/display: add shared helpers to update psr config fields to
>   power module
> drm/amd/display: calculate psr config settings in runtime in DM
> drm/amd/display: update cursor position to DMUB FW
> drm/amd/display: expose AMD source specific DPCD for FreeSync PSR
>   support
> drm/amd/display: PSR-SU rate control support in DC
> 
>  Leo Li (1):
> drm/amd/display: Implement MPO PSR SU
> >>>
> >>> A couple of suggestions from Daniel on IRC:
> >>> 1.  Might be good to extract the "calculate total crtc damage" code
> >>> from i915 in intel_psr2_sel_fetch_update, stuff that into damage
> >>> helpers and reuse for i915 and amdgpu
> >>
> >> To expand a bit on this. There is currently a helper for total damage,
> >> but it's at the fb/plane level for drivers which need to upload
> >> buffers (usb/spi or virtual) drm_atomic_helper_damage_merged(). That
> >> one probably needs to be renamed to signify it's about the plane, and
> >> then we need a new drm_atomic_helper_crtc_damage_merged() which
> >> (extract from i915 code ideally) which computes total crtc damage for
> >> stuff like psr2/su or the command mode dsi panels (unfortunately none
> >> of the drivers for android for these panels have been upstreamed yet).
> >>
> >> <<<
> >> Checked the DRM comment for the helper `drm_atomic_helper_damage_merged()` 
> >> and
> >> quoted below:
> >> *
> >> Drivers might want to use the helper functions 
> >> drm_atomic_helper_damage_iter_init()
> >> and drm_atomic_helper_damage_iter_next() or 
> >> drm_atomic_helper_damage_merged()
> >> if the driver can only handle a single damage region at most.
> >> *
> >> Currently for amdgpu, the multiple damage clips combination (merging) is 
> >> handled in
> >> DMUB firmware. And the DRM comment shows that the usage of 
> >> "damage_merged()"
> >> helper is for the driver which can only handle single damage region at 
> >> most.
> >>
> >> Since AMDGPU is capable of handling multiple damaged clip (in DMUB FW), 
> >> can I
> >> understand that the group of helpers of `damage_merged()` in DRM is not 
> >> mandatory
> >> but optional?
> >
> > Ah I didn't see from a quick read that this was possible. How does
> > this work when the plane is enabled/disabled or resized or moved?
> > -Daniel
>
> Hi Daniel,
>
> When a plane is disabled, enabled, and/or resized(*), PSR is temporarily
> disabled. The mechanism to do so isn't in this patchset, but was added
> when PSR1 was first introduced to amdgpu_dm.
>
> In short, amdgpu_dm will disable PSR whenever DC requires a full update
> to program an atomic state (needs bandwidth recalculations and/or
> shuffling hw resources). For DC, enabling, disabling, and changing the
> scaling of a plane are considered full updates.
>
> When the plane is 

Re: [PATCH v2 00/19] DC/DM changes needed for amdgpu PSR-SU

2022-05-16 Thread Leo Li




On 2022-05-12 13:39, Daniel Vetter wrote:

On Thu, 12 May 2022 at 19:22, Zhang, Dingchen (David)
 wrote:


[AMD Official Use Only - General]

Hi Daniel

Thanks for your comments and explanations. I replied in-line and look forward 
to more discussion.

regards
David


From: Daniel Vetter 
Sent: Thursday, May 12, 2022 7:22 AM
To: Alex Deucher 
Cc: Zhang, Dingchen (David) ; amd-gfx list ; Wang, Chao-kai (Stylon) ; Li, 
Sun peng (Leo) ; Wentland, Harry ; Zhuo, Qingqing (Lillian) ; Siqueira, Rodrigo 
; Li, Roman ; Chiu, Solomon ; Zuo, Jerry ; Pillai, Aurabindo 
; Lin, Wayne ; Lakha, Bhawanpreet ; Gutierrez, Agustin 
; Kotarac, Pavle 
Subject: Re: [PATCH v2 00/19] DC/DM changes needed for amdgpu PSR-SU

On Wed, 11 May 2022 at 17:35, Alex Deucher  wrote:


On Tue, May 10, 2022 at 4:45 PM David Zhang  wrote:


changes in v2:
---
- set vsc_packet_rev2 for PSR1 which is safer
- add exposure of AMD specific DPCD regs for PSR-SU-RC (rate-control)
- add DC/DM change related to amdgpu PSR-SU-RC


David Zhang (18):
   drm/amd/display: align dmub cmd header to latest dmub FW to support
 PSR-SU
   drm/amd/display: feed PSR-SU as psr version to dmub FW
   drm/amd/display: combine dirty rectangles in DMUB FW
   drm/amd/display: update GSP1 generic info packet for PSRSU
   drm/amd/display: revise Start/End SDP data
   drm/amd/display: program PSR2 DPCD Configuration
   drm/amd/display: Passing Y-granularity to dmub fw
   drm/amd/display: Set default value of line_capture_indication
   drm/amd/display: add vline time in micro sec to PSR context
   drm/amd/display: fix system hang when PSR exits
   drm/amd/display: Set PSR level to enable ALPM by default
   drm/amd/display: use HW lock mgr for PSR-SU
   drm/amd/display: PSRSU+DSC WA for specific TCON
   drm/amd/display: add shared helpers to update psr config fields to
 power module
   drm/amd/display: calculate psr config settings in runtime in DM
   drm/amd/display: update cursor position to DMUB FW
   drm/amd/display: expose AMD source specific DPCD for FreeSync PSR
 support
   drm/amd/display: PSR-SU rate control support in DC

Leo Li (1):
   drm/amd/display: Implement MPO PSR SU


A couple of suggestions from Daniel on IRC:
1.  Might be good to extract the "calculate total crtc damage" code
from i915 in intel_psr2_sel_fetch_update, stuff that into damage
helpers and reuse for i915 and amdgpu


To expand a bit on this. There is currently a helper for total damage,
but it's at the fb/plane level for drivers which need to upload
buffers (usb/spi or virtual) drm_atomic_helper_damage_merged(). That
one probably needs to be renamed to signify it's about the plane, and
then we need a new drm_atomic_helper_crtc_damage_merged() which
(extract from i915 code ideally) which computes total crtc damage for
stuff like psr2/su or the command mode dsi panels (unfortunately none
of the drivers for android for these panels have been upstreamed yet).

<<<
Checked the DRM comment for the helper `drm_atomic_helper_damage_merged()` and
quoted below:
*
Drivers might want to use the helper functions 
drm_atomic_helper_damage_iter_init()
and drm_atomic_helper_damage_iter_next() or drm_atomic_helper_damage_merged()
if the driver can only handle a single damage region at most.
*
Currently for amdgpu, the multiple damage clips combination (merging) is 
handled in
DMUB firmware. And the DRM comment shows that the usage of "damage_merged()"
helper is for the driver which can only handle single damage region at most.

Since AMDGPU is capable of handling multiple damaged clip (in DMUB FW), can I
understand that the group of helpers of `damage_merged()` in DRM is not 
mandatory
but optional?


Ah I didn't see from a quick read that this was possible. How does
this work when the plane is enabled/disabled or resized or moved?
-Daniel


Hi Daniel,

When a plane is disabled, enabled, and/or resized(*), PSR is temporarily 
disabled. The mechanism to do so isn't in this patchset, but was added 
when PSR1 was first introduced to amdgpu_dm.


In short, amdgpu_dm will disable PSR whenever DC requires a full update 
to program an atomic state (needs bandwidth recalculations and/or 
shuffling hw resources). For DC, enabling, disabling, and changing the 
scaling of a plane are considered full updates.


When the plane is moved, both the old and new plane bounds are given to 
FW as dirty rectangles. (*)Resize should fall under the same bucket, 
though DC would consider that as a full update. I think disabling PSR 
would take precedence... will give this another spin to check.


Thanks,
Leo




I also think that the split between dc and kms is a bit funny, I'd put
only the resulting damage rect into dc_pipe and do the computation of
that in the drm/kms linux code outside of dc functions (or in the glue
code for dc), since I'm assuming on windows it's completely different
approach in how you compute damage. Especially once we have the crtc
damage helper on linux.


2.  The 

Re: [PATCH 2/3] drm/amdgpu: add AMDGPU_VM_NOALLOC

2022-05-16 Thread Christian König

I don't have access to any gfx10 hardware.

Can you give me a dmesg and/or backtrace, etc..?

I can't push this unless it's working properly.

Christian.

Am 16.05.22 um 14:56 schrieb Marek Olšák:

Reproduction steps:
- use mesa/main on gfx10.3 (not sure what other GPUs do)
- run: radeonsi_mall_noalloc=true glxgears

Marek

On Mon, May 16, 2022 at 7:53 AM Christian König 
 wrote:


Crap, do you have a link to the failure?

Am 16.05.22 um 13:10 schrieb Marek Olšák:

I forgot to say: The NOALLOC flag causes an allocation failure,
so there is a kernel bug somewhere.

Marek

On Mon, May 16, 2022 at 7:06 AM Marek Olšák  wrote:

FYI, I think it's time to merge this because the Mesa commits
are going to be merged in ~30 minutes if Gitlab CI is green,
and that includes updated amdgpu_drm.h.

Marek

On Wed, May 11, 2022 at 2:55 PM Marek Olšák
 wrote:

Ok sounds good.

Marek

On Wed., May 11, 2022, 03:43 Christian König,
 wrote:

It really *is* a NOALLOC feature. In other words
there is no latency improvement on reads because the
cache is always checked, even with the noalloc flag set.

The only thing it affects is that misses not enter
the cache and so don't cause any additional pressure
on evicting cache lines.

You might want to double check with the hardware
guys, but I'm something like 95% sure that it works
this way.

Christian.

Am 11.05.22 um 09:22 schrieb Marek Olšák:

Bypass means that the contents of the cache are
ignored, which decreases latency at the cost of no
coherency between bypassed and normal memory
requests. NOA (noalloc) means that the cache is
checked and can give you cache hits, but misses are
not cached and the overall latency is higher. I
don't know what the hw does, but I hope it was
misnamed and it really means bypass because there is
no point in doing cache lookups on every memory
request if the driver wants to disable caching to
*decrease* latency in the situations when the cache
isn't helping.

Marek

On Wed, May 11, 2022 at 2:15 AM Lazar, Lijo
 wrote:



On 5/11/2022 11:36 AM, Christian König wrote:
> Mhm, it doesn't really bypass MALL. It just
doesn't allocate any MALL
> entries on write.
>
> How about AMDGPU_VM_PAGE_NO_MALL ?

One more - AMDGPU_VM_PAGE_LLC_* [ LLC = last
level cache, * = some sort
of attribute which decides LLC behaviour]

Thanks,
Lijo

>
> Christian.
>
> Am 10.05.22 um 23:21 schrieb Marek Olšák:
>> A better name would be:
>> AMDGPU_VM_PAGE_BYPASS_MALL
>>
>> Marek
>>
>> On Fri, May 6, 2022 at 7:23 AM Christian König
>>  wrote:
>>
>>     Add the AMDGPU_VM_NOALLOC flag to let
userspace control MALL
>>     allocation.
>>
>>     Only compile tested!
>>
>>     Signed-off-by: Christian König

>>     ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 ++
>>   drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 3 +++
>>   drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 3 +++
>>   include/uapi/drm/amdgpu_drm.h        | 2 ++
>>      4 files changed, 10 insertions(+)
>>
>>     diff --git
a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>  b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>     index bf97d8f07f57..d8129626581f 100644
>>     --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>     +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>     @@ -650,6 +650,8 @@ uint64_t
amdgpu_gem_va_map_flags(struct
>>     amdgpu_device *adev, uint32_t flags)
>> pte_flag |= AMDGPU_PTE_WRITEABLE;
>>             if (flags & AMDGPU_VM_PAGE_PRT)
>> pte_flag |= AMDGPU_PTE_PRT;
>>     +       if 

Re: [PATCH] drm/amdgpu: Fix multiple GPU resets in XGMI hive.

2022-05-16 Thread Andrey Grodzovsky


On 2022-05-16 11:08, Christian König wrote:

Am 16.05.22 um 16:12 schrieb Andrey Grodzovsky:


Ping



Ah, yes sorry.


Andrey

On 2022-05-13 11:41, Andrey Grodzovsky wrote:

Yes, exactly that's the idea.

Basically the reset domain knowns which amdgpu devices it needs to 
reset together.


If you then represent that so that you always have a hive even when 
you only have one device in it, or if you put an array of devices 
which needs to be reset together into the reset domain doesn't matter.


Maybe go for the later approach, that is probably a bit cleaner and 
less code to change.


Christian.



Unfortunately this approach raises also a few  difficulties -
First - if holding array of devices in reset_domain then when you 
come to GPU reset function you don't really know which adev is the 
one triggered the reset and this is actually essential to some 
procedures like emergency restart.


What is "emergency restart"? That's not some requirement I know about.



Emergency restart is something u can see at the beginning of 
amdgpu_gpu_recover function - it's a historical work around for some 
type of ASICs who weren't able to do full reset I think.  We should 
eventually remove it bu for now I thin it's still in use.







Second - in XGMI case we must take into account that one of the hive 
members might go away in runtime (i could do echo 1 > 
/sysfs/pci_id/remove on it for example at any moment) - so now we 
need to maintain this array and mark such entry with NULL probably 
on XGMI node removal , and then there might be hot insertion and all 
this adds more complications.


I now tend to prefer your initial solution for it's simplicity and 
the result will be what we need -


"E.g. in the reset code (either before or after the reset, that's 
debatable) you do something like this:


for (i = 0; i < num_ring; ++i)
cancel_delayed_work(ring[i]->scheduler)
cancel_work(adev->ras_work);
cancel_work(adev->iofault_work);
cancel_work(adev->debugfs_work);
"


Works for me. I already expected that switching over the reset to be 
based on the reset context wouldn't be that easy.


Regards,
Christian.



Ok - i will resend a patch.

Andrey






Let me know what you think.

Andrey 


Re: VCN_INFO_TABLE_MAX_NUM_INSTANCES vs AMDGPU_MAX_VCN_INSTANCES

2022-05-16 Thread Alex Deucher
On Sun, May 15, 2022 at 11:46 AM Ernst Sjöstrand  wrote:
>
> smatch found this problem on amd-staging-drm-next:
>
> drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c:1443 
> amdgpu_discovery_get_vcn_info() error: buffer overflow 
> 'adev->vcn.vcn_codec_disable_mask' 2 <= 3
>
> This is caused by:
> #define AMDGPU_MAX_VCN_INSTANCES 2
> #define VCN_INFO_TABLE_MAX_NUM_INSTANCES 4
>
> Can we just drop VCN_INFO_TABLE_MAX_NUM_INSTANCES completely and use 
> AMDGPU_MAX_VCN_INSTANCES everywhere instead (and bump it to 4)?

We should be able to bump AMDGPU_MAX_VCN_INSTANCES to 4 (although it
would waste some memory in the places it is used at this point).
VCN_INFO_TABLE_MAX_NUM_INSTANCES is part of a firmware structure so we
can't change that without breaking the firmware structure.

Alex


>
> //E
>


Re: [PATCH] drm/amdgpu: Fix multiple GPU resets in XGMI hive.

2022-05-16 Thread Christian König

Am 16.05.22 um 16:12 schrieb Andrey Grodzovsky:


Ping



Ah, yes sorry.


Andrey

On 2022-05-13 11:41, Andrey Grodzovsky wrote:

Yes, exactly that's the idea.

Basically the reset domain knowns which amdgpu devices it needs to 
reset together.


If you then represent that so that you always have a hive even when 
you only have one device in it, or if you put an array of devices 
which needs to be reset together into the reset domain doesn't matter.


Maybe go for the later approach, that is probably a bit cleaner and 
less code to change.


Christian.



Unfortunately this approach raises also a few  difficulties -
First - if holding array of devices in reset_domain then when you 
come to GPU reset function you don't really know which adev is the 
one triggered the reset and this is actually essential to some 
procedures like emergency restart.


What is "emergency restart"? That's not some requirement I know about.



Second - in XGMI case we must take into account that one of the hive 
members might go away in runtime (i could do echo 1 > 
/sysfs/pci_id/remove on it for example at any moment) - so now we 
need to maintain this array and mark such entry with NULL probably on 
XGMI node removal , and then there might be hot insertion and all 
this adds more complications.


I now tend to prefer your initial solution for it's simplicity and 
the result will be what we need -


"E.g. in the reset code (either before or after the reset, that's 
debatable) you do something like this:


for (i = 0; i < num_ring; ++i)
cancel_delayed_work(ring[i]->scheduler)
cancel_work(adev->ras_work);
cancel_work(adev->iofault_work);
cancel_work(adev->debugfs_work);
"


Works for me. I already expected that switching over the reset to be 
based on the reset context wouldn't be that easy.


Regards,
Christian.



Let me know what you think.

Andrey 


Re: [PATCH v12] drm/amdgpu: add drm buddy support to amdgpu

2022-05-16 Thread Alex Deucher
On Mon, May 16, 2022 at 8:40 AM Mike Lothian  wrote:
>
> Hi
>
> The merge window for 5.19 will probably be opening next week, has
> there been any progress with this bug?

It took a while to find a combination of GPUs that would repro the
issue, but now that we can, it is still being investigated.

Alex

>
> Thanks
>
> Mike
>
> On Mon, 2 May 2022 at 17:31, Mike Lothian  wrote:
> >
> > On Mon, 2 May 2022 at 16:54, Arunpravin Paneer Selvam
> >  wrote:
> > >
> > >
> > >
> > > On 5/2/2022 8:41 PM, Mike Lothian wrote:
> > > > On Wed, 27 Apr 2022 at 12:55, Mike Lothian  wrote:
> > > >> On Tue, 26 Apr 2022 at 17:36, Christian König 
> > > >>  wrote:
> > > >>> Hi Mike,
> > > >>>
> > > >>> sounds like somehow stitching together the SG table for PRIME doesn't
> > > >>> work any more with this patch.
> > > >>>
> > > >>> Can you try with P2P DMA disabled?
> > > >> -CONFIG_PCI_P2PDMA=y
> > > >> +# CONFIG_PCI_P2PDMA is not set
> > > >>
> > > >> If that's what you're meaning, then there's no difference, I'll upload
> > > >> my dmesg to the gitlab issue
> > > >>
> > > >>> Apart from that can you take a look Arun?
> > > >>>
> > > >>> Thanks,
> > > >>> Christian.
> > > > Hi
> > > >
> > > > Have you had any success in replicating this?
> > > Hi Mike,
> > > I couldn't replicate on my Raven APU machine. I see you have 2 cards
> > > initialized, one is Renoir
> > > and the other is Navy Flounder. Could you give some more details, are
> > > you running Gravity Mark
> > > on Renoir and what is your system RAM configuration?
> > > >
> > > > Cheers
> > > >
> > > > Mike
> > >
> > Hi
> >
> > It's a PRIME laptop, it failed on the RENOIR too, it caused a lockup,
> > but systemd managed to capture it, I'll attach it to the issue
> >
> > I've got 64GB RAM, the 6800M has 12GB VRAM
> >
> > Cheers
> >
> > Mike


[PATCH] drm/amdkfd: simplify cpu hive assignment

2022-05-16 Thread Jonathan Kim
CPU hive assignment currently assumes when a GPU hive is connected_to_cpu,
there is only one hive in the system.

Only assign CPUs to the hive if they are explicitly directly connected to
the GPU hive to get rid of the need for this assumption.

It's more efficient to do this when querying IO links since other non-CRAT
info has to be filled in anyways.  Also, stop re-assigning the
same CPU to the same GPU hive if it has already been done before.

Signed-off-by: Jonathan Kim 
---
 drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 22 ++
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index 2e20f54bb147..8d50d207cf66 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -1271,6 +1271,12 @@ static void kfd_fill_iolink_non_crat_info(struct 
kfd_topology_device *dev)
if (!peer_dev)
continue;
 
+   /* Include the CPU peer in GPU hive if connected over xGMI. */
+   if (!peer_dev->gpu && !peer_dev->node_props.hive_id &&
+   dev->node_props.hive_id &&
+   dev->gpu->adev->gmc.xgmi.connected_to_cpu)
+   peer_dev->node_props.hive_id = dev->node_props.hive_id;
+
list_for_each_entry(inbound_link, _dev->io_link_props,
list) {
if (inbound_link->node_to != link->node_from)
@@ -1302,22 +1308,6 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
 
pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id);
 
-   /* Include the CPU in xGMI hive if xGMI connected by assigning it the 
hive ID. */
-   if (gpu->hive_id && gpu->adev->gmc.xgmi.connected_to_cpu) {
-   struct kfd_topology_device *top_dev;
-
-   down_read(_lock);
-
-   list_for_each_entry(top_dev, _device_list, list) {
-   if (top_dev->gpu)
-   break;
-
-   top_dev->node_props.hive_id = gpu->hive_id;
-   }
-
-   up_read(_lock);
-   }
-
/* Check to see if this gpu device exists in the topology_device_list.
 * If so, assign the gpu to that device,
 * else create a Virtual CRAT for this gpu device and then parse that
-- 
2.25.1



Re: [PATCH] drm/amdgpu: Fix multiple GPU resets in XGMI hive.

2022-05-16 Thread Andrey Grodzovsky

Ping

Andrey

On 2022-05-13 11:41, Andrey Grodzovsky wrote:

Yes, exactly that's the idea.

Basically the reset domain knowns which amdgpu devices it needs to 
reset together.


If you then represent that so that you always have a hive even when 
you only have one device in it, or if you put an array of devices 
which needs to be reset together into the reset domain doesn't matter.


Maybe go for the later approach, that is probably a bit cleaner and 
less code to change.


Christian.



Unfortunately this approach raises also a few  difficulties -
First - if holding array of devices in reset_domain then when you come 
to GPU reset function you don't really know which adev is the one 
triggered the reset and this is actually essential to some procedures 
like emergency restart.


Second - in XGMI case we must take into account that one of the hive 
members might go away in runtime (i could do echo 1 > 
/sysfs/pci_id/remove on it for example at any moment) - so now we need 
to maintain this array and mark such entry with NULL probably on XGMI 
node removal , and then there might be hot insertion and all this adds 
more complications.


I now tend to prefer your initial solution for it's simplicity and the 
result will be what we need -


"E.g. in the reset code (either before or after the reset, that's 
debatable) you do something like this:


for (i = 0; i < num_ring; ++i)
cancel_delayed_work(ring[i]->scheduler)
cancel_work(adev->ras_work);
cancel_work(adev->iofault_work);
cancel_work(adev->debugfs_work);
"

Let me know what you think.

Andrey 

RE: [PATCH v2 00/11] DC Patches May 16, 2022

2022-05-16 Thread Wheeler, Daniel
[Public]

Hi all,
 
This week this patchset was tested on the following systems:
 
Sapphire Pulse RX5700XT 
Reference AMD RX6800
Engineering board with Ryzen 9 5900H
 
These systems were tested on the following display types: 
eDP, (1080p 60hz [5900H])
VGA and DVI (1680x1050 60HZ [DP to VGA/DVI, USB-C to DVI/VGA])
DP/HDMI/USB-C (1440p 170hz, 4k 60hz, 4k 144hz [Includes USB-C to DP/HDMI 
adapters])
 
MST tested with Startech MST14DP123DP and 2x 4k 60Hz displays
DSC tested with Cable Matters 101075 (DP to 3x DP), and 201375 (USB-C to 3x DP) 
with 3x 4k60 displays
 
The testing is a mix of automated and manual tests. Manual testing includes 
(but is not limited to):
Changing display configurations and settings
Benchmark testing
Feature testing (Freesync, etc.)
 
Automated testing includes (but is not limited to):
Script testing (scripts to automate some of the manual checks)
IGT testing
 
The patchset consists of the branch amd-staging-drm-next (Head commit - 
da38a66ac46e334f198afcd1b4d4554b4ddca0df -> drm/amdgpu: Ensure the DMA engine 
is deactivated during set ups) with a selection of patches added on top of it. 
This goes for both Ubuntu testing and Chrome OS testing.
 
Tested on Ubuntu 22.04
 
Tested-by: Daniel Wheeler 
 
 
Thank you,
 
Dan Wheeler
Technologist | AMD
SW Display
--
1 Commerce Valley Dr E, Thornhill, ON L3T 7X6
amd.com

-Original Message-
From: amd-gfx  On Behalf Of Qingqing Zhuo
Sent: May 13, 2022 5:17 PM
To: amd-gfx@lists.freedesktop.org
Cc: Wang, Chao-kai (Stylon) ; Li, Sun peng (Leo) 
; Wentland, Harry ; Zhuo, Qingqing 
(Lillian) ; Siqueira, Rodrigo 
; Li, Roman ; Chiu, Solomon 
; Pillai, Aurabindo ; Lin, 
Wayne ; Lakha, Bhawanpreet ; 
Gutierrez, Agustin ; Kotarac, Pavle 

Subject: [PATCH v2 00/11] DC Patches May 16, 2022

This DC patchset brings improvements in multiple areas. In summary, we 
highlight:
 
* Improvements in link training fallback
* Adding individual edp hotplug support
* Fixes in DPIA HPD status, display clock change hang, etc.
* FPU isolation work for DCN30

---

Alvin Lee (1):
  drm/amd/display: Clean up code in dc

Aric Cyr (1):
  drm/amd/display: 3.2.186

Bhawanpreet Lakha (1):
  drm/amd/display: Fic incorrect pipe being used for clk update

David Galiffi (1):
  drm/amd/display: Check if modulo is 0 before dividing.

Derek Lai (1):
  drm/amd/display: Allow individual control of eDP hotplug support

Jasdeep Dhillon (1):
  drm/amd/display: Move FPU associated DCN30 code to DML folder

Jimmy Kizito (2):
  drm/amd/display: Update link training fallback behaviour.
  drm/amd/display: Query DPIA HPD status.

Michael Strauss (1):
  Revert "drm/amd/display: Refactor LTTPR cap retrieval"

Nicholas Kazlauskas (1):
  drm/amd/display: Check zero planes for OTG disable W/A on clock change

Paul Hsieh (1):
  drm/amd/display: clear request when release aux engine

 .../amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c |   2 +-
 .../dc/clk_mgr/dcn315/dcn315_clk_mgr.c|   3 +-
 .../dc/clk_mgr/dcn316/dcn316_clk_mgr.c|   3 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  15 +-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  24 +-  
.../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 248 ---
 .../drm/amd/display/dc/core/dc_link_dpia.c|  19 +
 drivers/gpu/drm/amd/display/dc/dc.h   |   4 +-
 drivers/gpu/drm/amd/display/dc/dc_link.h  |   2 -
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.c  |   3 +-
 .../drm/amd/display/dc/dce/dce_clock_source.c |   9 +-
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c|   1 -
 .../gpu/drm/amd/display/dc/dcn30/dcn30_optc.c |  10 +  
.../drm/amd/display/dc/dcn30/dcn30_resource.c | 516 ++-
 .../drm/amd/display/dc/dcn30/dcn30_resource.h |   5 +
 .../amd/display/dc/dcn301/dcn301_resource.c   |   2 +
 .../amd/display/dc/dcn302/dcn302_resource.c   |   2 +
 .../amd/display/dc/dcn303/dcn303_resource.c   |   2 +
 .../drm/amd/display/dc/dcn31/dcn31_resource.c |   2 +
 drivers/gpu/drm/amd/display/dc/dml/Makefile   |   3 +-
 .../drm/amd/display/dc/dml/dcn30/dcn30_fpu.c  | 617 ++  
.../drm/amd/display/dc/dml/dcn30/dcn30_fpu.h  |  67 ++
 .../gpu/drm/amd/display/dc/inc/core_types.h   |   7 +
 .../gpu/drm/amd/display/dc/inc/dc_link_dp.h   |   3 +-
 .../gpu/drm/amd/display/dc/inc/dc_link_dpia.h |   5 +
 .../amd/display/include/link_service_types.h  |   6 -
 26 files changed, 947 insertions(+), 633 deletions(-)  create mode 100644 
drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h

--
2.25.1


Re: Screen corruption using radeon kernel driver

2022-05-16 Thread Mikhail Krylov
On Mon, Apr 25, 2022 at 01:22:04PM -0400, Alex Deucher wrote:
> + dri-devel
> 
> On Mon, Apr 25, 2022 at 3:33 AM Krylov Michael  wrote:
> >
> > Hello!
> >
> > After updating my Linux kernel from version 4.19 (Debian 10 version) to
> > 5.10 (packaged with Debian 11), I've noticed that the image
> > displayed on my older computer, 32-bit Pentium 4 using ATI Radeon X1950
> > AGP video card is severely corrupted in the graphical (Xorg and Wayland)
> > mode: all kinds of black and white stripes across the screen, some
> > letters missing, etc.
> >
> > I've checked several options (Xorg drivers, Wayland instead of
> > Xorg, radeon.agpmode=-1 in kernel command line and so on), but the
> > problem persisted. I've managed to find that the problem was in the
> > kernel, as everything worked well with 4.19 kernel with everything
> > else being from Debian 11.
> >
> > I have managed to find the culprit of that corruption, that is the
> > commit 33b3ad3788aba846fc8b9a065fe2685a0b64f713 on the linux kernel.
> > Reverting this commit and building the kernel with that commit reverted
> > fixes the problem. Disabling HIMEM also gets rid of that problem. But it
> > also leaves the system with less that 1G of RAM, which is, of course,
> > undesirable.
> >
> > Apparently this problem is somewhat known, as I can tell after googling
> > for the commit id, see this link for example:
> > https://lkml.org/lkml/2020/1/9/518
> >
> > Mageia distro, for example, reverted this commit in the kernel they are
> > building:
> >
> > http://sophie.zarb.org/distrib/Mageia/7/i586/by-pkgid/b9193a4f85192bc57f4d770fb9bb399c/files/32
> >
> > I've reported this bug to Debian bugtracker, checked the recent verion
> > of the kernel (5.17), bug still persists. Here's a link to the Debian
> > bug page:
> >
> > https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=993670
> >
> > I'm not sure if reverting this commit is the correct way to go, so if
> > you need to check any changes/patches that I could apply and test on
> > the real hardware, I'll be glad to do that (but please keep in mind
> > that testing could take some time, I don't have access to this computer
> > 24/7, but I'll do my best to respond ASAP).
> 
> I would be happy to revert that commit.  I attempted to revert it a
> year or so ago, but Christoph didn't want to.  He was going to look
> further into it.  I was not able to repro the issue.  It seemed to be
> related to highmem support.  You might try disabling that.  Here is
> the previous thread for reference:
> https://lists.freedesktop.org/archives/amd-gfx/2020-September/053922.html
> 
> Alex

Yeah, I tried to disable HIMEM, and that indeed fixes the problem, but
it leaves me with less than 1G of available memory which is undesirable.


signature.asc
Description: PGP signature


Re: [PATCH 2/3] drm/amdgpu: add AMDGPU_VM_NOALLOC

2022-05-16 Thread Marek Olšák
Reproduction steps:
- use mesa/main on gfx10.3 (not sure what other GPUs do)
- run: radeonsi_mall_noalloc=true glxgears

Marek

On Mon, May 16, 2022 at 7:53 AM Christian König <
ckoenig.leichtzumer...@gmail.com> wrote:

> Crap, do you have a link to the failure?
>
> Am 16.05.22 um 13:10 schrieb Marek Olšák:
>
> I forgot to say: The NOALLOC flag causes an allocation failure, so there
> is a kernel bug somewhere.
>
> Marek
>
> On Mon, May 16, 2022 at 7:06 AM Marek Olšák  wrote:
>
>> FYI, I think it's time to merge this because the Mesa commits are going
>> to be merged in ~30 minutes if Gitlab CI is green, and that includes
>> updated amdgpu_drm.h.
>>
>> Marek
>>
>> On Wed, May 11, 2022 at 2:55 PM Marek Olšák  wrote:
>>
>>> Ok sounds good.
>>>
>>> Marek
>>>
>>> On Wed., May 11, 2022, 03:43 Christian König, <
>>> ckoenig.leichtzumer...@gmail.com> wrote:
>>>
 It really *is* a NOALLOC feature. In other words there is no latency
 improvement on reads because the cache is always checked, even with the
 noalloc flag set.

 The only thing it affects is that misses not enter the cache and so
 don't cause any additional pressure on evicting cache lines.

 You might want to double check with the hardware guys, but I'm
 something like 95% sure that it works this way.

 Christian.

 Am 11.05.22 um 09:22 schrieb Marek Olšák:

 Bypass means that the contents of the cache are ignored, which
 decreases latency at the cost of no coherency between bypassed and normal
 memory requests. NOA (noalloc) means that the cache is checked and can give
 you cache hits, but misses are not cached and the overall latency is
 higher. I don't know what the hw does, but I hope it was misnamed and it
 really means bypass because there is no point in doing cache lookups on
 every memory request if the driver wants to disable caching to *decrease*
 latency in the situations when the cache isn't helping.

 Marek

 On Wed, May 11, 2022 at 2:15 AM Lazar, Lijo  wrote:

>
>
> On 5/11/2022 11:36 AM, Christian König wrote:
> > Mhm, it doesn't really bypass MALL. It just doesn't allocate any
> MALL
> > entries on write.
> >
> > How about AMDGPU_VM_PAGE_NO_MALL ?
>
> One more - AMDGPU_VM_PAGE_LLC_* [ LLC = last level cache, * = some
> sort
> of attribute which decides LLC behaviour]
>
> Thanks,
> Lijo
>
> >
> > Christian.
> >
> > Am 10.05.22 um 23:21 schrieb Marek Olšák:
> >> A better name would be:
> >> AMDGPU_VM_PAGE_BYPASS_MALL
> >>
> >> Marek
> >>
> >> On Fri, May 6, 2022 at 7:23 AM Christian König
> >>  wrote:
> >>
> >> Add the AMDGPU_VM_NOALLOC flag to let userspace control MALL
> >> allocation.
> >>
> >> Only compile tested!
> >>
> >> Signed-off-by: Christian König 
> >> ---
> >>  drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 ++
> >>  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 3 +++
> >>  drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c  | 3 +++
> >>  include/uapi/drm/amdgpu_drm.h   | 2 ++
> >>  4 files changed, 10 insertions(+)
> >>
> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> >> index bf97d8f07f57..d8129626581f 100644
> >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> >> @@ -650,6 +650,8 @@ uint64_t amdgpu_gem_va_map_flags(struct
> >> amdgpu_device *adev, uint32_t flags)
> >> pte_flag |= AMDGPU_PTE_WRITEABLE;
> >> if (flags & AMDGPU_VM_PAGE_PRT)
> >> pte_flag |= AMDGPU_PTE_PRT;
> >> +   if (flags & AMDGPU_VM_PAGE_NOALLOC)
> >> +   pte_flag |= AMDGPU_PTE_NOALLOC;
> >>
> >> if (adev->gmc.gmc_funcs->map_mtype)
> >> pte_flag |= amdgpu_gmc_map_mtype(adev,
> >> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> >> b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> >> index b8c79789e1e4..9077dfccaf3c 100644
> >> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> >> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> >> @@ -613,6 +613,9 @@ static void gmc_v10_0_get_vm_pte(struct
> >> amdgpu_device *adev,
> >> *flags &= ~AMDGPU_PTE_MTYPE_NV10_MASK;
> >> *flags |= (mapping->flags & AMDGPU_PTE_MTYPE_NV10_MASK);
> >>
> >> +   *flags &= ~AMDGPU_PTE_NOALLOC;
> >> +   *flags |= (mapping->flags & AMDGPU_PTE_NOALLOC);
> >> +
> >> if (mapping->flags & AMDGPU_PTE_PRT) {
> >> *flags |= AMDGPU_PTE_PRT;
> >> *flags |= AMDGPU_PTE_SNOOPED;
> >> diff --git 

Re: [PATCH v1 14/15] tools: add hmm gup tests for device coherent type

2022-05-16 Thread Alistair Popple


Alex Sierra  writes:

> The intention is to test hmm device coherent type under different get
> user pages paths. Also, test gup with FOLL_LONGTERM flag set in
> device coherent pages. These pages should get migrated back to system
> memory.
>
> Signed-off-by: Alex Sierra 
> ---
>  tools/testing/selftests/vm/hmm-tests.c | 104 +
>  1 file changed, 104 insertions(+)
>
> diff --git a/tools/testing/selftests/vm/hmm-tests.c 
> b/tools/testing/selftests/vm/hmm-tests.c
> index 84ec8c4a1dc7..65e30ab6494c 100644
> --- a/tools/testing/selftests/vm/hmm-tests.c
> +++ b/tools/testing/selftests/vm/hmm-tests.c
> @@ -36,6 +36,7 @@
>   * in the usual include/uapi/... directory.
>   */
>  #include "../../../../lib/test_hmm_uapi.h"
> +#include "../../../../mm/gup_test.h"
>
>  struct hmm_buffer {
>   void*ptr;
> @@ -60,6 +61,8 @@ enum {
>  #define NTIMES   10
>
>  #define ALIGN(x, a) (((x) + (a - 1)) & (~((a) - 1)))
> +/* Just the flags we need, copied from mm.h: */
> +#define FOLL_WRITE   0x01/* check pte is writable */
>
>  FIXTURE(hmm)
>  {
> @@ -1766,4 +1769,105 @@ TEST_F(hmm, exclusive_cow)
>   hmm_buffer_free(buffer);
>  }
>
> +static int gup_test_exec(int gup_fd, unsigned long addr,
> +  int cmd, int npages, int size)
> +{
> + struct gup_test gup = {
> + .nr_pages_per_call  = npages,
> + .addr   = addr,
> + .gup_flags  = FOLL_WRITE,
> + .size   = size,
> + };
> +
> + if (ioctl(gup_fd, cmd, )) {
> + perror("ioctl on error\n");
> + return errno;
> + }
> +
> + return 0;
> +}
> +
> +/*
> + * Test get user device pages through gup_test. Setting PIN_LONGTERM flag.
> + * This should trigger a migration back to system memory for both, private
> + * and coherent type pages.
> + * This test makes use of gup_test module. Make sure GUP_TEST_CONFIG is added
> + * to your configuration before you run it.
> + */
> +TEST_F(hmm, hmm_gup_test)
> +{
> + struct hmm_buffer *buffer;
> + int gup_fd;
> + unsigned long npages;
> + unsigned long size;
> + unsigned long i;
> + int *ptr;
> + int ret;
> + unsigned char *m;
> +
> + gup_fd = open("/sys/kernel/debug/gup_test", O_RDWR);
> + if (gup_fd == -1)
> + SKIP(return, "Skipping test, could not find gup_test driver");
> +
> + npages = 3;
> + size = npages << self->page_shift;
> +
> + buffer = malloc(sizeof(*buffer));
> + ASSERT_NE(buffer, NULL);
> +
> + buffer->fd = -1;
> + buffer->size = size;
> + buffer->mirror = malloc(size);
> + ASSERT_NE(buffer->mirror, NULL);
> +
> + buffer->ptr = mmap(NULL, size,
> +PROT_READ | PROT_WRITE,
> +MAP_PRIVATE | MAP_ANONYMOUS,
> +buffer->fd, 0);
> + ASSERT_NE(buffer->ptr, MAP_FAILED);
> +
> + /* Initialize buffer in system memory. */
> + for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
> + ptr[i] = i;
> +
> + /* Migrate memory to device. */
> + ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
> + ASSERT_EQ(ret, 0);
> + ASSERT_EQ(buffer->cpages, npages);
> + /* Check what the device read. */
> + for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
> + ASSERT_EQ(ptr[i], i);
> +
> + ASSERT_EQ(gup_test_exec(gup_fd,
> + (unsigned long)buffer->ptr,
> + GUP_BASIC_TEST, 1, self->page_size), 0);
> + ASSERT_EQ(gup_test_exec(gup_fd,
> + (unsigned long)buffer->ptr + 1 * 
> self->page_size,
> + GUP_FAST_BENCHMARK, 1, self->page_size), 0);
> + ASSERT_EQ(gup_test_exec(gup_fd,
> + (unsigned long)buffer->ptr + 2 * 
> self->page_size,
> + PIN_LONGTERM_BENCHMARK, 1, self->page_size), 0);
> +
> + /* Take snapshot to CPU pagetables */
> + ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
> + ASSERT_EQ(ret, 0);
> + ASSERT_EQ(buffer->cpages, npages);
> + m = buffer->mirror;
> + if (hmm_is_coherent_type(variant->device_number)) {
> + ASSERT_EQ(HMM_DMIRROR_PROT_DEV_COHERENT_LOCAL | 
> HMM_DMIRROR_PROT_WRITE, m[0]);
> + ASSERT_EQ(HMM_DMIRROR_PROT_DEV_COHERENT_LOCAL | 
> HMM_DMIRROR_PROT_WRITE, m[1]);
> + } else {
> + ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[0]);
> + ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[1]);
> + }
> + ASSERT_EQ(HMM_DMIRROR_PROT_WRITE, m[2]);
> + /* Check again the content on the pages. Make sure there's no

Very minor nit-pick, but if you happen to be re-spinning anyway the
comment formatting needs fixing and a new line before the comment would
be nice. Otherwise:

Reviewed-by: Alistair Popple 

> +  * corrupted data.
> + 

Re: [PATCH v12] drm/amdgpu: add drm buddy support to amdgpu

2022-05-16 Thread Mike Lothian
Hi

The merge window for 5.19 will probably be opening next week, has
there been any progress with this bug?

Thanks

Mike

On Mon, 2 May 2022 at 17:31, Mike Lothian  wrote:
>
> On Mon, 2 May 2022 at 16:54, Arunpravin Paneer Selvam
>  wrote:
> >
> >
> >
> > On 5/2/2022 8:41 PM, Mike Lothian wrote:
> > > On Wed, 27 Apr 2022 at 12:55, Mike Lothian  wrote:
> > >> On Tue, 26 Apr 2022 at 17:36, Christian König  
> > >> wrote:
> > >>> Hi Mike,
> > >>>
> > >>> sounds like somehow stitching together the SG table for PRIME doesn't
> > >>> work any more with this patch.
> > >>>
> > >>> Can you try with P2P DMA disabled?
> > >> -CONFIG_PCI_P2PDMA=y
> > >> +# CONFIG_PCI_P2PDMA is not set
> > >>
> > >> If that's what you're meaning, then there's no difference, I'll upload
> > >> my dmesg to the gitlab issue
> > >>
> > >>> Apart from that can you take a look Arun?
> > >>>
> > >>> Thanks,
> > >>> Christian.
> > > Hi
> > >
> > > Have you had any success in replicating this?
> > Hi Mike,
> > I couldn't replicate on my Raven APU machine. I see you have 2 cards
> > initialized, one is Renoir
> > and the other is Navy Flounder. Could you give some more details, are
> > you running Gravity Mark
> > on Renoir and what is your system RAM configuration?
> > >
> > > Cheers
> > >
> > > Mike
> >
> Hi
>
> It's a PRIME laptop, it failed on the RENOIR too, it caused a lockup,
> but systemd managed to capture it, I'll attach it to the issue
>
> I've got 64GB RAM, the 6800M has 12GB VRAM
>
> Cheers
>
> Mike


[PATCH] drm/amdgpu: Clean up of initializing doorbells for gfx_v9 and gfx_v10

2022-05-16 Thread ricetons
From: Haohui Mai 

Clean up redundant, copy-paste code blocks during the intialization of
the doorbells in mqd_init().

Signed-off-by: Haohui Mai 
---
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 17 -
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c  | 17 -
 2 files changed, 34 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index 4b66b9c93754..12f63d6aab12 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -6919,23 +6919,6 @@ static int gfx_v10_0_compute_mqd_init(struct 
amdgpu_device *adev, void *m,
mqd->cp_hqd_pq_wptr_poll_addr_lo = wb_gpu_addr & 0xfffc;
mqd->cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits(wb_gpu_addr) & 0x;
 
-   tmp = 0;
-   /* enable the doorbell if requested */
-   if (prop->use_doorbell) {
-   tmp = RREG32_SOC15(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL);
-   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
-   DOORBELL_OFFSET, prop->doorbell_index);
-
-   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
-   DOORBELL_EN, 1);
-   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
-   DOORBELL_SOURCE, 0);
-   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
-   DOORBELL_HIT, 0);
-   }
-
-   mqd->cp_hqd_pq_doorbell_control = tmp;
-
/* reset read and write pointers, similar to CP_RB0_WPTR/_RPTR */
mqd->cp_hqd_pq_rptr = RREG32_SOC15(GC, 0, mmCP_HQD_PQ_RPTR);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 83639b5ea6a9..f49a2dd89ee7 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -3535,23 +3535,6 @@ static int gfx_v9_0_mqd_init(struct amdgpu_ring *ring)
mqd->cp_hqd_pq_wptr_poll_addr_lo = wb_gpu_addr & 0xfffc;
mqd->cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits(wb_gpu_addr) & 0x;
 
-   tmp = 0;
-   /* enable the doorbell if requested */
-   if (ring->use_doorbell) {
-   tmp = RREG32_SOC15(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL);
-   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
-   DOORBELL_OFFSET, ring->doorbell_index);
-
-   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
-DOORBELL_EN, 1);
-   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
-DOORBELL_SOURCE, 0);
-   tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
-DOORBELL_HIT, 0);
-   }
-
-   mqd->cp_hqd_pq_doorbell_control = tmp;
-
/* reset read and write pointers, similar to CP_RB0_WPTR/_RPTR */
ring->wptr = 0;
mqd->cp_hqd_pq_rptr = RREG32_SOC15(GC, 0, mmCP_HQD_PQ_RPTR);
-- 
2.25.1



Re: [PATCH 2/3] drm/amdgpu: add AMDGPU_VM_NOALLOC

2022-05-16 Thread Christian König

Crap, do you have a link to the failure?

Am 16.05.22 um 13:10 schrieb Marek Olšák:
I forgot to say: The NOALLOC flag causes an allocation failure, so 
there is a kernel bug somewhere.


Marek

On Mon, May 16, 2022 at 7:06 AM Marek Olšák  wrote:

FYI, I think it's time to merge this because the Mesa commits are
going to be merged in ~30 minutes if Gitlab CI is green, and that
includes updated amdgpu_drm.h.

Marek

On Wed, May 11, 2022 at 2:55 PM Marek Olšák  wrote:

Ok sounds good.

Marek

On Wed., May 11, 2022, 03:43 Christian König,
 wrote:

It really *is* a NOALLOC feature. In other words there is
no latency improvement on reads because the cache is
always checked, even with the noalloc flag set.

The only thing it affects is that misses not enter the
cache and so don't cause any additional pressure on
evicting cache lines.

You might want to double check with the hardware guys, but
I'm something like 95% sure that it works this way.

Christian.

Am 11.05.22 um 09:22 schrieb Marek Olšák:

Bypass means that the contents of the cache are ignored,
which decreases latency at the cost of no coherency
between bypassed and normal memory requests. NOA
(noalloc) means that the cache is checked and can give
you cache hits, but misses are not cached and the overall
latency is higher. I don't know what the hw does, but I
hope it was misnamed and it really means bypass because
there is no point in doing cache lookups on every memory
request if the driver wants to disable caching to
*decrease* latency in the situations when the cache isn't
helping.

Marek

On Wed, May 11, 2022 at 2:15 AM Lazar, Lijo
 wrote:



On 5/11/2022 11:36 AM, Christian König wrote:
> Mhm, it doesn't really bypass MALL. It just doesn't
allocate any MALL
> entries on write.
>
> How about AMDGPU_VM_PAGE_NO_MALL ?

One more - AMDGPU_VM_PAGE_LLC_* [ LLC = last level
cache, * = some sort
of attribute which decides LLC behaviour]

Thanks,
Lijo

>
> Christian.
>
> Am 10.05.22 um 23:21 schrieb Marek Olšák:
>> A better name would be:
>> AMDGPU_VM_PAGE_BYPASS_MALL
>>
>> Marek
>>
>> On Fri, May 6, 2022 at 7:23 AM Christian König
>>  wrote:
>>
>>     Add the AMDGPU_VM_NOALLOC flag to let
userspace control MALL
>>     allocation.
>>
>>     Only compile tested!
>>
>>     Signed-off-by: Christian König

>>     ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 ++
>>   drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 3 +++
>>   drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c  | 3 +++
>>      include/uapi/drm/amdgpu_drm.h          | 2 ++
>>      4 files changed, 10 insertions(+)
>>
>>     diff --git
a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>  b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>     index bf97d8f07f57..d8129626581f 100644
>>     --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>     +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>     @@ -650,6 +650,8 @@ uint64_t
amdgpu_gem_va_map_flags(struct
>>     amdgpu_device *adev, uint32_t flags)
>>                     pte_flag |= AMDGPU_PTE_WRITEABLE;
>>             if (flags & AMDGPU_VM_PAGE_PRT)
>>                     pte_flag |= AMDGPU_PTE_PRT;
>>     +       if (flags & AMDGPU_VM_PAGE_NOALLOC)
>>     +               pte_flag |= AMDGPU_PTE_NOALLOC;
>>
>>             if (adev->gmc.gmc_funcs->map_mtype)
>>                     pte_flag |=
amdgpu_gmc_map_mtype(adev,
>>     diff --git
a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
>>  b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
>>     index b8c79789e1e4..9077dfccaf3c 100644
>>     --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
>>     +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
>>     @@ -613,6 +613,9 @@ static void
gmc_v10_0_get_vm_pte(struct
  

Re: [PATCH 2/3] drm/amdgpu: add AMDGPU_VM_NOALLOC

2022-05-16 Thread Marek Olšák
I forgot to say: The NOALLOC flag causes an allocation failure, so there is
a kernel bug somewhere.

Marek

On Mon, May 16, 2022 at 7:06 AM Marek Olšák  wrote:

> FYI, I think it's time to merge this because the Mesa commits are going to
> be merged in ~30 minutes if Gitlab CI is green, and that includes updated
> amdgpu_drm.h.
>
> Marek
>
> On Wed, May 11, 2022 at 2:55 PM Marek Olšák  wrote:
>
>> Ok sounds good.
>>
>> Marek
>>
>> On Wed., May 11, 2022, 03:43 Christian König, <
>> ckoenig.leichtzumer...@gmail.com> wrote:
>>
>>> It really *is* a NOALLOC feature. In other words there is no latency
>>> improvement on reads because the cache is always checked, even with the
>>> noalloc flag set.
>>>
>>> The only thing it affects is that misses not enter the cache and so
>>> don't cause any additional pressure on evicting cache lines.
>>>
>>> You might want to double check with the hardware guys, but I'm something
>>> like 95% sure that it works this way.
>>>
>>> Christian.
>>>
>>> Am 11.05.22 um 09:22 schrieb Marek Olšák:
>>>
>>> Bypass means that the contents of the cache are ignored, which decreases
>>> latency at the cost of no coherency between bypassed and normal memory
>>> requests. NOA (noalloc) means that the cache is checked and can give you
>>> cache hits, but misses are not cached and the overall latency is higher. I
>>> don't know what the hw does, but I hope it was misnamed and it really means
>>> bypass because there is no point in doing cache lookups on every memory
>>> request if the driver wants to disable caching to *decrease* latency in the
>>> situations when the cache isn't helping.
>>>
>>> Marek
>>>
>>> On Wed, May 11, 2022 at 2:15 AM Lazar, Lijo  wrote:
>>>


 On 5/11/2022 11:36 AM, Christian König wrote:
 > Mhm, it doesn't really bypass MALL. It just doesn't allocate any MALL
 > entries on write.
 >
 > How about AMDGPU_VM_PAGE_NO_MALL ?

 One more - AMDGPU_VM_PAGE_LLC_* [ LLC = last level cache, * = some sort
 of attribute which decides LLC behaviour]

 Thanks,
 Lijo

 >
 > Christian.
 >
 > Am 10.05.22 um 23:21 schrieb Marek Olšák:
 >> A better name would be:
 >> AMDGPU_VM_PAGE_BYPASS_MALL
 >>
 >> Marek
 >>
 >> On Fri, May 6, 2022 at 7:23 AM Christian König
 >>  wrote:
 >>
 >> Add the AMDGPU_VM_NOALLOC flag to let userspace control MALL
 >> allocation.
 >>
 >> Only compile tested!
 >>
 >> Signed-off-by: Christian König 
 >> ---
 >>  drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 ++
 >>  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 3 +++
 >>  drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c  | 3 +++
 >>  include/uapi/drm/amdgpu_drm.h   | 2 ++
 >>  4 files changed, 10 insertions(+)
 >>
 >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
 >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
 >> index bf97d8f07f57..d8129626581f 100644
 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
 >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
 >> @@ -650,6 +650,8 @@ uint64_t amdgpu_gem_va_map_flags(struct
 >> amdgpu_device *adev, uint32_t flags)
 >> pte_flag |= AMDGPU_PTE_WRITEABLE;
 >> if (flags & AMDGPU_VM_PAGE_PRT)
 >> pte_flag |= AMDGPU_PTE_PRT;
 >> +   if (flags & AMDGPU_VM_PAGE_NOALLOC)
 >> +   pte_flag |= AMDGPU_PTE_NOALLOC;
 >>
 >> if (adev->gmc.gmc_funcs->map_mtype)
 >> pte_flag |= amdgpu_gmc_map_mtype(adev,
 >> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
 >> b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
 >> index b8c79789e1e4..9077dfccaf3c 100644
 >> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
 >> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
 >> @@ -613,6 +613,9 @@ static void gmc_v10_0_get_vm_pte(struct
 >> amdgpu_device *adev,
 >> *flags &= ~AMDGPU_PTE_MTYPE_NV10_MASK;
 >> *flags |= (mapping->flags & AMDGPU_PTE_MTYPE_NV10_MASK);
 >>
 >> +   *flags &= ~AMDGPU_PTE_NOALLOC;
 >> +   *flags |= (mapping->flags & AMDGPU_PTE_NOALLOC);
 >> +
 >> if (mapping->flags & AMDGPU_PTE_PRT) {
 >> *flags |= AMDGPU_PTE_PRT;
 >> *flags |= AMDGPU_PTE_SNOOPED;
 >> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
 >> b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
 >> index 8d733eeac556..32ee56adb602 100644
 >> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
 >> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
 >> @@ -508,6 +508,9 @@ static void gmc_v11_0_get_vm_pte(struct
 >> amdgpu_device *adev,
 >> *flags &= ~AMDGPU_PTE_MTYPE_NV10_MASK;
 >> *flags |= (mapping->flags & 

Re: [PATCH 2/3] drm/amdgpu: add AMDGPU_VM_NOALLOC

2022-05-16 Thread Marek Olšák
FYI, I think it's time to merge this because the Mesa commits are going to
be merged in ~30 minutes if Gitlab CI is green, and that includes updated
amdgpu_drm.h.

Marek

On Wed, May 11, 2022 at 2:55 PM Marek Olšák  wrote:

> Ok sounds good.
>
> Marek
>
> On Wed., May 11, 2022, 03:43 Christian König, <
> ckoenig.leichtzumer...@gmail.com> wrote:
>
>> It really *is* a NOALLOC feature. In other words there is no latency
>> improvement on reads because the cache is always checked, even with the
>> noalloc flag set.
>>
>> The only thing it affects is that misses not enter the cache and so don't
>> cause any additional pressure on evicting cache lines.
>>
>> You might want to double check with the hardware guys, but I'm something
>> like 95% sure that it works this way.
>>
>> Christian.
>>
>> Am 11.05.22 um 09:22 schrieb Marek Olšák:
>>
>> Bypass means that the contents of the cache are ignored, which decreases
>> latency at the cost of no coherency between bypassed and normal memory
>> requests. NOA (noalloc) means that the cache is checked and can give you
>> cache hits, but misses are not cached and the overall latency is higher. I
>> don't know what the hw does, but I hope it was misnamed and it really means
>> bypass because there is no point in doing cache lookups on every memory
>> request if the driver wants to disable caching to *decrease* latency in the
>> situations when the cache isn't helping.
>>
>> Marek
>>
>> On Wed, May 11, 2022 at 2:15 AM Lazar, Lijo  wrote:
>>
>>>
>>>
>>> On 5/11/2022 11:36 AM, Christian König wrote:
>>> > Mhm, it doesn't really bypass MALL. It just doesn't allocate any MALL
>>> > entries on write.
>>> >
>>> > How about AMDGPU_VM_PAGE_NO_MALL ?
>>>
>>> One more - AMDGPU_VM_PAGE_LLC_* [ LLC = last level cache, * = some sort
>>> of attribute which decides LLC behaviour]
>>>
>>> Thanks,
>>> Lijo
>>>
>>> >
>>> > Christian.
>>> >
>>> > Am 10.05.22 um 23:21 schrieb Marek Olšák:
>>> >> A better name would be:
>>> >> AMDGPU_VM_PAGE_BYPASS_MALL
>>> >>
>>> >> Marek
>>> >>
>>> >> On Fri, May 6, 2022 at 7:23 AM Christian König
>>> >>  wrote:
>>> >>
>>> >> Add the AMDGPU_VM_NOALLOC flag to let userspace control MALL
>>> >> allocation.
>>> >>
>>> >> Only compile tested!
>>> >>
>>> >> Signed-off-by: Christian König 
>>> >> ---
>>> >>  drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 ++
>>> >>  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 3 +++
>>> >>  drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c  | 3 +++
>>> >>  include/uapi/drm/amdgpu_drm.h   | 2 ++
>>> >>  4 files changed, 10 insertions(+)
>>> >>
>>> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>> >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>> >> index bf97d8f07f57..d8129626581f 100644
>>> >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>> >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>> >> @@ -650,6 +650,8 @@ uint64_t amdgpu_gem_va_map_flags(struct
>>> >> amdgpu_device *adev, uint32_t flags)
>>> >> pte_flag |= AMDGPU_PTE_WRITEABLE;
>>> >> if (flags & AMDGPU_VM_PAGE_PRT)
>>> >> pte_flag |= AMDGPU_PTE_PRT;
>>> >> +   if (flags & AMDGPU_VM_PAGE_NOALLOC)
>>> >> +   pte_flag |= AMDGPU_PTE_NOALLOC;
>>> >>
>>> >> if (adev->gmc.gmc_funcs->map_mtype)
>>> >> pte_flag |= amdgpu_gmc_map_mtype(adev,
>>> >> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
>>> >> b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
>>> >> index b8c79789e1e4..9077dfccaf3c 100644
>>> >> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
>>> >> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
>>> >> @@ -613,6 +613,9 @@ static void gmc_v10_0_get_vm_pte(struct
>>> >> amdgpu_device *adev,
>>> >> *flags &= ~AMDGPU_PTE_MTYPE_NV10_MASK;
>>> >> *flags |= (mapping->flags & AMDGPU_PTE_MTYPE_NV10_MASK);
>>> >>
>>> >> +   *flags &= ~AMDGPU_PTE_NOALLOC;
>>> >> +   *flags |= (mapping->flags & AMDGPU_PTE_NOALLOC);
>>> >> +
>>> >> if (mapping->flags & AMDGPU_PTE_PRT) {
>>> >> *flags |= AMDGPU_PTE_PRT;
>>> >> *flags |= AMDGPU_PTE_SNOOPED;
>>> >> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
>>> >> b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
>>> >> index 8d733eeac556..32ee56adb602 100644
>>> >> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
>>> >> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
>>> >> @@ -508,6 +508,9 @@ static void gmc_v11_0_get_vm_pte(struct
>>> >> amdgpu_device *adev,
>>> >> *flags &= ~AMDGPU_PTE_MTYPE_NV10_MASK;
>>> >> *flags |= (mapping->flags & AMDGPU_PTE_MTYPE_NV10_MASK);
>>> >>
>>> >> +   *flags &= ~AMDGPU_PTE_NOALLOC;
>>> >> +   *flags |= (mapping->flags & AMDGPU_PTE_NOALLOC);
>>> >> +
>>> >> if (mapping->flags & AMDGPU_PTE_PRT) {
>>> >> *flags |= AMDGPU_PTE_PRT;
>>> >>  

RE: [Intel-gfx] [V2 2/3] drm/i915/display/debug: Expose crtc current bpc via debugfs

2022-05-16 Thread Jani Nikula
On Tue, 12 Apr 2022, "Murthy, Arun R"  wrote:
>> -Original Message-
>> From: Intel-gfx  On Behalf Of
>> Bhanuprakash Modem
>> Sent: Monday, April 11, 2022 3:21 PM
>> To: intel-...@lists.freedesktop.org; dri-de...@lists.freedesktop.org; amd-
>> g...@lists.freedesktop.org; jani.nik...@linux.intel.com;
>> ville.syrj...@linux.intel.com; harry.wentl...@amd.com; Sharma, Swati2
>> 
>> Subject: [Intel-gfx] [V2 2/3] drm/i915/display/debug: Expose crtc current bpc
>> via debugfs
>> 
>> This new debugfs will expose the currently using bpc by crtc.
>> It is very useful for verifying whether we enter the correct output color 
>> depth
>> from IGT.
>> 
>> This patch will also add the connector's max supported bpc to
>> "i915_display_info" debugfs.
>> 
>> Example:
>> cat /sys/kernel/debug/dri/0/crtc-0/i915_current_bpc
>> Current: 8
>> 
>> Cc: Jani Nikula 
>> Cc: Ville Syrjälä 
>> Cc: Uma Shankar 
>> Signed-off-by: Bhanuprakash Modem 
>
> Reviewed-by: Arun R Murthy 

Acked-by: Jani Nikula 

for merging this via drm-misc-next.



-- 
Jani Nikula, Intel Open Source Graphics Center


Re: [Intel-gfx] [V2 3/3] drm/amd/display: Move connector debugfs to drm

2022-05-16 Thread Jani Nikula
On Mon, 02 May 2022, Harry Wentland  wrote:
> Both the kernel and IGT series look good to me.
>
> I recommend you merge the entire kernel set as one into drm-next. We
> can pull it into amd-staging-drm-next so as not to break our CI once
> the IGT patches land.

Can we read that as an ack to merge via drm-misc-next? :)

BR,
Jani.


-- 
Jani Nikula, Intel Open Source Graphics Center


[PATCH] drm/amdgpu: Off by one in dm_dmub_outbox1_low_irq()

2022-05-16 Thread Dan Carpenter
The > ARRAY_SIZE() should be >= ARRAY_SIZE() to prevent an out of bounds
access.

Fixes: e27c41d5b068 ("drm/amd/display: Support for DMUB HPD interrupt handling")
Signed-off-by: Dan Carpenter 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 6edfc0963dab..c4f122c6faec 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -770,7 +770,7 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params)
 
do {
dc_stat_get_dmub_notification(adev->dm.dc, );
-   if (notify.type > ARRAY_SIZE(dm->dmub_thread_offload)) {
+   if (notify.type >= ARRAY_SIZE(dm->dmub_thread_offload)) 
{
DRM_ERROR("DM: notify type %d invalid!", 
notify.type);
continue;
}
-- 
2.35.1