lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 18 Apr 2007 12:11:38 -0400 (EDT)
From:	Alan Stern <stern@...land.harvard.edu>
To:	Tejun Heo <htejun@...il.com>
cc:	Cornelia Huck <cornelia.huck@...ibm.com>,
	linux-kernel <linux-kernel@...r.kernel.org>,
	Greg K-H <greg@...ah.com>,
	Rusty Russell <rusty@...tcorp.com.au>,
	Dmitry Torokhov <dmitry.torokhov@...il.com>
Subject: Re: [PATCH RFD] alternative kobject release wait mechanism

On Thu, 19 Apr 2007, Tejun Heo wrote:

> The goal of immediate-disconnect is to remove such lingering reference
> counts so that device_unregister() or driver detach puts the last
> reference count.

Yes, I understand.  If you had immediate-disconnect then you wouldn't need 
device_unregister_wait().  In fact, you wouldn't need any reference counts 
at all.  It would be guaranteed that when the unregister call returned, 
all references would be gone.

> You tell a higher layer that a device is going away, on return from the
> function, that layer isn't gonna access the device anymore.

No, no.  You tell somebody (it might be a higher layer, it might be a 
lower layer, or it might be a same-height layer -- doesn't matter) that a 
device is going away.  On return from the function, that layer isn't going 
to access the device any more, _nor_ will anyone else who has obtained a 
reference from that layer.  This last clause is very important.

> I don't think this is gonna be too difficult to do.  I think I can
> convert block layer and IDE/SCSI drivers without too much problem.
> Dunno much about other layers tho.

You have to convert more than layers (or core subsystems).  You also have 
to audit and convert drivers.  It will be tremendously difficult to do.

> Dunno if I understood the problem right but can't we do the following?
> 
> remove()
> {
> 	acquire sem;
> 	device_del();
> 	release sem;
> 	device_put_wait();
> }

You did misunderstand.  Here's what I was talking about:

Driver A:
---------
	unregister_device(dev);

		/* inside the driver core */
		down(&dev->sem);
		if (dev->driver)
			dev->driver->remove(dev);
		up(&dev->sem);
		device_put(dev);	/* or device_put_wait */


Driver B:
---------
void remove(struct device *dev)
{
	struct my_device *mydev = dev_get_drvdata(dev);

	mydev->gone = 1;
	kref_put(&mydev->kref, my_device_release);
}


Driver B's kernel thread:
-------------------------
	kref_get(&mydev->kref);
	down(&mydev->dev.sem);
	if (mydev->gone)
		goto finished;
	...
 finished:
	up(&mydev->dev.sem);
	kref_put(&mydev->kref, my_device_release);

Consider what happens if the kernel thread blocks on its down() while the
remove() method is running.  It will be impossible for Driver B to
eliminate the reference to dev held by mydev and by the down() routine.

In short, Driver B _can't_ provide an immediate detach.  Not unless 
someone figures out a way to cancel a blocked down().  And do the same 
thing for other blocking primitives.

Alan Stern

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ