From: Hannes Reinecke <hare@suse.de>
To: Damien Le Moal <damien.lemoal@opensource.wdc.com>,
Ondrej Zary <linux@zary.sk>
Cc: Christoph Hellwig <hch@lst.de>,
Sergey Shtylyov <s.shtylyov@omp.ru>, Jens Axboe <axboe@kernel.dk>,
Tim Waugh <tim@cyberelk.net>,
linux-block@vger.kernel.org, linux-parport@lists.infradead.org,
linux-ide@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] pata_parport: add driver (PARIDE replacement)
Date: Tue, 15 Nov 2022 09:04:49 +0100 [thread overview]
Message-ID: <61b91b3c-bd4d-05a4-bb66-f4fd344fa45a@suse.de> (raw)
In-Reply-To: <dc4e757a-737d-0bfa-c85d-9521feaa8d5f@opensource.wdc.com>
[-- Attachment #1: Type: text/plain, Size: 1712 bytes --]
On 11/15/22 04:06, Damien Le Moal wrote:
> On 11/15/22 04:25, Ondrej Zary wrote:
>> On Monday 14 November 2022 09:03:28 Damien Le Moal wrote:
>>> On 11/14/22 16:53, Ondrej Zary wrote:
>>>> On Monday 14 November 2022, Damien Le Moal wrote:
>>>>> On 11/12/22 20:17, Ondrej Zary wrote:
>>>>>> On Wednesday 19 October 2022 09:34:31 Christoph Hellwig wrote:
>>>>>>> It's been a while - did you get a chance to make some progress on
>>>>>>> this? Do you need any help to unblock you?
>>>>>>>
>>>>>>
>>>>>> Sorry again, I'm back now. Trying to fix locking problems.
>>>>>> Added this to each function for analysis how the functions are called wrt.
>>>>>> locking:
>>>>>>
>>>>>> printk("%s, locked=%d\n", __FUNCTION__, spin_is_locked(ap->lock));
>>>>>
>>>>> Do you have your code somewhere that we can look at ?
>>>>
>>>> This is the current version with debug printks. I've also added dump_stack()
>>>> to find out the code path but haven't analyzed the output yet.
>>>
>>> Can you send a proper patch ? Or a link to a git tree ? That is easier to
>>> handle than pasted code in an email...
>>
>> Patch against what? I don't have a git server.
>
> patch against current 6.1-rc, or against an older kernel should be OK too.
> But please "git send-email" a patch, or push your dev tree to github ?
>
Please check the attachment; I've converted Ondrey mail to a patch
relative to the original submission.
Cheers,
Hannes
--
Dr. Hannes Reinecke Kernel Storage Architect
hare@suse.de +49 911 74053 688
SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), Geschäftsführer: Ivo Totev, Andrew
Myers, Andrew McDonald, Martje Boudien Moerman
[-- Attachment #2: 0001-pata_parport-debug-patch-for-locking-issues.patch --]
[-- Type: text/x-patch, Size: 8992 bytes --]
From 994330bafd68da875469718064ac622e42adcc97 Mon Sep 17 00:00:00 2001
From: Hannes Reinecke <hare@suse.de>
Date: Tue, 15 Nov 2022 08:57:51 +0100
Subject: [PATCH] pata_parport: debug patch for locking issues
Add logging messages to debug locking issues.
Signed-off-by: Ondrey Zary <linux@zary.sk>
---
drivers/ata/pata_parport.c | 112 ++++++++++++++++++-------------------
1 file changed, 56 insertions(+), 56 deletions(-)
diff --git a/drivers/ata/pata_parport.c b/drivers/ata/pata_parport.c
index 783764626a27..513567ce66a3 100644
--- a/drivers/ata/pata_parport.c
+++ b/drivers/ata/pata_parport.c
@@ -25,8 +25,12 @@ MODULE_PARM_DESC(verbose, "Enable verbose messages (0=off [default], 1=on)");
#define DISCONNECT_TIMEOUT (HZ / 10)
-static void pi_connect(struct pi_adapter *pi)
+static void pi_connect(struct ata_port *ap)
{
+ struct pi_adapter *pi = ap->host->private_data;
+ if (spin_is_locked(ap->lock))
+ dump_stack();
+
del_timer_sync(&pi->timer);
if (!pi->claimed) {
pi->claimed = true;
@@ -35,10 +39,8 @@ static void pi_connect(struct pi_adapter *pi)
}
}
-static void pi_disconnect_timer(struct timer_list *t)
+static void pi_disconnect(struct pi_adapter *pi)
{
- struct pi_adapter *pi = from_timer(pi, t, timer);
-
if (pi->claimed) {
pi->proto->disconnect(pi);
parport_release(pi->pardev);
@@ -46,18 +48,26 @@ static void pi_disconnect_timer(struct timer_list *t)
}
}
+static void pi_disconnect_timer(struct timer_list *t)
+{
+ struct pi_adapter *pi = from_timer(pi, t, timer);
+
+ pi_disconnect(pi);
+}
+
/* functions taken from libata-sff.c and converted from direct port I/O */
static void pata_parport_dev_select(struct ata_port *ap, unsigned int device)
{
struct pi_adapter *pi = ap->host->private_data;
u8 tmp;
+ printk("%s, locked=%d\n", __FUNCTION__, spin_is_locked(ap->lock));
if (device == 0)
tmp = ATA_DEVICE_OBS;
else
tmp = ATA_DEVICE_OBS | ATA_DEV1;
- pi_connect(pi);
+ pi_connect(ap);
pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tmp);
mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
ata_sff_pause(ap);
@@ -67,10 +77,10 @@ static bool pata_parport_devchk(struct ata_port *ap, unsigned int device)
{
struct pi_adapter *pi = ap->host->private_data;
u8 nsect, lbal;
-
+ printk("%s, locked=%d\n", __FUNCTION__, spin_is_locked(ap->lock));
pata_parport_dev_select(ap, device);
- pi_connect(pi);
+ pi_connect(ap);
pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0x55);
pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
@@ -94,8 +104,8 @@ static int pata_parport_bus_softreset(struct ata_port *ap, unsigned int devmask,
unsigned long deadline)
{
struct pi_adapter *pi = ap->host->private_data;
-
- pi_connect(pi);
+ printk("%s, locked=%d\n", __FUNCTION__, spin_is_locked(ap->lock));
+ pi_connect(ap);
/* software reset. causes dev0 to be selected */
pi->proto->write_regr(pi, 1, 6, ap->ctl);
udelay(20);
@@ -116,7 +126,7 @@ static int pata_parport_softreset(struct ata_link *link, unsigned int *classes,
unsigned int devmask = 0;
int rc;
u8 err;
-
+ printk("%s, locked=%d\n", __FUNCTION__, spin_is_locked(ap->lock));
/* determine if device 0/1 are present */
if (pata_parport_devchk(ap, 0))
devmask |= (1 << 0);
@@ -147,8 +157,8 @@ static u8 pata_parport_check_status(struct ata_port *ap)
{
u8 status;
struct pi_adapter *pi = ap->host->private_data;
-
- pi_connect(pi);
+ printk("%s, locked=%d\n", __FUNCTION__, spin_is_locked(ap->lock));
+ pi_connect(ap);
status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
@@ -159,8 +169,8 @@ static u8 pata_parport_check_altstatus(struct ata_port *ap)
{
u8 altstatus;
struct pi_adapter *pi = ap->host->private_data;
-
- pi_connect(pi);
+ printk("%s, locked=%d\n", __FUNCTION__, spin_is_locked(ap->lock));
+ pi_connect(ap);
altstatus = pi->proto->read_regr(pi, 1, 6);
mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
@@ -171,8 +181,8 @@ static void pata_parport_tf_load(struct ata_port *ap,
const struct ata_taskfile *tf)
{
struct pi_adapter *pi = ap->host->private_data;
-
- pi_connect(pi);
+ printk("%s, locked=%d\n", __FUNCTION__, spin_is_locked(ap->lock));
+ pi_connect(ap);
if (tf->ctl != ap->last_ctl) {
pi->proto->write_regr(pi, 1, 6, tf->ctl);
ap->last_ctl = tf->ctl;
@@ -209,8 +219,8 @@ static void pata_parport_tf_load(struct ata_port *ap,
static void pata_parport_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct pi_adapter *pi = ap->host->private_data;
-
- pi_connect(pi);
+ printk("%s, locked=%d\n", __FUNCTION__, spin_is_locked(ap->lock));
+ pi_connect(ap);
tf->status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
tf->error = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
tf->nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
@@ -236,8 +246,8 @@ static void pata_parport_exec_command(struct ata_port *ap,
const struct ata_taskfile *tf)
{
struct pi_adapter *pi = ap->host->private_data;
-
- pi_connect(pi);
+ printk("%s, locked=%d\n", __FUNCTION__, spin_is_locked(ap->lock));
+ pi_connect(ap);
pi->proto->write_regr(pi, 0, ATA_REG_CMD, tf->command);
ata_sff_pause(ap);
mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
@@ -248,8 +258,8 @@ static unsigned int pata_parport_data_xfer(struct ata_queued_cmd *qc,
{
struct ata_port *ap = qc->dev->link->ap;
struct pi_adapter *pi = ap->host->private_data;
-
- pi_connect(pi);
+ printk("%s, locked=%d\n", __FUNCTION__, spin_is_locked(ap->lock));
+ pi_connect(ap);
if (rw == READ)
pi->proto->read_block(pi, buf, buflen);
else
@@ -271,11 +281,12 @@ static void pata_parport_drain_fifo(struct ata_queued_cmd *qc)
return;
ap = qc->ap;
+ printk("%s, locked=%d\n", __FUNCTION__, spin_is_locked(ap->lock));
pi = ap->host->private_data;
/* Drain up to 64K of data before we give up this recovery method */
for (count = 0; (pata_parport_check_status(ap) & ATA_DRQ)
&& count < 65536; count += 2) {
- pi_connect(pi);
+ pi_connect(ap);
pi->proto->read_block(pi, junk, 2);
mod_timer(&pi->timer, jiffies + DISCONNECT_TIMEOUT);
}
@@ -284,33 +295,6 @@ static void pata_parport_drain_fifo(struct ata_queued_cmd *qc)
ata_port_dbg(ap, "drained %d bytes to clear DRQ\n", count);
}
-static void pata_parport_lost_interrupt(struct ata_port *ap)
-{
- u8 status;
- struct ata_queued_cmd *qc;
-
- /* Only one outstanding command per SFF channel */
- qc = ata_qc_from_tag(ap, ap->link.active_tag);
- /* We cannot lose an interrupt on a non-existent or polled command */
- if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
- return;
- /*
- * See if the controller thinks it is still busy - if so the command
- * isn't a lost IRQ but is still in progress
- */
- status = pata_parport_check_altstatus(ap);
- if (status & ATA_BUSY)
- return;
-
- /*
- * There was a command running, we are no longer busy and we have
- * no interrupt.
- */
- ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
- /* Run the host interrupt logic as if the interrupt had not been lost */
- ata_sff_port_intr(ap, qc);
-}
-
static struct ata_port_operations pata_parport_port_ops = {
.inherits = &ata_sff_port_ops,
@@ -325,8 +309,6 @@ static struct ata_port_operations pata_parport_port_ops = {
.sff_exec_command = pata_parport_exec_command,
.sff_data_xfer = pata_parport_data_xfer,
.sff_drain_fifo = pata_parport_drain_fifo,
-
- .lost_interrupt = pata_parport_lost_interrupt,
};
static const struct ata_port_info pata_parport_port_info = {
@@ -473,6 +455,19 @@ static struct scsi_host_template pata_parport_sht = {
PATA_PARPORT_SHT("pata_parport")
};
+struct pi_device_match {
+ struct parport *parport;
+ struct pi_protocol *proto;
+};
+
+static int pi_find_dev(struct device *dev, void *data)
+{
+ struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
+ struct pi_device_match *match = data;
+
+ return pi->pardev->port == match->parport && pi->proto == match->proto;
+}
+
static struct pi_adapter *pi_init_one(struct parport *parport,
struct pi_protocol *pr, int mode, int unit, int delay)
{
@@ -481,6 +476,14 @@ static struct pi_adapter *pi_init_one(struct parport *parport,
const struct ata_port_info *ppi[] = { &pata_parport_port_info };
struct ata_host *host;
struct pi_adapter *pi;
+ struct pi_device_match match = { .parport = parport, .proto = pr };
+
+ /*
+ * Abort if there's a device already registered on the same parport
+ * using the same protocol.
+ */
+ if (bus_for_each_dev(&pata_parport_bus_type, NULL, &match, pi_find_dev))
+ return NULL;
pi = kzalloc(sizeof(struct pi_adapter), GFP_KERNEL);
if (!pi)
@@ -674,10 +677,7 @@ static void pi_remove_one(struct device *dev)
ata_host_detach(host);
del_timer_sync(&pi->timer);
- if (pi->claimed) {
- pi->proto->disconnect(pi);
- parport_release(pi->pardev);
- }
+ pi_disconnect(pi);
pi_release(pi);
device_unregister(dev);
ida_free(&pata_parport_bus_dev_ids, dev->id);
--
2.35.3
next prev parent reply other threads:[~2022-11-15 8:05 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-12 14:44 Ondrej Zary
2022-03-13 19:15 ` Ondrej Zary
2022-03-13 23:19 ` Jens Axboe
2022-03-14 20:25 ` Ondrej Zary
2022-03-14 20:29 ` Jens Axboe
2022-03-15 4:22 ` Damien Le Moal
2022-03-15 18:44 ` Ondrej Zary
2022-03-15 18:47 ` Jens Axboe
2022-03-15 21:17 ` Ondrej Zary
2022-03-16 0:19 ` Damien Le Moal
2022-03-15 8:24 ` Christoph Hellwig
2022-03-13 20:38 ` Sergey Shtylyov
2022-03-13 21:19 ` Ondrej Zary
2022-03-16 8:50 ` Sergey Shtylyov
2022-03-16 11:28 ` Ondrej Zary
2022-03-16 11:44 ` Damien Le Moal
2022-03-16 12:58 ` Ondrej Zary
2022-10-19 7:34 ` Christoph Hellwig
2022-10-19 18:58 ` Ondrej Zary
2022-11-12 11:17 ` Ondrej Zary
2022-11-13 23:23 ` Damien Le Moal
2022-11-14 7:53 ` Ondrej Zary
2022-11-14 8:03 ` Damien Le Moal
2022-11-14 19:25 ` Ondrej Zary
2022-11-15 3:06 ` Damien Le Moal
2022-11-15 8:04 ` Hannes Reinecke [this message]
2022-11-15 14:56 ` Ondrej Zary
2022-11-16 1:30 ` Damien Le Moal
2022-12-12 22:55 ` Ondrej Zary
2022-12-12 23:07 ` Damien Le Moal
2022-12-13 6:22 ` Christoph Hellwig
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=61b91b3c-bd4d-05a4-bb66-f4fd344fa45a@suse.de \
--to=hare@suse.de \
--cc=axboe@kernel.dk \
--cc=damien.lemoal@opensource.wdc.com \
--cc=hch@lst.de \
--cc=linux-block@vger.kernel.org \
--cc=linux-ide@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-parport@lists.infradead.org \
--cc=linux@zary.sk \
--cc=s.shtylyov@omp.ru \
--cc=tim@cyberelk.net \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®