mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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


  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®