Message ID | 20230612195657.245125-12-eajames@linux.ibm.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp101838vqr; Mon, 12 Jun 2023 13:00:34 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7CBouxMS0fv4p6QtLsdChF0ob0qDGv39Sh7Xmz3STPB7cdajT3ta2HYx+G7c22M9iHHnSe X-Received: by 2002:a05:6402:3506:b0:514:a21b:f137 with SMTP id b6-20020a056402350600b00514a21bf137mr6556365edd.6.1686600034338; Mon, 12 Jun 2023 13:00:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686600034; cv=none; d=google.com; s=arc-20160816; b=KoQJCcm7c+Ag2NGjxjNX488mQWQ7uNQS2HYObIzsl090FRwfIiD2IoUsmcL4JeIkbF 95T3sjQev1JyP40DvtjE3uH5JaWQ2FWJj0VCCLZwjSYP4vTTTrzFcUZ0TQMRhaS02mNA vIFBE/JuO3W1hgtJTy5oVY+ZVvyzTMclc7cuVvd0gzd3XKIYCPuvJMDsuOQYcD7/R0vS ICk3TFCVmk8DOPvHY+OevBJyoJfQYs+QfMyCuHdPbH8ajR67ePFJDYacI4YasUUovXTc Zyfjmabg5hnTJnUzLnbE49VSk/lQSxJLWaUhmpldCAz1oEioj1TjGl+iB58qQryDjzkL tQBw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=zkjo7yw+XyzaXEbEFhbeLIcrenF/SgLQDubhtwnz964=; b=VYy0FV7JUbgFqThUuYgF1dkb3e2IgH4ZXWAfmBLiihoLLfUJvN/XoM5gycI6+uNe9x zwGT44rHaZy4hJsCiiBUKmDZCdFS/GhdQsQ3KK7shjv66zw53V8CizfkrxRg3cjK+Val x1i/boaojsFUIDS/uXCXeimJxNqhwK5uTeyfywIGKZNNYTTvVlK8uuYFMfyc9LY8RQUq TLOQoZdI+SrpTUXOf3/EV3f/WA8qZGzONhVA1kFYGpWbM69K6DL6V1KRnYk89qKKGeXb bRrYCO2qTtorTGan8lwcSRq9TORnpHzOMoBJmO9M5fA1p21/IKoIAwQ559J57x9mof0S byMg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ibm.com header.s=pp1 header.b=SrptcaKH; 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=REJECT sp=NONE dis=NONE) header.from=ibm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id l6-20020aa7d946000000b00514b957c9dfsi6244649eds.571.2023.06.12.13.00.07; Mon, 12 Jun 2023 13:00:34 -0700 (PDT) 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=@ibm.com header.s=pp1 header.b=SrptcaKH; 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=REJECT sp=NONE dis=NONE) header.from=ibm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238256AbjFLT5c (ORCPT <rfc822;rust.linux@gmail.com> + 99 others); Mon, 12 Jun 2023 15:57:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231726AbjFLT5S (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Mon, 12 Jun 2023 15:57:18 -0400 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 35F6910CC; Mon, 12 Jun 2023 12:57:17 -0700 (PDT) Received: from pps.filterd (m0353726.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 35CJl6gI006086; Mon, 12 Jun 2023 19:57:04 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=zkjo7yw+XyzaXEbEFhbeLIcrenF/SgLQDubhtwnz964=; b=SrptcaKHy414ZL73/2ZgKpgMcioAd2mVLbUr87dtCg32+TD6eBropJpZx2EGt8MWhSvp NJoRbc220y9O5OX3zqjMZerwCLUIuvhyJUY9/hNocf3lPRnst7nYf+Xuks7+x3PIjBoG Z515vSXImwu0PDOi30G9egl1wTpJ4erptTMEtzgsFI3JQSqIaWkZdrD/rC9X3zymFcPy p+YCx71RDRVD6kxSIO0SDuQ/MzhUeskzeE9/wUQZUQGbXmk+O/5HWwxO9VNrsTPK5fGu uct2NG0+F2hYfd3av3tpFsEch8B0v7t88fP2PVpBfS/VYa5Pi9BWXIQsVvBzUdkzbz6n oQ== Received: from ppma02dal.us.ibm.com (a.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.10]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3r69tqg661-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 12 Jun 2023 19:57:03 +0000 Received: from pps.filterd (ppma02dal.us.ibm.com [127.0.0.1]) by ppma02dal.us.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 35CJ0qZQ027199; Mon, 12 Jun 2023 19:57:02 GMT Received: from smtprelay03.dal12v.mail.ibm.com ([9.208.130.98]) by ppma02dal.us.ibm.com (PPS) with ESMTPS id 3r4gt5krr6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 12 Jun 2023 19:57:02 +0000 Received: from smtpav06.dal12v.mail.ibm.com (smtpav06.dal12v.mail.ibm.com [10.241.53.105]) by smtprelay03.dal12v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 35CJv1b451577340 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 12 Jun 2023 19:57:01 GMT Received: from smtpav06.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B2A445805F; Mon, 12 Jun 2023 19:57:01 +0000 (GMT) Received: from smtpav06.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6D4E25805E; Mon, 12 Jun 2023 19:57:01 +0000 (GMT) Received: from slate16.aus.stglabs.ibm.com (unknown [9.61.148.226]) by smtpav06.dal12v.mail.ibm.com (Postfix) with ESMTP; Mon, 12 Jun 2023 19:57:01 +0000 (GMT) From: Eddie James <eajames@linux.ibm.com> To: linux-fsi@lists.ozlabs.org Cc: linux-kernel@vger.kernel.org, jk@ozlabs.org, joel@jms.id.au, alistair@popple.id.au, andrew@aj.id.au, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, devicetree@vger.kernel.org Subject: [PATCH 11/14] fsi: Improve master indexing Date: Mon, 12 Jun 2023 14:56:54 -0500 Message-Id: <20230612195657.245125-12-eajames@linux.ibm.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20230612195657.245125-1-eajames@linux.ibm.com> References: <20230612195657.245125-1-eajames@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: bYjn5AaMjBJ187RLnVB6mJMQ7ex554vw X-Proofpoint-GUID: bYjn5AaMjBJ187RLnVB6mJMQ7ex554vw X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.573,FMLib:17.11.176.26 definitions=2023-06-12_14,2023-06-12_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 impostorscore=0 clxscore=1015 mlxlogscore=999 bulkscore=0 spamscore=0 lowpriorityscore=0 phishscore=0 suspectscore=0 adultscore=0 priorityscore=1501 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2305260000 definitions=main-2306120169 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_EF,RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE 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: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1768528317865067576?= X-GMAIL-MSGID: =?utf-8?q?1768528317865067576?= |
Series |
fsi: Miscellaneous fixes and I2C Responder driver
|
|
Commit Message
Eddie James
June 12, 2023, 7:56 p.m. UTC
Master indexing is problematic if a hub is rescanned while the
root master is being rescanned. Move the IDA free below the device
unregistration, lock the scan mutex in the probe function, and
request a specific idx in the hub driver.
Signed-off-by: Eddie James <eajames@linux.ibm.com>
---
drivers/fsi/fsi-core.c | 41 ++++++++++++++++++++++--------------
drivers/fsi/fsi-master-hub.c | 2 ++
2 files changed, 27 insertions(+), 16 deletions(-)
Comments
On Mon, 12 Jun 2023 at 19:57, Eddie James <eajames@linux.ibm.com> wrote: > > Master indexing is problematic if a hub is rescanned while the > root master is being rescanned. Move the IDA free below the device > unregistration, lock the scan mutex in the probe function, and > request a specific idx in the hub driver. I've applied this series, but taking a closer look at this patch I think it can be improved. If you resend, just send this patch. > > Signed-off-by: Eddie James <eajames@linux.ibm.com> > --- > drivers/fsi/fsi-core.c | 41 ++++++++++++++++++++++-------------- > drivers/fsi/fsi-master-hub.c | 2 ++ > 2 files changed, 27 insertions(+), 16 deletions(-) > > diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c > index ec4d02264391..503061a6740b 100644 > --- a/drivers/fsi/fsi-core.c > +++ b/drivers/fsi/fsi-core.c > @@ -1327,46 +1327,55 @@ static struct class fsi_master_class = { > int fsi_master_register(struct fsi_master *master) > { > int rc; > - struct device_node *np; > > mutex_init(&master->scan_lock); > - master->idx = ida_alloc(&master_ida, GFP_KERNEL); > + > + if (master->idx) { Why do we allocate a new idx if there's already one? > + master->idx = ida_alloc_range(&master_ida, master->idx, > + master->idx, GFP_KERNEL); If we can't get one in the range we want, we ask for any? Should this print a warning? > + if (master->idx < 0) > + master->idx = ida_alloc(&master_ida, GFP_KERNEL); > + } else { If ixd was zero, we create one. This is the "normal" case? > + master->idx = ida_alloc(&master_ida, GFP_KERNEL); > + } > + We check the same error condition again. > if (master->idx < 0) > return master->idx; > > - dev_set_name(&master->dev, "fsi%d", master->idx); > + if (!dev_name(&master->dev)) > + dev_set_name(&master->dev, "fsi%d", master->idx); > + > master->dev.class = &fsi_master_class; > > + mutex_lock(&master->scan_lock); > rc = device_register(&master->dev); > if (rc) { > ida_free(&master_ida, master->idx); > - return rc; > - } > + } else { > + struct device_node *np = dev_of_node(&master->dev); This change looks a bit different to the idx changes. What's happening here? > > - np = dev_of_node(&master->dev); > - if (!of_property_read_bool(np, "no-scan-on-init")) { > - mutex_lock(&master->scan_lock); > - fsi_master_scan(master); > - mutex_unlock(&master->scan_lock); > + if (!of_property_read_bool(np, "no-scan-on-init")) > + fsi_master_scan(master); > } > > - return 0; > + mutex_unlock(&master->scan_lock); > + return rc; > } > EXPORT_SYMBOL_GPL(fsi_master_register); > > void fsi_master_unregister(struct fsi_master *master) > { > - trace_fsi_master_unregister(master); > + int idx = master->idx; > > - if (master->idx >= 0) { > - ida_free(&master_ida, master->idx); > - master->idx = -1; > - } > + trace_fsi_master_unregister(master); > > mutex_lock(&master->scan_lock); > fsi_master_unscan(master); > + master->n_links = 0; > mutex_unlock(&master->scan_lock); > + > device_unregister(&master->dev); > + ida_free(&master_ida, idx); > } > EXPORT_SYMBOL_GPL(fsi_master_unregister); > > diff --git a/drivers/fsi/fsi-master-hub.c b/drivers/fsi/fsi-master-hub.c > index 6d8b6e8854e5..36da643b3201 100644 > --- a/drivers/fsi/fsi-master-hub.c > +++ b/drivers/fsi/fsi-master-hub.c > @@ -12,6 +12,7 @@ > #include <linux/slab.h> > > #include "fsi-master.h" > +#include "fsi-slave.h" > > #define FSI_ENGID_HUB_MASTER 0x1c > > @@ -229,6 +230,7 @@ static int hub_master_probe(struct device *dev) > hub->master.dev.release = hub_master_release; > hub->master.dev.of_node = of_node_get(dev_of_node(dev)); > > + hub->master.idx = fsi_dev->slave->link + 1; > hub->master.n_links = links; > hub->master.read = hub_master_read; > hub->master.write = hub_master_write; > -- > 2.31.1 >
On Wed, 9 Aug 2023 at 07:08, Joel Stanley <joel@jms.id.au> wrote: > > On Mon, 12 Jun 2023 at 19:57, Eddie James <eajames@linux.ibm.com> wrote: > > > > Master indexing is problematic if a hub is rescanned while the > > root master is being rescanned. Move the IDA free below the device > > unregistration, lock the scan mutex in the probe function, and > > request a specific idx in the hub driver. > > I've applied this series, but taking a closer look at this patch I > think it can be improved. If you resend, just send this patch. On hardware, it did this at FSI scan time: WARNING: CPU: 0 PID: 761 at /lib/idr.c:525 ida_free+0x140/0x154 ida_free called for id=1 which is not allocated. CPU: 0 PID: 761 Comm: openpower-proc- Not tainted 6.1.34-d42f59e #1 Hardware name: Generic DT based system unwind_backtrace from show_stack+0x18/0x1c show_stack from dump_stack_lvl+0x24/0x2c dump_stack_lvl from __warn+0x74/0xf0 __warn from warn_slowpath_fmt+0x9c/0xd8 warn_slowpath_fmt from ida_free+0x140/0x154 ida_free from fsi_master_register+0xd0/0xf0 fsi_master_register from hub_master_probe+0x11c/0x358 hub_master_probe from really_probe+0xd4/0x3f0 really_probe from driver_probe_device+0x38/0xd0 driver_probe_device from __device_attach_driver+0xc8/0x148 __device_attach_driver from bus_for_each_drv+0x90/0xdc bus_for_each_drv from __device_attach+0x114/0x1a4 __device_attach from bus_probe_device+0x8c/0x94 bus_probe_device from device_add+0x3a8/0x7fc device_add from fsi_master_scan+0x4e0/0x950 fsi_master_scan from fsi_master_rescan+0x38/0x88 fsi_master_rescan from master_rescan_store+0x14/0x20 master_rescan_store from kernfs_fop_write_iter+0x114/0x200 kernfs_fop_write_iter from vfs_write+0x1d0/0x374 vfs_write from ksys_write+0x78/0x100 ksys_write from ret_fast_syscall+0x0/0x54 Exception stack(0x9fc51fa8 to 0x9fc51ff0) 1fa0: 00000001 01a01c78 00000003 01a01c78 00000001 00000001 1fc0: 00000001 01a01c78 00000001 00000004 7eeb4ab0 7eeb4b3c 7eeb4ab4 7eeb499c 1fe0: 76985abc 7eeb4928 76848af8 766f176c > > > > > Signed-off-by: Eddie James <eajames@linux.ibm.com> > > --- > > drivers/fsi/fsi-core.c | 41 ++++++++++++++++++++++-------------- > > drivers/fsi/fsi-master-hub.c | 2 ++ > > 2 files changed, 27 insertions(+), 16 deletions(-) > > > > diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c > > index ec4d02264391..503061a6740b 100644 > > --- a/drivers/fsi/fsi-core.c > > +++ b/drivers/fsi/fsi-core.c > > @@ -1327,46 +1327,55 @@ static struct class fsi_master_class = { > > int fsi_master_register(struct fsi_master *master) > > { > > int rc; > > - struct device_node *np; > > > > mutex_init(&master->scan_lock); > > - master->idx = ida_alloc(&master_ida, GFP_KERNEL); > > + > > + if (master->idx) { > > Why do we allocate a new idx if there's already one? > > > + master->idx = ida_alloc_range(&master_ida, master->idx, > > + master->idx, GFP_KERNEL); > > If we can't get one in the range we want, we ask for any? Should this > print a warning? > > > + if (master->idx < 0) > > + master->idx = ida_alloc(&master_ida, GFP_KERNEL); > > + } else { > > If ixd was zero, we create one. This is the "normal" case? > > > + master->idx = ida_alloc(&master_ida, GFP_KERNEL); > > + } > > + > > We check the same error condition again. > > > if (master->idx < 0) > > return master->idx; > > > > > - dev_set_name(&master->dev, "fsi%d", master->idx); > > + if (!dev_name(&master->dev)) > > + dev_set_name(&master->dev, "fsi%d", master->idx); > > + > > master->dev.class = &fsi_master_class; > > > > + mutex_lock(&master->scan_lock); > > rc = device_register(&master->dev); > > if (rc) { > > ida_free(&master_ida, master->idx); > > - return rc; > > - } > > + } else { > > + struct device_node *np = dev_of_node(&master->dev); > > This change looks a bit different to the idx changes. What's happening here? > > > > - np = dev_of_node(&master->dev); > > - if (!of_property_read_bool(np, "no-scan-on-init")) { > > - mutex_lock(&master->scan_lock); > > - fsi_master_scan(master); > > - mutex_unlock(&master->scan_lock); > > + if (!of_property_read_bool(np, "no-scan-on-init")) > > + fsi_master_scan(master); > > } > > > > - return 0; > > + mutex_unlock(&master->scan_lock); > > + return rc; > > } > > EXPORT_SYMBOL_GPL(fsi_master_register); > > > > void fsi_master_unregister(struct fsi_master *master) > > { > > - trace_fsi_master_unregister(master); > > + int idx = master->idx; > > > > - if (master->idx >= 0) { > > - ida_free(&master_ida, master->idx); > > - master->idx = -1; > > - } > > + trace_fsi_master_unregister(master); > > > > mutex_lock(&master->scan_lock); > > fsi_master_unscan(master); > > + master->n_links = 0; > > mutex_unlock(&master->scan_lock); > > + > > device_unregister(&master->dev); > > + ida_free(&master_ida, idx); > > } > > EXPORT_SYMBOL_GPL(fsi_master_unregister); > > > > diff --git a/drivers/fsi/fsi-master-hub.c b/drivers/fsi/fsi-master-hub.c > > index 6d8b6e8854e5..36da643b3201 100644 > > --- a/drivers/fsi/fsi-master-hub.c > > +++ b/drivers/fsi/fsi-master-hub.c > > @@ -12,6 +12,7 @@ > > #include <linux/slab.h> > > > > #include "fsi-master.h" > > +#include "fsi-slave.h" > > > > #define FSI_ENGID_HUB_MASTER 0x1c > > > > @@ -229,6 +230,7 @@ static int hub_master_probe(struct device *dev) > > hub->master.dev.release = hub_master_release; > > hub->master.dev.of_node = of_node_get(dev_of_node(dev)); > > > > + hub->master.idx = fsi_dev->slave->link + 1; > > hub->master.n_links = links; > > hub->master.read = hub_master_read; > > hub->master.write = hub_master_write; > > -- > > 2.31.1 > >
On 8/9/23 06:55, Joel Stanley wrote: > On Wed, 9 Aug 2023 at 07:08, Joel Stanley <joel@jms.id.au> wrote: >> On Mon, 12 Jun 2023 at 19:57, Eddie James <eajames@linux.ibm.com> wrote: >>> Master indexing is problematic if a hub is rescanned while the >>> root master is being rescanned. Move the IDA free below the device >>> unregistration, lock the scan mutex in the probe function, and >>> request a specific idx in the hub driver. >> I've applied this series, but taking a closer look at this patch I >> think it can be improved. If you resend, just send this patch. > On hardware, it did this at FSI scan time: Well this backtrace is without this patch, right? The hub master changes that went in are dependent on this patch. master->idx is 1 for the hub but it's not being allocated in the ida and the device name isn't getting set. So device registration fails and then trying to free the index in the ida causes this warning. I'll reply to your comments in your other email and rebase and resend. > > WARNING: CPU: 0 PID: 761 at /lib/idr.c:525 ida_free+0x140/0x154 > ida_free called for id=1 which is not allocated. > CPU: 0 PID: 761 Comm: openpower-proc- Not tainted 6.1.34-d42f59e #1 > Hardware name: Generic DT based system > unwind_backtrace from show_stack+0x18/0x1c > show_stack from dump_stack_lvl+0x24/0x2c > dump_stack_lvl from __warn+0x74/0xf0 > __warn from warn_slowpath_fmt+0x9c/0xd8 > warn_slowpath_fmt from ida_free+0x140/0x154 > ida_free from fsi_master_register+0xd0/0xf0 > fsi_master_register from hub_master_probe+0x11c/0x358 > hub_master_probe from really_probe+0xd4/0x3f0 > really_probe from driver_probe_device+0x38/0xd0 > driver_probe_device from __device_attach_driver+0xc8/0x148 > __device_attach_driver from bus_for_each_drv+0x90/0xdc > bus_for_each_drv from __device_attach+0x114/0x1a4 > __device_attach from bus_probe_device+0x8c/0x94 > bus_probe_device from device_add+0x3a8/0x7fc > device_add from fsi_master_scan+0x4e0/0x950 > fsi_master_scan from fsi_master_rescan+0x38/0x88 > fsi_master_rescan from master_rescan_store+0x14/0x20 > master_rescan_store from kernfs_fop_write_iter+0x114/0x200 > kernfs_fop_write_iter from vfs_write+0x1d0/0x374 > vfs_write from ksys_write+0x78/0x100 > ksys_write from ret_fast_syscall+0x0/0x54 > Exception stack(0x9fc51fa8 to 0x9fc51ff0) > 1fa0: 00000001 01a01c78 00000003 01a01c78 00000001 00000001 > 1fc0: 00000001 01a01c78 00000001 00000004 7eeb4ab0 7eeb4b3c 7eeb4ab4 7eeb499c > 1fe0: 76985abc 7eeb4928 76848af8 766f176c > > >>> Signed-off-by: Eddie James <eajames@linux.ibm.com> >>> --- >>> drivers/fsi/fsi-core.c | 41 ++++++++++++++++++++++-------------- >>> drivers/fsi/fsi-master-hub.c | 2 ++ >>> 2 files changed, 27 insertions(+), 16 deletions(-) >>> >>> diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c >>> index ec4d02264391..503061a6740b 100644 >>> --- a/drivers/fsi/fsi-core.c >>> +++ b/drivers/fsi/fsi-core.c >>> @@ -1327,46 +1327,55 @@ static struct class fsi_master_class = { >>> int fsi_master_register(struct fsi_master *master) >>> { >>> int rc; >>> - struct device_node *np; >>> >>> mutex_init(&master->scan_lock); >>> - master->idx = ida_alloc(&master_ida, GFP_KERNEL); >>> + >>> + if (master->idx) { >> Why do we allocate a new idx if there's already one? >> >>> + master->idx = ida_alloc_range(&master_ida, master->idx, >>> + master->idx, GFP_KERNEL); >> If we can't get one in the range we want, we ask for any? Should this >> print a warning? >> >>> + if (master->idx < 0) >>> + master->idx = ida_alloc(&master_ida, GFP_KERNEL); >>> + } else { >> If ixd was zero, we create one. This is the "normal" case? >> >>> + master->idx = ida_alloc(&master_ida, GFP_KERNEL); >>> + } >>> + >> We check the same error condition again. >> >>> if (master->idx < 0) >>> return master->idx; >>> - dev_set_name(&master->dev, "fsi%d", master->idx); >>> + if (!dev_name(&master->dev)) >>> + dev_set_name(&master->dev, "fsi%d", master->idx); >>> + >>> master->dev.class = &fsi_master_class; >>> >>> + mutex_lock(&master->scan_lock); >>> rc = device_register(&master->dev); >>> if (rc) { >>> ida_free(&master_ida, master->idx); >>> - return rc; >>> - } >>> + } else { >>> + struct device_node *np = dev_of_node(&master->dev); >> This change looks a bit different to the idx changes. What's happening here? >>> - np = dev_of_node(&master->dev); >>> - if (!of_property_read_bool(np, "no-scan-on-init")) { >>> - mutex_lock(&master->scan_lock); >>> - fsi_master_scan(master); >>> - mutex_unlock(&master->scan_lock); >>> + if (!of_property_read_bool(np, "no-scan-on-init")) >>> + fsi_master_scan(master); >>> } >>> >>> - return 0; >>> + mutex_unlock(&master->scan_lock); >>> + return rc; >>> } >>> EXPORT_SYMBOL_GPL(fsi_master_register); >>> >>> void fsi_master_unregister(struct fsi_master *master) >>> { >>> - trace_fsi_master_unregister(master); >>> + int idx = master->idx; >>> >>> - if (master->idx >= 0) { >>> - ida_free(&master_ida, master->idx); >>> - master->idx = -1; >>> - } >>> + trace_fsi_master_unregister(master); >>> >>> mutex_lock(&master->scan_lock); >>> fsi_master_unscan(master); >>> + master->n_links = 0; >>> mutex_unlock(&master->scan_lock); >>> + >>> device_unregister(&master->dev); >>> + ida_free(&master_ida, idx); >>> } >>> EXPORT_SYMBOL_GPL(fsi_master_unregister); >>> >>> diff --git a/drivers/fsi/fsi-master-hub.c b/drivers/fsi/fsi-master-hub.c >>> index 6d8b6e8854e5..36da643b3201 100644 >>> --- a/drivers/fsi/fsi-master-hub.c >>> +++ b/drivers/fsi/fsi-master-hub.c >>> @@ -12,6 +12,7 @@ >>> #include <linux/slab.h> >>> >>> #include "fsi-master.h" >>> +#include "fsi-slave.h" >>> >>> #define FSI_ENGID_HUB_MASTER 0x1c >>> >>> @@ -229,6 +230,7 @@ static int hub_master_probe(struct device *dev) >>> hub->master.dev.release = hub_master_release; >>> hub->master.dev.of_node = of_node_get(dev_of_node(dev)); >>> >>> + hub->master.idx = fsi_dev->slave->link + 1; >>> hub->master.n_links = links; >>> hub->master.read = hub_master_read; >>> hub->master.write = hub_master_write; >>> -- >>> 2.31.1 >>>
On 8/9/23 02:08, Joel Stanley wrote: > On Mon, 12 Jun 2023 at 19:57, Eddie James <eajames@linux.ibm.com> wrote: >> Master indexing is problematic if a hub is rescanned while the >> root master is being rescanned. Move the IDA free below the device >> unregistration, lock the scan mutex in the probe function, and >> request a specific idx in the hub driver. > I've applied this series, but taking a closer look at this patch I > think it can be improved. If you resend, just send this patch. > >> Signed-off-by: Eddie James <eajames@linux.ibm.com> >> --- >> drivers/fsi/fsi-core.c | 41 ++++++++++++++++++++++-------------- >> drivers/fsi/fsi-master-hub.c | 2 ++ >> 2 files changed, 27 insertions(+), 16 deletions(-) >> >> diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c >> index ec4d02264391..503061a6740b 100644 >> --- a/drivers/fsi/fsi-core.c >> +++ b/drivers/fsi/fsi-core.c >> @@ -1327,46 +1327,55 @@ static struct class fsi_master_class = { >> int fsi_master_register(struct fsi_master *master) >> { >> int rc; >> - struct device_node *np; >> >> mutex_init(&master->scan_lock); >> - master->idx = ida_alloc(&master_ida, GFP_KERNEL); >> + >> + if (master->idx) { > Why do we allocate a new idx if there's already one? At this point, the master driver (aspeed, hub, i2cr, whatever) might just be requesting a certain index. It's not allocated yet, so it needs to be allocated so that we don't get overlap. > >> + master->idx = ida_alloc_range(&master_ida, master->idx, >> + master->idx, GFP_KERNEL); > If we can't get one in the range we want, we ask for any? Should this > print a warning? Perhaps, we could also return error here if we decide that the requested index is needed and not just wanted. > >> + if (master->idx < 0) >> + master->idx = ida_alloc(&master_ida, GFP_KERNEL); >> + } else { > If ixd was zero, we create one. This is the "normal" case? Yes, the assumption is: zero is the default due to zero-alloc'd master structures. > >> + master->idx = ida_alloc(&master_ida, GFP_KERNEL); >> + } >> + > We check the same error condition again. Yes I might be able to make this cleaner... > >> if (master->idx < 0) >> return master->idx; >> - dev_set_name(&master->dev, "fsi%d", master->idx); >> + if (!dev_name(&master->dev)) >> + dev_set_name(&master->dev, "fsi%d", master->idx); >> + >> master->dev.class = &fsi_master_class; >> >> + mutex_lock(&master->scan_lock); >> rc = device_register(&master->dev); >> if (rc) { >> ida_free(&master_ida, master->idx); >> - return rc; >> - } >> + } else { >> + struct device_node *np = dev_of_node(&master->dev); > This change looks a bit different to the idx changes. What's happening here? This is just restructuring to get the lock before the scan. It could be a separate commit, yea. Thanks for the review! Eddie >> - np = dev_of_node(&master->dev); >> - if (!of_property_read_bool(np, "no-scan-on-init")) { >> - mutex_lock(&master->scan_lock); >> - fsi_master_scan(master); >> - mutex_unlock(&master->scan_lock); >> + if (!of_property_read_bool(np, "no-scan-on-init")) >> + fsi_master_scan(master); >> } >> >> - return 0; >> + mutex_unlock(&master->scan_lock); >> + return rc; >> } >> EXPORT_SYMBOL_GPL(fsi_master_register); >> >> void fsi_master_unregister(struct fsi_master *master) >> { >> - trace_fsi_master_unregister(master); >> + int idx = master->idx; >> >> - if (master->idx >= 0) { >> - ida_free(&master_ida, master->idx); >> - master->idx = -1; >> - } >> + trace_fsi_master_unregister(master); >> >> mutex_lock(&master->scan_lock); >> fsi_master_unscan(master); >> + master->n_links = 0; >> mutex_unlock(&master->scan_lock); >> + >> device_unregister(&master->dev); >> + ida_free(&master_ida, idx); >> } >> EXPORT_SYMBOL_GPL(fsi_master_unregister); >> >> diff --git a/drivers/fsi/fsi-master-hub.c b/drivers/fsi/fsi-master-hub.c >> index 6d8b6e8854e5..36da643b3201 100644 >> --- a/drivers/fsi/fsi-master-hub.c >> +++ b/drivers/fsi/fsi-master-hub.c >> @@ -12,6 +12,7 @@ >> #include <linux/slab.h> >> >> #include "fsi-master.h" >> +#include "fsi-slave.h" >> >> #define FSI_ENGID_HUB_MASTER 0x1c >> >> @@ -229,6 +230,7 @@ static int hub_master_probe(struct device *dev) >> hub->master.dev.release = hub_master_release; >> hub->master.dev.of_node = of_node_get(dev_of_node(dev)); >> >> + hub->master.idx = fsi_dev->slave->link + 1; >> hub->master.n_links = links; >> hub->master.read = hub_master_read; >> hub->master.write = hub_master_write; >> -- >> 2.31.1 >>
diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index ec4d02264391..503061a6740b 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -1327,46 +1327,55 @@ static struct class fsi_master_class = { int fsi_master_register(struct fsi_master *master) { int rc; - struct device_node *np; mutex_init(&master->scan_lock); - master->idx = ida_alloc(&master_ida, GFP_KERNEL); + + if (master->idx) { + master->idx = ida_alloc_range(&master_ida, master->idx, + master->idx, GFP_KERNEL); + if (master->idx < 0) + master->idx = ida_alloc(&master_ida, GFP_KERNEL); + } else { + master->idx = ida_alloc(&master_ida, GFP_KERNEL); + } + if (master->idx < 0) return master->idx; - dev_set_name(&master->dev, "fsi%d", master->idx); + if (!dev_name(&master->dev)) + dev_set_name(&master->dev, "fsi%d", master->idx); + master->dev.class = &fsi_master_class; + mutex_lock(&master->scan_lock); rc = device_register(&master->dev); if (rc) { ida_free(&master_ida, master->idx); - return rc; - } + } else { + struct device_node *np = dev_of_node(&master->dev); - np = dev_of_node(&master->dev); - if (!of_property_read_bool(np, "no-scan-on-init")) { - mutex_lock(&master->scan_lock); - fsi_master_scan(master); - mutex_unlock(&master->scan_lock); + if (!of_property_read_bool(np, "no-scan-on-init")) + fsi_master_scan(master); } - return 0; + mutex_unlock(&master->scan_lock); + return rc; } EXPORT_SYMBOL_GPL(fsi_master_register); void fsi_master_unregister(struct fsi_master *master) { - trace_fsi_master_unregister(master); + int idx = master->idx; - if (master->idx >= 0) { - ida_free(&master_ida, master->idx); - master->idx = -1; - } + trace_fsi_master_unregister(master); mutex_lock(&master->scan_lock); fsi_master_unscan(master); + master->n_links = 0; mutex_unlock(&master->scan_lock); + device_unregister(&master->dev); + ida_free(&master_ida, idx); } EXPORT_SYMBOL_GPL(fsi_master_unregister); diff --git a/drivers/fsi/fsi-master-hub.c b/drivers/fsi/fsi-master-hub.c index 6d8b6e8854e5..36da643b3201 100644 --- a/drivers/fsi/fsi-master-hub.c +++ b/drivers/fsi/fsi-master-hub.c @@ -12,6 +12,7 @@ #include <linux/slab.h> #include "fsi-master.h" +#include "fsi-slave.h" #define FSI_ENGID_HUB_MASTER 0x1c @@ -229,6 +230,7 @@ static int hub_master_probe(struct device *dev) hub->master.dev.release = hub_master_release; hub->master.dev.of_node = of_node_get(dev_of_node(dev)); + hub->master.idx = fsi_dev->slave->link + 1; hub->master.n_links = links; hub->master.read = hub_master_read; hub->master.write = hub_master_write;