lkml.org 
[lkml]   [2022]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.18 859/879] coresight: core: Fix coresight device probe failure issue
    Date
    From: Mao Jinlong <quic_jinlmao@quicinc.com>

    commit 8c1d3f79d9ca48e406b78e90e94cf09a8c076bf2 upstream.

    It is possibe that probe failure issue happens when the device
    and its child_device's probe happens at the same time.
    In coresight_make_links, has_conns_grp is true for parent, but
    has_conns_grp is false for child device as has_conns_grp is set
    to true in coresight_create_conns_sysfs_group. The probe of parent
    device will fail at this condition. Add has_conns_grp check for
    child device before make the links and make the process from
    device_register to connection_create be atomic to avoid this
    probe failure issue.

    Cc: stable@vger.kernel.org
    Suggested-by: Suzuki K Poulose <suzuki.poulose@arm.com>
    Suggested-by: Mike Leach <mike.leach@linaro.org>
    Signed-off-by: Mao Jinlong <quic_jinlmao@quicinc.com>
    Link: https://lore.kernel.org/r/20220309142206.15632-1-quic_jinlmao@quicinc.com
    [ Added Cc stable ]
    Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/hwtracing/coresight/coresight-core.c | 33 ++++++++++++++++++---------
    1 file changed, 22 insertions(+), 11 deletions(-)

    --- a/drivers/hwtracing/coresight/coresight-core.c
    +++ b/drivers/hwtracing/coresight/coresight-core.c
    @@ -1379,7 +1379,7 @@ static int coresight_fixup_device_conns(
    continue;
    conn->child_dev =
    coresight_find_csdev_by_fwnode(conn->child_fwnode);
    - if (conn->child_dev) {
    + if (conn->child_dev && conn->child_dev->has_conns_grp) {
    ret = coresight_make_links(csdev, conn,
    conn->child_dev);
    if (ret)
    @@ -1571,6 +1571,7 @@ struct coresight_device *coresight_regis
    int nr_refcnts = 1;
    atomic_t *refcnts = NULL;
    struct coresight_device *csdev;
    + bool registered = false;

    csdev = kzalloc(sizeof(*csdev), GFP_KERNEL);
    if (!csdev) {
    @@ -1591,7 +1592,8 @@ struct coresight_device *coresight_regis
    refcnts = kcalloc(nr_refcnts, sizeof(*refcnts), GFP_KERNEL);
    if (!refcnts) {
    ret = -ENOMEM;
    - goto err_free_csdev;
    + kfree(csdev);
    + goto err_out;
    }

    csdev->refcnt = refcnts;
    @@ -1616,6 +1618,13 @@ struct coresight_device *coresight_regis
    csdev->dev.fwnode = fwnode_handle_get(dev_fwnode(desc->dev));
    dev_set_name(&csdev->dev, "%s", desc->name);

    + /*
    + * Make sure the device registration and the connection fixup
    + * are synchronised, so that we don't see uninitialised devices
    + * on the coresight bus while trying to resolve the connections.
    + */
    + mutex_lock(&coresight_mutex);
    +
    ret = device_register(&csdev->dev);
    if (ret) {
    put_device(&csdev->dev);
    @@ -1623,7 +1632,7 @@ struct coresight_device *coresight_regis
    * All resources are free'd explicitly via
    * coresight_device_release(), triggered from put_device().
    */
    - goto err_out;
    + goto out_unlock;
    }

    if (csdev->type == CORESIGHT_DEV_TYPE_SINK ||
    @@ -1638,11 +1647,11 @@ struct coresight_device *coresight_regis
    * from put_device(), which is in turn called from
    * function device_unregister().
    */
    - goto err_out;
    + goto out_unlock;
    }
    }
    -
    - mutex_lock(&coresight_mutex);
    + /* Device is now registered */
    + registered = true;

    ret = coresight_create_conns_sysfs_group(csdev);
    if (!ret)
    @@ -1652,16 +1661,18 @@ struct coresight_device *coresight_regis
    if (!ret && cti_assoc_ops && cti_assoc_ops->add)
    cti_assoc_ops->add(csdev);

    +out_unlock:
    mutex_unlock(&coresight_mutex);
    - if (ret) {
    + /* Success */
    + if (!ret)
    + return csdev;
    +
    + /* Unregister the device if needed */
    + if (registered) {
    coresight_unregister(csdev);
    return ERR_PTR(ret);
    }

    - return csdev;
    -
    -err_free_csdev:
    - kfree(csdev);
    err_out:
    /* Cleanup the connection information */
    coresight_release_platform_data(NULL, desc->pdata);

    \
     
     \ /
      Last update: 2022-06-08 03:44    [W:3.045 / U:0.428 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site