mbox series

[v4,0/7] cxl: Introduce HDM decoder emulation from DVSEC range registers

Message ID 167588394236.1155956.8466475582138210344.stgit@djiang5-mobl3.local
Headers show
Series cxl: Introduce HDM decoder emulation from DVSEC range registers | expand

Message

Dave Jiang Feb. 8, 2023, 7:20 p.m. UTC
v4:
- Init invalid range start to 0. (Dan)
- Direct assign range to range. (Dan)
- Add comment for why emulated decoder is locked. (Dan)
- Check range_len() instead of content of .start. (Dan)
- Fix too long line formatting. (Dan)
- Remove ->emulate_decoders (Dan)
- Dropped v3 7/8 patch. (Dan)
- Change decoder lock removal commit log for more clarity. (Dan)

v3:
- Simplify to directly return devm_cxl_enable_mem() in
  cxl_hdm_decode_init(). (Jonathan)
- Move relevant changes from 6/8 to 5/8 and update kdoc. (Jonathan)
- Add kernel doc update. (Jonathan)

v2:
- Refactor to continue when size is 0. (Jonathan)
- Update kdoc comments (Jonathan)
- Use a bool for is_cxl_endpoint() to make it easier for static analysis
  (Jonathan)
- Update commit log to indicate cxl_hdm_decode_init() return additional
  error codes after change. (Jonathan)
- Set target_type to CXL_DECODER_EXPANDER (type 3). (Jonathan)
- Skip HDM enabling if DVSEC range is active. (Jonathan)
- Set target_count to same as number of ranges. (Jonathan)
- Set target_type to CXL_DECODER_EXPANDER (type 3). (Jonathan)
- Refactor to put error case out of line. (Jonathan)
- Drop 7/8 "cxl: suppress component register discovery failure warning for RCD"
- Add support for missing case where HDM decoders are present but no decoders
  are committed. (Case 5 below)

This series provides the emulation of HDM decoders from the programmed range
registers. From CXL 3.0 spec 8.1.3.8, there can be up to 2 ranges programmed.
Some devices may not implement HDM decoder registers and some may not be
programmed by the BIOS. Under such scenarios, if one of more range registers
are programmed, then we can create an emulated HDM decoder per active range
indicated by the range registers. The emulated HDM decoders will show up as
locked and cannot be reprogrammed.

Below is a table that indicates different scenarios the driver may encounter:

rr: Range registers not programmed
hdm: HDM decoders not programmed
RR: Range registers programmed by BIOS
HDM: HDM decoders programmed by BIOS

emulate HDM: Create HDM decoder software structs and use values from range registers.
keep HDM: Populate HDM decoder software structs with values in HDM decoder registers.

Case 1:        Case 2:        Case 3:    Case 4:     Case 5:       Case 6:
rr             RR             rr hdm	 rr HDM	     RR hdm        RR HDM
unsupported    emulate HDM    keep HDM	 keep HDM    emulate HDM   keep HDM

For convenience, the kernel branch can be retrieved here [1].

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/djiang/linux.git/log/?h=cxl-emulate-hdm

base-commit: 4ec5183ec48656cec489c49f989c508b68b518e3

---

Dave Jiang (7):
      cxl: break out range register decoding from cxl_hdm_decode_init()
      cxl: export cxl_dvsec_rr_decode() to cxl_port
      cxl: refactor cxl_hdm_decode_init()
      cxl: emulate HDM decoder from DVSEC range registers
      cxl: create emulated cxl_hdm for devices that do not have HDM decoders
      cxl: Add emulation when HDM decoders are not committed
      cxl: remove locked check for dvsec_range_allowed()


 drivers/cxl/core/hdm.c | 119 +++++++++++++++++++++---
 drivers/cxl/core/pci.c | 199 +++++++++++++++++++----------------------
 drivers/cxl/cxl.h      |  20 ++++-
 drivers/cxl/cxlmem.h   |  12 ---
 drivers/cxl/cxlpci.h   |   3 +-
 drivers/cxl/port.c     |  25 ++++--
 6 files changed, 237 insertions(+), 141 deletions(-)

--

Comments

Dan Williams Feb. 11, 2023, 2:05 a.m. UTC | #1
Dave Jiang wrote:
> v4:
> - Init invalid range start to 0. (Dan)
> - Direct assign range to range. (Dan)
> - Add comment for why emulated decoder is locked. (Dan)
> - Check range_len() instead of content of .start. (Dan)
> - Fix too long line formatting. (Dan)
> - Remove ->emulate_decoders (Dan)
> - Dropped v3 7/8 patch. (Dan)
> - Change decoder lock removal commit log for more clarity. (Dan)
> 
> v3:
> - Simplify to directly return devm_cxl_enable_mem() in
>   cxl_hdm_decode_init(). (Jonathan)
> - Move relevant changes from 6/8 to 5/8 and update kdoc. (Jonathan)
> - Add kernel doc update. (Jonathan)
> 
> v2:
> - Refactor to continue when size is 0. (Jonathan)
> - Update kdoc comments (Jonathan)
> - Use a bool for is_cxl_endpoint() to make it easier for static analysis
>   (Jonathan)
> - Update commit log to indicate cxl_hdm_decode_init() return additional
>   error codes after change. (Jonathan)
> - Set target_type to CXL_DECODER_EXPANDER (type 3). (Jonathan)
> - Skip HDM enabling if DVSEC range is active. (Jonathan)
> - Set target_count to same as number of ranges. (Jonathan)
> - Set target_type to CXL_DECODER_EXPANDER (type 3). (Jonathan)
> - Refactor to put error case out of line. (Jonathan)
> - Drop 7/8 "cxl: suppress component register discovery failure warning for RCD"
> - Add support for missing case where HDM decoders are present but no decoders
>   are committed. (Case 5 below)
> 
> This series provides the emulation of HDM decoders from the programmed range
> registers. From CXL 3.0 spec 8.1.3.8, there can be up to 2 ranges programmed.
> Some devices may not implement HDM decoder registers and some may not be
> programmed by the BIOS. Under such scenarios, if one of more range registers
> are programmed, then we can create an emulated HDM decoder per active range
> indicated by the range registers. The emulated HDM decoders will show up as
> locked and cannot be reprogrammed.
> 
> Below is a table that indicates different scenarios the driver may encounter:
> 
> rr: Range registers not programmed
> hdm: HDM decoders not programmed
> RR: Range registers programmed by BIOS
> HDM: HDM decoders programmed by BIOS
> 
> emulate HDM: Create HDM decoder software structs and use values from range registers.
> keep HDM: Populate HDM decoder software structs with values in HDM decoder registers.
> 
> Case 1:        Case 2:        Case 3:    Case 4:     Case 5:       Case 6:
> rr             RR             rr hdm	 rr HDM	     RR hdm        RR HDM
> unsupported    emulate HDM    keep HDM	 keep HDM    emulate HDM   keep HDM
> 
> For convenience, the kernel branch can be retrieved here [1].
> 
> [1]: https://git.kernel.org/pub/scm/linux/kernel/git/djiang/linux.git/log/?h=cxl-emulate-hdm
> 
> base-commit: 4ec5183ec48656cec489c49f989c508b68b518e3
> 
> ---
> 
> Dave Jiang (7):
>       cxl: break out range register decoding from cxl_hdm_decode_init()
>       cxl: export cxl_dvsec_rr_decode() to cxl_port
>       cxl: refactor cxl_hdm_decode_init()
>       cxl: emulate HDM decoder from DVSEC range registers
>       cxl: create emulated cxl_hdm for devices that do not have HDM decoders
>       cxl: Add emulation when HDM decoders are not committed
>       cxl: remove locked check for dvsec_range_allowed()
> 
> 
>  drivers/cxl/core/hdm.c | 119 +++++++++++++++++++++---
>  drivers/cxl/core/pci.c | 199 +++++++++++++++++++----------------------
>  drivers/cxl/cxl.h      |  20 ++++-
>  drivers/cxl/cxlmem.h   |  12 ---
>  drivers/cxl/cxlpci.h   |   3 +-
>  drivers/cxl/port.c     |  25 ++++--
>  6 files changed, 237 insertions(+), 141 deletions(-)

Oh, this all looks good on the base driver, but this missed updating
cxl_test:

tools/testing/cxl/test/mock.c: In function ‘__wrap_devm_cxl_setup_hdm’:
tools/testing/cxl/test/mock.c:143:26: error: too few arguments to function ‘devm_cxl_setup_hdm’
  143 |                 cxlhdm = devm_cxl_setup_hdm(port);
      |                          ^~~~~~~~~~~~~~~~~~
In file included from ./drivers/cxl/cxlmem.h:8,
                 from tools/testing/cxl/test/mock.c:10:
./drivers/cxl/cxl.h:664:17: note: declared here
  664 | struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
      |                 ^~~~~~~~~~~~~~~~~~
tools/testing/cxl/test/mock.c: In function ‘__wrap_devm_cxl_enumerate_decoders’:
tools/testing/cxl/test/mock.c:174:22: error: too few arguments to function ‘devm_cxl_enumerate_decoders’
  174 |                 rc = devm_cxl_enumerate_decoders(cxlhdm);
      |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
./drivers/cxl/cxl.h:666:5: note: declared here
  666 | int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
tools/testing/cxl/test/mock.c: In function ‘__wrap_cxl_hdm_decode_init’:
tools/testing/cxl/test/mock.c:220:22: error: too few arguments to function ‘cxl_hdm_decode_init’
  220 |                 rc = cxl_hdm_decode_init(cxlds, cxlhdm);
      |                      ^~~~~~~~~~~~~~~~~~~
In file included from tools/testing/cxl/test/mock.c:11:
./drivers/cxl/cxlpci.h:73:5: note: declared here
   73 | int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm,
      |     ^~~~~~~~~~~~~~~~~~~