From: Dave Jiang <dave.jiang@intel.com>
To: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
Cc: <linux-cxl@vger.kernel.org>, <dan.j.williams@intel.com>,
<ira.weiny@intel.com>, <vishal.l.verma@intel.com>,
<alison.schofield@intel.com>, <dave@stgolabs.net>
Subject: Re: [PATCH v14 19/19] cxl: Check qos_class validity on memdev probe
Date: Wed, 20 Dec 2023 15:26:19 -0700 [thread overview]
Message-ID: <2fb48806-ae84-4e6e-82aa-712b4e511142@intel.com> (raw)
In-Reply-To: <20231219164221.000011c8@Huawei.com>
On 12/19/23 09:42, Jonathan Cameron wrote:
> On Wed, 13 Dec 2023 09:43:16 -0700
> Dave Jiang <dave.jiang@intel.com> wrote:
>
>> Add a check to make sure the qos_class for the device will match one of
>> the root decoders qos_class. If no match is found, then the qos_class for
>> the device is set to invalid. Also add a check to ensure that the device's
>> host bridge matches to one of the root decoder's downstream targets.
>>
>> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
> A few comments on places I think this can be simplified.
>
> Jonathan
>
>> ---
>> v14:
>> - Move unmatched entries to discard list (Dan)
>> - Update perf_prop_entry to cxl_dpa_perf (Dan)
>> - Use DEFINE_FREE() in cxl_qos_class_verify to clean up code (Dan)
>> - Move qos verify to core/cdat.c in order to be called before region setup
>> (Dan)
>> ---
>> drivers/cxl/core/cdat.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 137 insertions(+)
>>
>> diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
>> index 8c561f1deec6..5fe57fe5e2ee 100644
>> --- a/drivers/cxl/core/cdat.c
>> +++ b/drivers/cxl/core/cdat.c
>> @@ -270,6 +270,142 @@ static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
>> devm_add_action_or_reset(&cxlds->cxlmd->dev, free_perf_ents, mds);
>> }
>>
>> +struct qos_class_ctx {
>> + bool matched;
>> + int dev_qos_class;
>> +};
>> +
>> +static int match_cxlrd_qos_class(struct device *dev, void *data)
>> +{
>> + struct qos_class_ctx *ctx = data;
>> + struct cxl_root_decoder *cxlrd;
>> +
>> + if (!is_root_decoder(dev))
>> + return 0;
>> +
>> + cxlrd = to_cxl_root_decoder(dev);
>> + if (cxlrd->qos_class == CXL_QOS_CLASS_INVALID ||
>> + ctx->dev_qos_class == CXL_QOS_CLASS_INVALID)
> Why check this one in here? Caller should take that out first.
Ok I'll move to caller.
>
>> + return 0;
>> +
>> + if (cxlrd->qos_class == ctx->dev_qos_class) {
>> + ctx->matched = 1;
>> + return 1;
>
> As noted below, this is the return value for the device_for_each_child()
> so can use that instead of needing ctx->matched.
Yes. Will simplify.
>
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int cxl_qos_match(struct cxl_port *root_port,
>> + struct list_head *work_list,
>> + struct list_head *discard_list)
>> +{
>> + struct cxl_dpa_perf *dpa_perf, *n;
>> + struct qos_class_ctx ctx;
>> + int rc;
>> +
>> + if (list_empty(work_list))
>> + return 0;
>> +
>> + list_for_each_entry_safe(dpa_perf, n, work_list, list) {
>> + ctx = (struct qos_class_ctx) {
>> + .matched = false,
>> + .dev_qos_class = dpa_perf->qos_class,
>> + };
>
> as above the dev_qos_class doesn't change so can we not
> reject it early here?
> if (!dpa_perf->qos_class)
> continue; /* I think? */
Not sure what you mean here. qos_class can be 0.
I ended up just changing it to this:
static void cxl_qos_match(struct cxl_port *root_port,
struct list_head *work_list,
struct list_head *discard_list)
{
struct cxl_dpa_perf *dpa_perf, *n;
int rc;
list_for_each_entry_safe(dpa_perf, n, work_list, list) {
if (dpa_perf->qos_class == CXL_QOS_CLASS_INVALID)
return;
rc = device_for_each_child(&root_port->dev,
(void *)&dpa_perf->qos_class,
match_cxlrd_qos_class);
if (!rc)
list_move_tail(&dpa_perf->list, discard_list);
}
}
>
>> + rc = device_for_each_child(&root_port->dev, &ctx, match_cxlrd_qos_class);
>> + if (rc < 0)
>> + return -ENOENT;
>
> Can only return 0 or 1 and 1 is returned only on a match, so can use that
> in place of ctx.matched if you like.
Yes I will remove ctx.matched completely.
>
>> +
>> + if (!ctx.matched)
>> + list_move_tail(&dpa_perf->list, discard_list);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +struct qos_hb_ctx {
>> + bool matched;
>> + struct device *host_bridge;
>> +};
>> +
>> +static int match_cxlrd_hb(struct device *dev, void *data)
>> +{
>> + struct cxl_switch_decoder *cxlsd;
>> + struct qos_hb_ctx *ctx = data;
>> + struct cxl_root_decoder *cxlrd;
>> + unsigned int seq;
>> +
>> + if (!is_root_decoder(dev))
>> + return 0;
>> +
>> + cxlrd = to_cxl_root_decoder(dev);
>> + cxlsd = &cxlrd->cxlsd;
>> +
>> + do {
>> + seq = read_seqbegin(&cxlsd->target_lock);
>> + for (int i = 0; i < cxlsd->nr_targets; i++) {
>> + if (ctx->host_bridge ==
>> + cxlsd->target[i]->dport_dev) {
>> + ctx->matched = true;
>> + return 1;
>> + }
>> + }
>> + } while (read_seqretry(&cxlsd->target_lock, seq));
>> +
>> + return 0;
>> +}
>> +
>> +static void discard_dpa_perf(struct list_head *list)
>> +{
>> + struct cxl_dpa_perf *dpa_perf, *n;
>> +
>> + list_for_each_entry_safe(dpa_perf, n, list, list) {
>> + list_del(&dpa_perf->list);
>> + kfree(dpa_perf);
>> + }
>> +}
>> +DEFINE_FREE(dpa_perf, struct list_head *, if (_T) discard_dpa_perf(_T))
>
> Can if (_T) ever fail?
> The list can be empty but I think the pointer is always valid.
Right. I'll change it to if (!list_empty(_T)) given here we are pointing to a list_head on stack.
>
>> +
>> +static int cxl_qos_class_verify(struct cxl_memdev *cxlmd)
>> +{
>> + struct cxl_dev_state *cxlds = cxlmd->cxlds;
>> + struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
>> + struct cxl_port *root_port __free(put_device) = NULL;
>> + LIST_HEAD(__discard);
>> + struct list_head *discard __free(dpa_perf) = &__discard;
>> + struct qos_hb_ctx hbctx;
>> + int rc;
>> +
>> + root_port = find_cxl_root(cxlmd->endpoint);
>> + if (!root_port)
>> + return -ENODEV;
>> +
>> + /* Check that the QTG IDs are all sane between end device and root decoders */
>> + rc = cxl_qos_match(root_port, &mds->ram_perf_list, discard);
>> + if (rc < 0)
>> + return rc;
>> +
>> + rc = cxl_qos_match(root_port, &mds->pmem_perf_list, discard);
>> + if (rc < 0)
>> + return rc;
>> +
>> + /* Check to make sure that the device's host bridge is under a root decoder */
>> + hbctx = (struct qos_hb_ctx) {
>> + .matched = false,
>> + .host_bridge = cxlmd->endpoint->host_bridge,
>> + };
>> + rc = device_for_each_child(&root_port->dev, &hbctx, match_cxlrd_hb);
>> + if (rc < 0)
>> + return rc;
> As above failre sure this can't return an error, and I think you can use the return
> value == 1 in place of the matched variable allowing simpler context.
Will simplify
>> +
>> + if (!hbctx.matched) {
>> + list_splice_tail_init(&mds->ram_perf_list, discard);
>> + list_splice_tail_init(&mds->pmem_perf_list, discard);
>> + }
>> +
>> + return rc;
>> +}
>> +
>
>
next prev parent reply other threads:[~2023-12-20 22:26 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-13 16:41 [PATCH v14 00/19] cxl: Add support for QTG ID retrieval for CXL subsystem Dave Jiang
2023-12-13 16:41 ` [PATCH v14 01/19] lib/firmware_table: tables: Add CDAT table parsing support Dave Jiang
2023-12-13 16:41 ` [PATCH v14 02/19] base/node / acpi: Change 'node_hmem_attrs' to 'access_coordinates' Dave Jiang
2023-12-13 16:41 ` [PATCH v14 03/19] acpi: numa: Create enum for memory_target access coordinates indexing Dave Jiang
2023-12-13 16:41 ` [PATCH v14 04/19] acpi: numa: Add genport target allocation to the HMAT parsing Dave Jiang
2023-12-13 16:41 ` [PATCH v14 05/19] acpi: Break out nesting for hmat_parse_locality() Dave Jiang
2023-12-13 16:41 ` [PATCH v14 06/19] acpi: numa: Add setting of generic port system locality attributes Dave Jiang
2023-12-13 16:42 ` [PATCH v14 07/19] acpi: numa: Add helper function to retrieve the performance attributes Dave Jiang
2023-12-13 16:42 ` [PATCH v14 08/19] cxl: Add callback to parse the DSMAS subtables from CDAT Dave Jiang
2023-12-13 16:42 ` [PATCH v14 09/19] cxl: Add callback to parse the DSLBIS subtable " Dave Jiang
2023-12-13 16:42 ` [PATCH v14 10/19] cxl: Add callback to parse the SSLBIS " Dave Jiang
2023-12-13 16:42 ` [PATCH v14 11/19] cxl: Add support for _DSM Function for retrieving QTG ID Dave Jiang
2023-12-13 16:42 ` [PATCH v14 12/19] cxl: Calculate and store PCI link latency for the downstream ports Dave Jiang
2023-12-13 16:42 ` [PATCH v14 13/19] tools/testing/cxl: Add hostbridge UID string for cxl_test mock hb devices Dave Jiang
2023-12-13 16:42 ` [PATCH v14 14/19] cxl: Store the access coordinates for the generic ports Dave Jiang
2023-12-13 16:42 ` [PATCH v14 15/19] cxl: Add helper function that calculate performance data for downstream ports Dave Jiang
2023-12-13 16:42 ` [PATCH v14 16/19] cxl: Compute the entire CXL path latency and bandwidth data Dave Jiang
2023-12-13 16:43 ` [PATCH v14 17/19] cxl: Store QTG IDs and related info to the CXL memory device context Dave Jiang
2023-12-13 16:43 ` [PATCH v14 18/19] cxl: Export sysfs attributes for memory device QoS class Dave Jiang
2023-12-15 20:33 ` Dave Jiang
2023-12-18 16:28 ` Dave Jiang
2023-12-13 16:43 ` [PATCH v14 19/19] cxl: Check qos_class validity on memdev probe Dave Jiang
2023-12-19 16:42 ` Jonathan Cameron
2023-12-20 22:26 ` Dave Jiang [this message]
2024-01-08 14:01 ` Jonathan Cameron
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2fb48806-ae84-4e6e-82aa-712b4e511142@intel.com \
--to=dave.jiang@intel.com \
--cc=Jonathan.Cameron@Huawei.com \
--cc=alison.schofield@intel.com \
--cc=dan.j.williams@intel.com \
--cc=dave@stgolabs.net \
--cc=ira.weiny@intel.com \
--cc=linux-cxl@vger.kernel.org \
--cc=vishal.l.verma@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.