All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adrian McMenamin <adrian@newgolddream.dyndns.info>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: dwmw2@infradead.org, greg@kroah.com, lethal@linux-sh.org,
	linux-kernel@vger.kernel.org, linux-sh@vger.kernel.org,
	linux-mtd@vger.kernel.org
Subject: Re: [PATCH] 1/2 Maple: Update bus driver to allow support of VMU
Date: Thu, 20 Mar 2008 22:23:17 +0000	[thread overview]
Message-ID: <1206051797.6274.17.camel@localhost.localdomain> (raw)
In-Reply-To: <20080320135618.1a283b3e.akpm@linux-foundation.org>


On Thu, 2008-03-20 at 13:56 -0700, Andrew Morton wrote:

> urgh, down_trylock().  And a secret, undocumented one too.
> 
> A trylock is always an exceptional thing.  How is *any* reader of this code
> supposed to work out what the heck it's doing there?  Convert it into
> down(), run the code and decrypt the lockdep warnings, I suspect.
> 
> <looks>
> 
> Nope, I can't see any other lock being held when we call this function.
> 
> The trylocks are an utter mystery to me.  Please don't write mysterious
> code.
> 

OK, I am sure this is my problem but I have no idea why you are
describing down_trylock as undocumented - I simply took it out of page
111 of the "Linux Device Drivers" book - hardly the canonical source but
why are you telling me that it is undocumented?

The down_trylock is used here so that a passed in packet and the regular
every second check that the device has not been hot-unplugged don't
deadlock. If I used down then a deadlock is a near certainty. It simply
bounces the 1 second test here if the lock is already down. Is that a
big problem?



> > @@ -398,32 +403,38 @@ static int setup_maple_commands(struct device *device, void *ignored)
> >  /* VBLANK bottom half - implemented via workqueue */
> >  static void maple_vblank_handler(struct work_struct *work)
> >  {
> > -	if (!maple_dma_done())
> > -		return;
> >  	if (!list_empty(&maple_sentq))
> >  		return;
> > +	if (!maple_dma_done())
> > +		return;
> >  	ctrl_outl(0, MAPLE_ENABLE);
> > -	liststatus = 0;
> >  	bus_for_each_dev(&maple_bus_type, NULL, NULL,
> >  			 setup_maple_commands);
> >  	if (time_after(jiffies, maple_pnp_time))
> >  		maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL;
> > -	if (liststatus && list_empty(&maple_sentq)) {
> > +	mutex_lock(&maple_wlist_lock);
> > +	if (!list_empty(&maple_waitq) && list_empty(&maple_sentq)) {
> > +		mutex_unlock(&maple_wlist_lock);
> > +		mutex_lock(&maple_list_lock);
> >  		INIT_LIST_HEAD(&maple_sentq);
> > +		mutex_unlock(&maple_list_lock);
> >  		maple_send();
> > +	} else {
> > +		mutex_unlock(&maple_wlist_lock);
> >  	}
> > +
> >  	maplebus_dma_reset();
> >  }
> 
> This locking looks like a mess.  I'd suggest that maple_list_lock and
> maple_wlist_lock now need documentation.  Describe what data they protect
> and what their ranking rules are.


Well, they don't seem a mess to me, but I can document them, though I
thought thety were pretty self-documenting :( One locks the waiting
queue of packets, one the queue of output packets.

> 
> >  /* handle devices added via hotplugs - placing them on queue for DEVINFO*/
> >  static void maple_map_subunits(struct maple_device *mdev, int submask)
> >  {
> > -	int retval, k, devcheck;
> > +	int retval, k, devcheck, locking;
> >  	struct maple_device *mdev_add;
> >  	struct maple_device_specify ds;
> >  
> > +	ds.port = mdev->port;
> >  	for (k = 0; k < 5; k++) {
> > -		ds.port = mdev->port;
> >  		ds.unit = k + 1;
> >  		retval > >  		    bus_for_each_dev(&maple_bus_type, NULL, &ds,
> > @@ -437,9 +448,15 @@ static void maple_map_subunits(struct maple_device *mdev, int submask)
> >  			mdev_add = maple_alloc_dev(mdev->port, k + 1);
> >  			if (!mdev_add)
> >  				return;
> > +			locking = down_trylock(&mdev_add->mq->sem);
> > +			if (locking) {
> > +				up(&mdev_add->mq->sem);
> > +				down_interruptible(&mdev_add->mq->sem);
> > +			}
> 
> What the heck is that trying to do?!?!?!


Again, it is trying to avoid a deadlock between injected packets and
scans for hotplug events.

> 
> And it's buggy.  The return value of down_interruptible() is ignored, so
> the driver has lost track of whether or not the semphore was taken.



You are right about that and it should be fixed
> 



WARNING: multiple messages have this Message-ID (diff)
From: Adrian McMenamin <adrian@newgolddream.dyndns.info>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: dwmw2@infradead.org, greg@kroah.com, lethal@linux-sh.org,
	linux-kernel@vger.kernel.org, linux-sh@vger.kernel.org,
	linux-mtd@vger.kernel.org
Subject: Re: [PATCH] 1/2 Maple: Update bus driver to allow support of VMU device
Date: Thu, 20 Mar 2008 22:23:17 +0000	[thread overview]
Message-ID: <1206051797.6274.17.camel@localhost.localdomain> (raw)
In-Reply-To: <20080320135618.1a283b3e.akpm@linux-foundation.org>


On Thu, 2008-03-20 at 13:56 -0700, Andrew Morton wrote:

> urgh, down_trylock().  And a secret, undocumented one too.
> 
> A trylock is always an exceptional thing.  How is *any* reader of this code
> supposed to work out what the heck it's doing there?  Convert it into
> down(), run the code and decrypt the lockdep warnings, I suspect.
> 
> <looks>
> 
> Nope, I can't see any other lock being held when we call this function.
> 
> The trylocks are an utter mystery to me.  Please don't write mysterious
> code.
> 

OK, I am sure this is my problem but I have no idea why you are
describing down_trylock as undocumented - I simply took it out of page
111 of the "Linux Device Drivers" book - hardly the canonical source but
why are you telling me that it is undocumented?

The down_trylock is used here so that a passed in packet and the regular
every second check that the device has not been hot-unplugged don't
deadlock. If I used down then a deadlock is a near certainty. It simply
bounces the 1 second test here if the lock is already down. Is that a
big problem?



> > @@ -398,32 +403,38 @@ static int setup_maple_commands(struct device *device, void *ignored)
> >  /* VBLANK bottom half - implemented via workqueue */
> >  static void maple_vblank_handler(struct work_struct *work)
> >  {
> > -	if (!maple_dma_done())
> > -		return;
> >  	if (!list_empty(&maple_sentq))
> >  		return;
> > +	if (!maple_dma_done())
> > +		return;
> >  	ctrl_outl(0, MAPLE_ENABLE);
> > -	liststatus = 0;
> >  	bus_for_each_dev(&maple_bus_type, NULL, NULL,
> >  			 setup_maple_commands);
> >  	if (time_after(jiffies, maple_pnp_time))
> >  		maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL;
> > -	if (liststatus && list_empty(&maple_sentq)) {
> > +	mutex_lock(&maple_wlist_lock);
> > +	if (!list_empty(&maple_waitq) && list_empty(&maple_sentq)) {
> > +		mutex_unlock(&maple_wlist_lock);
> > +		mutex_lock(&maple_list_lock);
> >  		INIT_LIST_HEAD(&maple_sentq);
> > +		mutex_unlock(&maple_list_lock);
> >  		maple_send();
> > +	} else {
> > +		mutex_unlock(&maple_wlist_lock);
> >  	}
> > +
> >  	maplebus_dma_reset();
> >  }
> 
> This locking looks like a mess.  I'd suggest that maple_list_lock and
> maple_wlist_lock now need documentation.  Describe what data they protect
> and what their ranking rules are.


Well, they don't seem a mess to me, but I can document them, though I
thought thety were pretty self-documenting :( One locks the waiting
queue of packets, one the queue of output packets.

> 
> >  /* handle devices added via hotplugs - placing them on queue for DEVINFO*/
> >  static void maple_map_subunits(struct maple_device *mdev, int submask)
> >  {
> > -	int retval, k, devcheck;
> > +	int retval, k, devcheck, locking;
> >  	struct maple_device *mdev_add;
> >  	struct maple_device_specify ds;
> >  
> > +	ds.port = mdev->port;
> >  	for (k = 0; k < 5; k++) {
> > -		ds.port = mdev->port;
> >  		ds.unit = k + 1;
> >  		retval =
> >  		    bus_for_each_dev(&maple_bus_type, NULL, &ds,
> > @@ -437,9 +448,15 @@ static void maple_map_subunits(struct maple_device *mdev, int submask)
> >  			mdev_add = maple_alloc_dev(mdev->port, k + 1);
> >  			if (!mdev_add)
> >  				return;
> > +			locking = down_trylock(&mdev_add->mq->sem);
> > +			if (locking) {
> > +				up(&mdev_add->mq->sem);
> > +				down_interruptible(&mdev_add->mq->sem);
> > +			}
> 
> What the heck is that trying to do?!?!?!


Again, it is trying to avoid a deadlock between injected packets and
scans for hotplug events.

> 
> And it's buggy.  The return value of down_interruptible() is ignored, so
> the driver has lost track of whether or not the semphore was taken.



You are right about that and it should be fixed
> 



  reply	other threads:[~2008-03-20 22:23 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-18 22:30 [PATCH] 0/2 Add support for maple "Visual Memory Unit" on SEGA Adrian McMenamin
2008-03-18 22:30 ` [PATCH] 0/2 Add support for maple "Visual Memory Unit" on SEGA Dreamcast Adrian McMenamin
2008-03-18 22:49 ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU device Adrian McMenamin
2008-03-18 22:49   ` Adrian McMenamin
2008-03-18 22:56   ` [PATCH] 2/2 mtd: Add support for the Dreamcast VMU flash Adrian McMenamin
2008-03-18 22:56     ` Adrian McMenamin
2008-03-20 21:10     ` Andrew Morton
2008-03-20 21:10       ` Andrew Morton
2008-03-20 22:34       ` Adrian McMenamin
2008-03-20 22:34         ` Adrian McMenamin
2008-03-20 20:56   ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU Andrew Morton
2008-03-20 20:56     ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU device Andrew Morton
2008-03-20 22:23     ` Adrian McMenamin [this message]
2008-03-20 22:23       ` Adrian McMenamin
2008-03-20 22:39       ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU Andrew Morton
2008-03-20 22:39         ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU device Andrew Morton
2008-03-20 22:52         ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU Adrian McMenamin
2008-03-20 22:52           ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU device Adrian McMenamin
2008-03-21  5:11           ` Paul Mundt
2008-03-21  5:11             ` Paul Mundt

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=1206051797.6274.17.camel@localhost.localdomain \
    --to=adrian@newgolddream.dyndns.info \
    --cc=akpm@linux-foundation.org \
    --cc=dwmw2@infradead.org \
    --cc=greg@kroah.com \
    --cc=lethal@linux-sh.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@vger.kernel.org \
    --cc=linux-sh@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.