Received: by 2002:a05:6358:16cc:b0:ea:6187:17c9 with SMTP id r12csp9133495rwl; Wed, 11 Jan 2023 01:44:49 -0800 (PST) X-Google-Smtp-Source: AMrXdXt1XXz/CVEYlee5N7gZKIoyfvU/03LjU84KLfugnpy/5tNRLx2t1fJh8OOTWxtfzMEWoB8i X-Received: by 2002:a17:907:8b11:b0:81b:fbff:a7cc with SMTP id sz17-20020a1709078b1100b0081bfbffa7ccmr61609631ejc.18.1673430288958; Wed, 11 Jan 2023 01:44:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673430288; cv=none; d=google.com; s=arc-20160816; b=l17bIcsUTzJTrdWltckz1NGRlW+OTE47iNp/wGmYCp7C4pHraxQVQlj82+44xOUGSi RA67jLXiqRNUN4gi/eRYmgPfhXuE6Hh9jnS3hHhPra/r6ZE47zzWdyrCpxJZTOcPhAlZ 6nbu0lc8Fg+X+P7pSL4I6I/3IECpMNaUa3Y/Rcwd8/bCubaAb2P0aTBThIokgb01Cblf y7xu4k5sZnFSRHUrgA9oAEnxd7azH+lyGeJLQrPlV5AcH2q5lEzc2J182FrvmxAxC8AF bPY4PjIRMp4JLte2SNWnrbz/cXaCcw08bHglfYKC2qo/la7cxa5iux7vt9votfq/0lq7 EbGw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from :references:cc:to:content-language:subject:user-agent:mime-version :date:message-id:dkim-signature; bh=mvSen0YPktxZ6yY811DDXcSx4nAy7KzBUaW4BDWH8SE=; b=jPpsGuHThu8tBg/SLMoUwQP7e3Ilnv+GaI0ZHFlszu+bXKEuoNOZpFS5oxn8GkGgXs 2AdwZhtAz4Pi6nKsRXpmIcl3pBLzRHJWrTKZb83RJW68+jnzCAs7K7izLgBzHHN/s6O1 lbQpw0PXYHfCCp8ewPgNOKSRNCIUeumF3coSYZZjbbrw51VW+C4SNSyAdQ1+FhzY2aed 0mor8L/k+EGV/e5HSK4o70kznqDMRbLx2SuPl4v47x6lJ+8/sorbXvW0r6nwppWKn6+p H974iq4eaCKxcf6ACUnpNSej9EFXMueq2NehGVYtFqmz2StyAESa6mnn21qwwXsJeP3/ bsWg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=WjX12aX1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id f17-20020a170906825100b0084d200455b8si3208774ejx.556.2023.01.11.01.44.36; Wed, 11 Jan 2023 01:44:48 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=WjX12aX1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238776AbjAKJgY (ORCPT + 53 others); Wed, 11 Jan 2023 04:36:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37468 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230282AbjAKJfL (ORCPT ); Wed, 11 Jan 2023 04:35:11 -0500 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D506ED98; Wed, 11 Jan 2023 01:34:20 -0800 (PST) Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 30B7X1sn029595; Wed, 11 Jan 2023 09:34:13 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=message-id : date : mime-version : subject : to : cc : references : from : in-reply-to : content-type : content-transfer-encoding; s=qcppdkim1; bh=mvSen0YPktxZ6yY811DDXcSx4nAy7KzBUaW4BDWH8SE=; b=WjX12aX1Co7bHatr4Rakla7oHxjAM4fhKpkRCO/7rbiu2gImE7sP+6LHD+hqwMO8ynZ9 8CleY31OUMdVfmtMt6I2KH/dF1u+HSdhxrGPpVjKbcm0lpf93qH8Fgp/dLd7UYevTFCz e3D5zgjIxzAci8/Te3Nm1D8OqYRe6l4k/Tvbe/zs+VxpzVPY4tSNKpnBBAMiGlXGohVL YuWyYB0hP0lcrukRoDlaZwwl/knvGQNNpq7FOy6t6awCgxWwSwdBQVtJ/duSKP77mw5d nLQ1fDumH9C2d0apzKxnyuC/DBzrnJWlfrGQjE1fh7+pqQKAx2a7D1owUwI8BiGxq7Rf /g== Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3n1kxhgtys-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 11 Jan 2023 09:34:12 +0000 Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA04.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 30B9YCG0004761 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 11 Jan 2023 09:34:12 GMT Received: from [10.79.43.91] (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.36; Wed, 11 Jan 2023 01:34:08 -0800 Message-ID: <8ede3a51-179d-986b-ea02-d698c8bda284@quicinc.com> Date: Wed, 11 Jan 2023 15:04:05 +0530 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.2.2 Subject: Re: [PATCH V7 2/2] firmware: qcom: scm: Add wait-queue handling logic Content-Language: en-US To: Srinivas Kandagatla , CC: , , , , , , , , References: <20230110063745.16739-1-quic_sibis@quicinc.com> <20230110063745.16739-3-quic_sibis@quicinc.com> From: Sibi Sankar In-Reply-To: Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 8bit X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: zehQERBPI6N38mewlHPKkysqyWt98-lR X-Proofpoint-ORIG-GUID: zehQERBPI6N38mewlHPKkysqyWt98-lR X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2023-01-11_04,2023-01-10_03,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 mlxscore=0 phishscore=0 priorityscore=1501 spamscore=0 bulkscore=0 adultscore=0 clxscore=1011 suspectscore=0 malwarescore=0 mlxlogscore=970 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2301110073 X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NICE_REPLY_A,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hey Srini, Thanks for taking time to review the series. On 1/10/23 17:44, Srinivas Kandagatla wrote: > Hi Sibi, > > Few minor comments below, > > On 10/01/2023 06:37, Sibi Sankar wrote: >> From: Guru Das Srinagesh >> >> When the firmware (FW) supports multiple requests per VM, multiple >> requests >> from the same/different VM can reach the firmware at the same time. Since >> the firmware currently being used has limited resources, it guards them >> with a resource lock and puts requests on a wait-queue internally and >> signals to HLOS that it is doing so. It does this by returning a new >> return >> value in addition to success or error: SCM_WAITQ_SLEEP. A sleeping SCM >> call >> can be woken up by an interrupt that the FW raises. >> > ... > >>   drivers/firmware/qcom_scm-smc.c | 90 ++++++++++++++++++++++++++++++--- >>   drivers/firmware/qcom_scm.c     | 89 +++++++++++++++++++++++++++++++- >>   drivers/firmware/qcom_scm.h     |  8 +++ >>   3 files changed, 179 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/firmware/qcom_scm-smc.c >> b/drivers/firmware/qcom_scm-smc.c >> index d111833364ba..30999f04749c 100644 >> --- a/drivers/firmware/qcom_scm-smc.c >> +++ b/drivers/firmware/qcom_scm-smc.c > ... >> +static int __scm_smc_do_quirk_handle_waitq(struct device *dev, struct >> arm_smccc_args *waitq, >> +                       struct arm_smccc_res *res) >> +{ >> +    int ret; >> +    struct arm_smccc_args resume; >> +    u32 wq_ctx, smc_call_ctx, flags; >> +    struct arm_smccc_args *smc = waitq; >> + >> +    do { >> +        __scm_smc_do_quirk(smc, res); >> + >> +        if (res->a0 == QCOM_SCM_WAITQ_SLEEP) { >> +            wq_ctx = res->a1; >> +            smc_call_ctx = res->a2; >> +            flags = res->a3; >> + >> +            if (!dev) >> +                return -EPROBE_DEFER; > > why are we checking dev pointer in the middle of the call? > A comment here would really help readers. Given that we no longer use drv_data to pass around scm struct, the check is no longer required. I'll drop it in the next re-spin. > >> + >> +            ret = qcom_scm_lookup_completion(wq_ctx); >> +            if (ret) >> +                return ret; >> + >> +            fill_wq_resume_args(&resume, smc_call_ctx); >> +            smc = &resume; >> +        } >> +    } while (res->a0 == QCOM_SCM_WAITQ_SLEEP); >> + >> +    return 0; >> +} >> + > ... >> diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c >> index cdbfe54c8146..19ac506a9b1f 100644 >> --- a/drivers/firmware/qcom_scm.c >> +++ b/drivers/firmware/qcom_scm.c >> @@ -4,6 +4,7 @@ >>    */ >>   #include >>   #include >> +#include >>   #include >>   #include >>   #include >> @@ -13,6 +14,7 @@ >>   #include >>   #include >>   #include >> +#include >>   #include >>   #include >>   #include > > include ?? > ack > >> @@ -33,6 +35,7 @@ struct qcom_scm { >>       struct clk *iface_clk; >>       struct clk *bus_clk; >>       struct icc_path *path; >> +    struct completion waitq_comp; >>       struct reset_controller_dev reset; >>       /* control access to the interconnect path */ >> @@ -63,6 +66,9 @@ static const u8 >> qcom_scm_cpu_warm_bits[QCOM_SCM_BOOT_MAX_CPUS] = { >>       BIT(2), BIT(1), BIT(4), BIT(6) >>   }; >> +#define QCOM_SMC_WAITQ_FLAG_WAKE_ONE    BIT(0) >> +#define QCOM_SMC_WAITQ_FLAG_WAKE_ALL    BIT(1) >> + >>   static const char * const qcom_scm_convention_names[] = { >>       [SMC_CONVENTION_UNKNOWN] = "unknown", >>       [SMC_CONVENTION_ARM_32] = "smc arm 32", >> @@ -1325,11 +1331,79 @@ bool qcom_scm_is_available(void) >>   } >>   EXPORT_SYMBOL(qcom_scm_is_available); >> +static struct completion *qcom_scm_lookup_wq(struct qcom_scm *scm, >> u32 wq_ctx) >> +{ >> +    /* assert wq_ctx is zero */ > +    if (wq_ctx != 0) { > > Is this correct? looks like zero is the only valid one. > > I thought wq_ctx was a unique number (UID). Currently the SMC calls from the kernel scm driver are still serialized and firmware only supports a single wq_ctx. This is expected to change in the future, will document it the comments. > >> +        dev_err(scm->dev, "No waitqueue found for wq_ctx %d\n", wq_ctx); >> +        return ERR_PTR(-EINVAL); >> +    } >> + >> +    return &scm->waitq_comp; >> +} >> + >> +int qcom_scm_lookup_completion(u32 wq_ctx) >> +{ >> +    struct completion *wq = NULL; >> + >> +    wq = qcom_scm_lookup_wq(__scm, wq_ctx); >> +    if (IS_ERR(wq)) >> +        return PTR_ERR(wq); >> + >> +    wait_for_completion(wq); > > We can potentially block here forever without a timeout. > yeah potentially until a hung task timeout. This is what we want since we can't make additional scm calls anyway. > As you are reusing completion, I have not seen any reinitialization of > completion, this could potentially return above line without waiting at > all. A complete would paired with a single waiter, so additional completes would be neccessary for it to go through without waiting. > >> + >> +    return 0; >> +} >> + >> +static int qcom_scm_waitq_wakeup(struct qcom_scm *scm, unsigned int >> wq_ctx, bool wake_all) >> +{ >> +    struct completion *wq_to_wake; >> + >> +    wq_to_wake = qcom_scm_lookup_wq(scm, wq_ctx); >> +    if (IS_ERR(wq_to_wake)) >> +        return PTR_ERR(wq_to_wake); >> + >> +    if (wake_all) >> +        complete_all(wq_to_wake); >> +    else >> +        complete(wq_to_wake); > >> + >> +    return 0; >> +} >> + >> +static irqreturn_t qcom_scm_irq_handler(int irq, void *data) >> +{ >> +    int ret; >> +    struct qcom_scm *scm = data; >> +    u32 wq_ctx, flags, more_pending = 0; >> + >> +    do { >> +        ret = scm_get_wq_ctx(&wq_ctx, &flags, &more_pending); >> +        if (ret) { >> +            dev_err(scm->dev, "GET_WQ_CTX SMC call failed: %d\n", ret); >> +            goto out; >> +        } >> + >> +        if (flags != QCOM_SMC_WAITQ_FLAG_WAKE_ONE && >> +            flags != QCOM_SMC_WAITQ_FLAG_WAKE_ALL) { >> +            dev_err(scm->dev, "Invalid flags found for wq_ctx: %u\n", >> flags); >> +            goto out; >> +        } >> + >> +        ret = qcom_scm_waitq_wakeup(scm, wq_ctx, !!(flags & >> QCOM_SMC_WAITQ_FLAG_WAKE_ALL)); >> +        if (ret) >> +            goto out; >> +    } while (more_pending); >> + >> +out: >> +    return IRQ_HANDLED; >> +} >> + >>   static int qcom_scm_probe(struct platform_device *pdev) >>   { >>       struct qcom_scm *scm; >>       unsigned long clks; >> -    int ret; >> +    int irq, ret; >>       scm = devm_kzalloc(&pdev->dev, sizeof(*scm), GFP_KERNEL); >>       if (!scm) >> @@ -1402,6 +1476,19 @@ static int qcom_scm_probe(struct >> platform_device *pdev) >>       __scm = scm; >>       __scm->dev = &pdev->dev; >> +    init_completion(&__scm->waitq_comp); >> + >> +    irq = platform_get_irq(pdev, 0); >> +    if (irq < 0) { >> +        if (irq != -ENXIO) >> +            return irq; >> +    } else { >> +        ret = devm_request_threaded_irq(__scm->dev, irq, NULL, >> qcom_scm_irq_handler, >> +                        IRQF_ONESHOT, "qcom-scm", __scm); >> +        if (ret < 0) >> +            return dev_err_probe(scm->dev, ret, "Failed to request >> qcom-scm irq\n"); >> +    } >> + >>       __get_convention(); >>       /* > > --srini