virtio: make PCI devices take a virtio_pci module ref
Subsystems (9)
PATCH 1/1 virtio: make PCI devices take a virtio_pci module ref
Nothing takes a ref on virtio_pci, so even if you have devices in use, rmmod will attempt to unload the module.
Fix by simply making each device take a ref on the module.
--- drivers/virtio/virtio_pci.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
drivers/virtio/virtio_pci.c +4 -0
@@ -322,6 +322,9 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,return -ENODEV ; } +if (!try_module_get (THIS_MODULE )) +return -ENODEV ; +/* allocate our structure and fill it out */ vp_dev =kzalloc (sizeof (struct virtio_pci_device ),GFP_KERNEL );if (vp_dev ==NULL )
@@ -393,6 +396,7 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev)pci_release_regions (pci_dev);pci_disable_device (pci_dev);kfree (vp_dev); +module_put (THIS_MODULE ); }#ifdef CONFIG_PM
Signature · 1 line
1.6.0.3
Quoted 2 lines · Mark McLoughlin
Nothing takes a ref on
virtio_pci, so even if you have devices in use, rmmod will attempt to unload the module.
It unbinds the device properly as any other driver. So what's the problem here?
Quoted 7 lines
Fix by simply making each device take a ref on the module.
Signed-off-by Mark McLoughlin <[email protected]>Reported-by Michael Tokarev <[email protected]>--- drivers/virtio/virtio_pci.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
Quoted 4 lines · On Thursday 04 December 2008 23:14:31 Mark McLoughlin wrote:
Nothing takes a ref on
virtio_pci, so even if you have devices in use, rmmod will attempt to unload the module.Fix by simply making each device take a ref on the module.
Hi Mark,
Taking a reference to oneself is almost always wrong. I'm a little
surprised that a successful call to pci_device->probe doesn't bump the module count though.
Jesse?
Thanks,
Rusty.
Quoted 5 lines · Jiri Slaby
Quoted 2 lines · Mark McLoughlin
Nothing takes a ref on
virtio_pci, so even if you have devices in use, rmmod will attempt to unload the module.It unbinds the device properly as any other driver. So what's the problem here?
Here's what we get when rmmod'ing (a zero-refcounted but in use) virtio_pci (I did it by a chance, cut-n-pasted the wrong line):
WARNING: at drivers/base/core.c:122 device_release+0x5f/0x70() Device 'virtio1' does not have a release() function, it is broken and must be fixed. Modules linked in: ext3 jbd mbcache acpiphp dock pci_hotplug virtio_net virtio_blk virtio_pci(-) virtio_ring virtio
Pid: 361, comm: rmmod Tainted: G S 2.6.27-i686smp #2.6.27.7
[<c012b81f>] warn_slowpath+0x6f/0xa0 [<c0110030>] prepare_set+0x30/0x80 [<c012067e>] __wake_up+0x3e/0x60 [<c01d1d25>] release_sysfs_dirent+0x45/0xb0 ...
Quoted 1 line
Quoted 1 line
Reported-by Michael Tokarev <[email protected]>
It was in my original report to kvm@vger.
Thanks!
/mjt
Michael Tokarev napsal(a):
Quoted 14 lines
Quoted 4 lines · Jiri Slaby
Quoted 2 lines · Mark McLoughlin
Nothing takes a ref on
virtio_pci, so even if you have devices in use, rmmod will attempt to unload the module.It unbinds the device properly as any other driver. So what's the problem here?
Here's what we get when rmmod'ing (a zero-refcounted but in use)
virtio_pci(I did it by a chance, cut-n-pasted the wrong line):WARNING: at drivers/base/core.c:122 device_release+0x5f/0x70() Device 'virtio1' does not have a release() function, it is broken and must be fixed. Modules linked in: ext3 jbd mbcache acpiphp dock pci_hotplug virtio_net virtio_blk virtio_pci(-) virtio_ring virtio
Quoted 6 lines
Pid: 361, comm: rmmod Tainted: G S 2.6.27-i686smp #2.6.27.7
[<c012b81f>] warn_slowpath+0x6f/0xa0 [<c0110030>] prepare_set+0x30/0x80 [<c012067e>] __wake_up+0x3e/0x60 [<c01d1d25>] release_sysfs_dirent+0x45/0xb0 ...
So why don't you fix the root cause and add such a crap into the probe function (not even counting probe can fail later)?
Fix the virtio bus instead.
Quoted 22 lines · Jiri Slaby
Michael Tokarev napsal(a):
Quoted 14 lines
Quoted 4 lines · Jiri Slaby
Quoted 2 lines · Mark McLoughlin
Nothing takes a ref on
virtio_pci, so even if you have devices in use, rmmod will attempt to unload the module.It unbinds the device properly as any other driver. So what's the problem here?
Here's what we get when rmmod'ing (a zero-refcounted but in use)
virtio_pci(I did it by a chance, cut-n-pasted the wrong line):WARNING: at drivers/base/core.c:122 device_release+0x5f/0x70() Device 'virtio1' does not have a release() function, it is broken and must be fixed. Modules linked in: ext3 jbd mbcache acpiphp dock pci_hotplug virtio_net virtio_blk virtio_pci(-) virtio_ring virtioQuoted 6 lines
Pid: 361, comm: rmmod Tainted: G S 2.6.27-i686smp #2.6.27.7
[<c012b81f>] warn_slowpath+0x6f/0xa0 [<c0110030>] prepare_set+0x30/0x80 [<c012067e>] __wake_up+0x3e/0x60 [<c01d1d25>] release_sysfs_dirent+0x45/0xb0 ...
Quoted 4 lines
So why don't you fix the root cause and add such a crap into the probe function (not even counting probe can fail later)?
Fix the virtio bus instead.
Yeah, the patch I posted wasn't meant as a fix for this traceback. Here's one that does fix it.
Cheers,
Mark.
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] virtio: add device release() function
Add a release() function for virtio_pci devices so as to avoid:
Device 'virtio0' does not have a release() function, it is broken and must be fixed
The struct device is embedded in the struct virtio_pci_device which is freed by virtio_pci_remove(), so virtio_pci_release_dev() need not actually do anything.
--- drivers/virtio/virtio_pci.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)
drivers/virtio/virtio_pci.c +6 -0
@@ -70,12 +70,17 @@ static struct pci_device_id virtio_pci_id_table[] = {MODULE_DEVICE_TABLE (pci, virtio_pci_id_table); +static void virtio_pci_release_dev (struct device *dev) +{ +} +/* A PCI device has it's own struct device and so does a virtio device so * we create a place for the virtio devices to show up in sysfs. I think it * would make more sense for virtio to not insist on having it's own device. */ static struct device virtio_pci_root = { .parent =NULL , .bus_id ="virtio-pci" , + .release = virtio_pci_release_dev, };/* Convert a generic virtio device to our structure */
@@ -328,6 +333,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,return -ENOMEM ; vp_dev->vdev.dev.parent = &virtio_pci_root; + vp_dev->vdev.dev.release = virtio_pci_release_dev; vp_dev->vdev.config = &virtio_pci_config_ops; vp_dev->pci_dev = pci_dev;INIT_LIST_HEAD (&vp_dev->virtqueues);
Signature · 1 line
1.6.0.3
Hi Rusty,
Quoted 9 lines · Rusty Russell
Quoted 4 lines · On Thursday 04 December 2008 23:14:31 Mark McLoughlin wrote:
Nothing takes a ref on
virtio_pci, so even if you have devices in use, rmmod will attempt to unload the module.Fix by simply making each device take a ref on the module.
Hi Mark,
Taking a reference to oneself is almost always wrong.
Yeah, it certainly seems fairly unorthodox, alright. But then again, virtio_pci is an odd creature anyway :-)
My thinking was that the virtio abstraction is preventing there being an explicit dependency between e.g. virtio_net and virtio_pci. If we didn't have the abstraction, virtio_net would be calling directly into virtio_pci and we'd have an explicit dep. So, I was just trying to artificially mimic that.
Another example of a lack of an explicit dependency causing problems is Fedora's mkinitrd having this hack:
if echo $PWD | grep -q /virtio-pci/ ; then
findmodule virtio_pci
fi
which basically says "if this is a virtio device, don't forget to include virtio_pci in the initrd too!". Now, mkinitrd is full of hacks, but this is a particularly unusual one.
Í'm thinking that maybe we should default to having virtio_pci built-in if e.g. CONFIG_KVM_GUEST is set.
Quoted 2 lines
I'm a little surprised that a successful call to
pci_device->probedoesn't bump the module count though.
Nah, removing a module for device should actually work fine.
Anyway, with the root cause of Michael's traceback fixed, rmmod-ing virtio_pci and re-loading it works just fine, so ...
Cheers,
Mark.
Quoted 3 lines · Mark McLoughlin
Quoted 1 line
Fix the virtio bus instead.
Yeah, the patch I posted wasn't meant as a fix for this traceback.
So what's the module_get patch needed for?
Quoted 1 line
Here's one that does fix it.
...
Quoted 21 lines
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] virtio: add devicerelease()functionAdd a
release()function forvirtio_pcidevices so as to avoid:Device 'virtio0' does not have a
release()function, it is broken and must be fixedThe struct device is embedded in the struct
virtio_pci_devicewhich is freed byvirtio_pci_remove(), sovirtio_pci_release_dev()need not actually do anything.Signed-off-by Mark McLoughlin <[email protected]>--- drivers/virtio/virtio_pci.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)drivers/virtio/virtio_pci.c +0
-0
drivers/virtio/virtio_pci.c static struct pci_device_id virtio_pci_id_table[] = { · line 75
Quoted 6 lines
drivers/virtio/virtio_pci.c +3
-0@@ -70,12 +70,17 @@ static struct pci_device_id virtio_pci_id_table[] = {MODULE_DEVICE_TABLE (pci, virtio_pci_id_table); +static void virtio_pci_release_dev (struct device *dev) +{ +}
You have to have a strong reason to have empty release. This is not the case, you should do the free here, not in remove, I suppose.
drivers/virtio/virtio_pci.c static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, · line 336
Quoted 5 lines
drivers/virtio/virtio_pci.c +1
-0@@ -328,6 +333,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,return -ENOMEM ; vp_dev->vdev.dev.parent = &virtio_pci_root; + vp_dev->vdev.dev.release = virtio_pci_release_dev;
This should rather be in register_virtio_device
Quoted 15 lines · Jiri Slaby
Quoted 3 lines · Mark McLoughlin
Quoted 1 line
Fix the virtio bus instead.
Yeah, the patch I posted wasn't meant as a fix for this traceback.
So what's the
module_getpatch needed for?Quoted 1 line
Here's one that does fix it.
...
Quoted 6 lines
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] virtio: add devicerelease()functionAdd a
release()function forvirtio_pcidevices so as to avoid:Device 'virtio0' does not have a
release()function, it is broken and must be fixed
Just providing an empty release function to the kernel is the complete wrong thing. Do you not think the kernel is actually trying to tell you something here? If it could test for an empty release function it would complain about that as well, providing one is no "fix" at all.
You need to free your memory in the release function that is owned by the device/structure. Please read the file, Documentation/kobject.txt for details as to what you need to do.
thanks,
greg k-h
Quoted 5 lines · Mark McLoughlin
On Fri, 2008-12-05 at 14:17 +0100, Jiri Slaby wrote:
drivers/virtio/virtio_pci.c +2
-0+static void virtio_pci_release_dev (struct device *dev) +{
drivers/virtio/virtio_pci.c static struct pci_device_id virtio_pci_id_table[] = { · line 84
Quoted 10 lines
drivers/virtio/virtio_pci.c +3
-0+} +/* A PCI device has it's own struct device and so does a virtio device so * we create a place for the virtio devices to show up in sysfs. I think it * would make more sense for virtio to not insist on having it's own device. */ static struct device virtio_pci_root = { .parent =NULL , .bus_id ="virtio-pci" , + .release = virtio_pci_release_dev, };
Actually, we should be able to delete this virtio_pci_root entirely. The device is a dummy one anyway.
Regards,
Anthony Liguori
Quoted 10 lines
/* Convert a generic virtio device to our structure */
drivers/virtio/virtio_pci.c +1
-0@@ -328,6 +333,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,return -ENOMEM ; vp_dev->vdev.dev.parent = &virtio_pci_root; + vp_dev->vdev.dev.release = virtio_pci_release_dev; vp_dev->vdev.config = &virtio_pci_config_ops; vp_dev->pci_dev = pci_dev;INIT_LIST_HEAD (&vp_dev->virtqueues);
Anthony Liguori napsal(a):
Quoted 2 lines
Actually, we should be able to delete this
virtio_pci_rootentirely. The device is a dummy one anyway.
But the bus is still to be fixed...
Quoted 17 lines · Greg KH
Quoted 15 lines · Jiri Slaby
Quoted 3 lines · Mark McLoughlin
Quoted 1 line
Fix the virtio bus instead.
Yeah, the patch I posted wasn't meant as a fix for this traceback.
So what's the
module_getpatch needed for?Quoted 1 line
Here's one that does fix it.
...
Quoted 6 lines
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] virtio: add devicerelease()functionAdd a
release()function forvirtio_pcidevices so as to avoid:Device 'virtio0' does not have a
release()function, it is broken and must be fixed
Quoted 8 lines
Just providing an empty release function to the kernel is the complete wrong thing. Do you not think the kernel is actually trying to tell you something here? If it could test for an empty release function it would complain about that as well, providing one is no "fix" at all.
You need to free your memory in the release function that is owned by the device/structure. Please read the file,
Documentation/kobject.txtfor details as to what you need to do.
Okay, consider me "mocked mercilessly by the kobject maintainer" :-)
Does this version look a bit more reasonable?
(The virtio_pci_root is statically allocated so I don't see how release() could be non-empty in this case, but let's debate whether we want to keep this dummy device at all)
Cheers,
Mark.
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] virtio: add PCI device release() function
Add a release() function for virtio_pci devices so as to avoid:
Device 'virtio0' does not have a release() function, it is broken and must be fixed
Move the code to free the resources associated with the device from virtio_pci_remove() into this new function. virtio_pci_remove() now merely unregisters the device which should cause the final ref to be dropped and virtio_pci_release_dev() to be called.
--- drivers/virtio/virtio_pci.c | 21 +++++++++++++++------ 1 files changed, 15 insertions(+), 6 deletions(-)
drivers/virtio/virtio_pci.c +15 -6
@@ -305,6 +305,20 @@ static struct virtio_config_ops virtio_pci_config_ops = { .finalize_features = vp_finalize_features, }; +static void virtio_pci_release_dev (struct device *_d) +{ + struct virtio_device *dev = container_of(_d, struct virtio_device, dev); +struct virtio_pci_device *vp_dev =to_vp_device (dev); +struct pci_dev *pci_dev = vp_dev->pci_dev; + +free_irq (pci_dev->irq, vp_dev); +pci_set_drvdata (pci_dev,NULL ); +pci_iounmap (pci_dev, vp_dev->ioaddr); +pci_release_regions (pci_dev); +pci_disable_device (pci_dev); +kfree (vp_dev); +} +/* the PCI probing function */ static int __devinit virtio_pci_probe (struct pci_dev *pci_dev,const struct pci_device_id *id)
@@ -328,6 +342,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,return -ENOMEM ; vp_dev->vdev.dev.parent = &virtio_pci_root; + vp_dev->vdev.dev.release = virtio_pci_release_dev; vp_dev->vdev.config = &virtio_pci_config_ops; vp_dev->pci_dev = pci_dev;INIT_LIST_HEAD (&vp_dev->virtqueues);
@@ -387,12 +402,6 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev)struct virtio_pci_device *vp_dev =pci_get_drvdata (pci_dev);unregister_virtio_device (&vp_dev->vdev); -free_irq (pci_dev->irq, vp_dev); -pci_set_drvdata (pci_dev,NULL ); -pci_iounmap (pci_dev, vp_dev->ioaddr); -pci_release_regions (pci_dev); -pci_disable_device (pci_dev); -kfree (vp_dev); }#ifdef CONFIG_PM
Signature · 1 line
1.6.0.3
Quoted 6 lines · Jiri Slaby
Quoted 3 lines · Mark McLoughlin
Quoted 1 line
Fix the virtio bus instead.
Yeah, the patch I posted wasn't meant as a fix for this traceback.
So what's the
module_getpatch needed for?
A misguided attempt to create an artificial dependency between virtio device drivers and the virtio bus implementation?
Quoted 24 lines
Quoted 1 line
Here's one that does fix it.
...
Quoted 22 lines
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] virtio: add devicerelease()functionAdd a
release()function forvirtio_pcidevices so as to avoid:Device 'virtio0' does not have a
release()function, it is broken and must be fixedThe struct device is embedded in the struct
virtio_pci_devicewhich is freed byvirtio_pci_remove(), sovirtio_pci_release_dev()need not actually do anything.Signed-off-by Mark McLoughlin <[email protected]>--- drivers/virtio/virtio_pci.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)drivers/virtio/virtio_pci.c +0
-0@@ -70,12 +70,17 @@ static struct pci_device_id virtio_pci_id_table[] = {
Quoted 8 lines
drivers/virtio/virtio_pci.c static struct pci_device_id virtio_pci_id_table[] = { · line 75
Quoted 5 lines
drivers/virtio/virtio_pci.c +3
-0MODULE_DEVICE_TABLE (pci, virtio_pci_id_table); +static void virtio_pci_release_dev (struct device *dev) +{ +}You have to have a strong reason to have empty release. This is not the case, you should do the free here, not in remove, I suppose.
Okay, see the other patch I just sent.
Quoted 7 lines
drivers/virtio/virtio_pci.c static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, · line 336
Quoted 5 lines
drivers/virtio/virtio_pci.c +1
-0@@ -328,6 +333,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,return -ENOMEM ; vp_dev->vdev.dev.parent = &virtio_pci_root; + vp_dev->vdev.dev.release = virtio_pci_release_dev;This should rather be in
register_virtio_device
Why? Because dev.release should be set by the same place that does device_register() or ...?
The resources being allocated here are virtio-pci specific, so if we wanted to do something like this we'd perhaps need to add a ->release() to struct virtio_device and just call that hook.
Cheers,
Mark.
Quoted 19 lines · Anthony Liguori
Quoted 5 lines · Mark McLoughlin
On Fri, 2008-12-05 at 14:17 +0100, Jiri Slaby wrote:
drivers/virtio/virtio_pci.c +2
-0+static void virtio_pci_release_dev (struct device *dev) +{drivers/virtio/virtio_pci.c static struct pci_device_id virtio_pci_id_table[] = { · line 84
Quoted 10 lines
drivers/virtio/virtio_pci.c +3
-0+} +/* A PCI device has it's own struct device and so does a virtio device so * we create a place for the virtio devices to show up in sysfs. I think it * would make more sense for virtio to not insist on having it's own device. */ static struct device virtio_pci_root = { .parent =NULL , .bus_id ="virtio-pci" , + .release = virtio_pci_release_dev, };Actually, we should be able to delete this
virtio_pci_rootentirely. The device is a dummy one anyway.
Care to recall why it was added initially and what's changed?
One side effect of removing it is that each device appears on its own in /sys/devices rather than neatly under /sys/devices/virtio-pci.
(And one side effect of that is that the aforementioned Fedora mkinitrd kludge stops working which would make me sad :-)
Cheers,
mark.
Quoted 23 lines · Mark McLoughlin
Quoted 22 lines · Greg KH
Quoted 15 lines · Jiri Slaby
Quoted 3 lines · Mark McLoughlin
Quoted 1 line
Fix the virtio bus instead.
Yeah, the patch I posted wasn't meant as a fix for this traceback.
So what's the
module_getpatch needed for?Quoted 1 line
Here's one that does fix it.
...
Quoted 6 lines
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] virtio: add devicerelease()functionAdd a
release()function forvirtio_pcidevices so as to avoid:Device 'virtio0' does not have a
release()function, it is broken and must be fixedJust providing an empty release function to the kernel is the complete wrong thing. Do you not think the kernel is actually trying to tell you something here? If it could test for an empty release function it would complain about that as well, providing one is no "fix" at all.
Quoted 5 lines
Quoted 3 lines
You need to free your memory in the release function that is owned by the device/structure. Please read the file,
Documentation/kobject.txtfor details as to what you need to do.Okay, consider me "mocked mercilessly by the kobject maintainer" :-)
Heh, prepare for some more mocking below...
Quoted 5 lines
Does this version look a bit more reasonable?
(The
virtio_pci_rootis statically allocated so I don't see howrelease()could be non-empty in this case, but let's debate whether we want to keep this dummy device at all)
You should NEVER declare a kobject statically. There should be a check in the kernel that complains about this on some arches in the -mm and -next trees, I'm supprised you didn't hit it.
To quote from the kobject.txt documentation file:
Because kobjects are dynamic, they must not be declared statically or on the stack, but instead, always allocated dynamically. Future versions of the kernel will contain a run-time check for kobjects that are created statically and will warn the developer of this improper usage.
That is why you need a "real" release function.
So, care to respin this again please?
thanks,
greg k-h
Quoted 23 lines · Mark McLoughlin
Quoted 4 lines · Anthony Liguori
Quoted 2 lines · Mark McLoughlin
On Fri, 2008-12-05 at 14:17 +0100, Jiri Slaby wrote:
Quoted 16 lines
Quoted 4 lines
drivers/virtio/virtio_pci.c +2
-0+static void virtio_pci_release_dev (struct device *dev) +{drivers/virtio/virtio_pci.c static struct pci_device_id virtio_pci_id_table[] = { · line 84
Quoted 10 lines
drivers/virtio/virtio_pci.c +3
-0+} +/* A PCI device has it's own struct device and so does a virtio device so * we create a place for the virtio devices to show up in sysfs. I think it * would make more sense for virtio to not insist on having it's own device. */ static struct device virtio_pci_root = { .parent =NULL , .bus_id ="virtio-pci" , + .release = virtio_pci_release_dev, };Actually, we should be able to delete this
virtio_pci_rootentirely. The device is a dummy one anyway.
Quoted 5 lines
Care to recall why it was added initially and what's changed?
One side effect of removing it is that each device appears on its own in
/sys/devicesrather than neatly under/sys/devices/virtio-pci.
Basically, to get the neater sysfs hierarchy. But it seems that this requires Evil Things so I'm inclined to say it's not worth it.
Quoted 3 lines
(And one side effect of that is that the aforementioned Fedora mkinitrd kludge stops working which would make me sad :-)
Yeah, that would be unfortunate. Can the kludge be done differently?
Regards,
Anthony Liguori
Quoted 4 lines
Cheers,
mark.
Quoted 10 lines · On Saturday 06 December 2008 01:37:06 Mark McLoughlin wrote:
Another example of a lack of an explicit dependency causing problems is Fedora's mkinitrd having this hack:
if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fiwhich basically says "if this is a virtio device, don't forget to include
virtio_pciin the initrd too!". Now, mkinitrd is full of hacks, but this is a particularly unusual one.
Um, I don't know what this does, sorry.
I have no idea how Fedora chooses what to put in an initrd; I can't think of a sensible way of deciding what goes in and what doesn't other than lists and heuristics.
But there really is no explicit dependency between virtio modules and virtio_pci. There just is for kvm/x86 at the moment, since that is how they use virtio. Running over another bus is certainly possible, though may never happen for x86 (happens today for s390).
Cheers,
Rusty.
Quoted 22 lines · On Friday 05 December 2008 23:47:06 Jiri Slaby wrote:
Michael Tokarev napsal(a):
Quoted 14 lines
Quoted 4 lines · Jiri Slaby
Quoted 2 lines · Mark McLoughlin
Nothing takes a ref on
virtio_pci, so even if you have devices in use, rmmod will attempt to unload the module.It unbinds the device properly as any other driver. So what's the problem here?
Here's what we get when rmmod'ing (a zero-refcounted but in use)
virtio_pci(I did it by a chance, cut-n-pasted the wrong line):WARNING: at drivers/base/core.c:122 device_release+0x5f/0x70() Device 'virtio1' does not have a release() function, it is broken and must be fixed. Modules linked in: ext3 jbd mbcache acpiphp dock pci_hotplug virtio_net virtio_blk virtio_pci(-) virtio_ring virtioQuoted 6 lines
Pid: 361, comm: rmmod Tainted: G S 2.6.27-i686smp #2.6.27.7
[<c012b81f>] warn_slowpath+0x6f/0xa0 [<c0110030>] prepare_set+0x30/0x80 [<c012067e>] __wake_up+0x3e/0x60 [<c01d1d25>] release_sysfs_dirent+0x45/0xb0 ...
Quoted 4 lines
So why don't you fix the root cause and add such a crap into the probe function (not even counting probe can fail later)?
Fix the virtio bus instead.
Incoherent? CHECK
Rude to bug reporter? CHECK
Unhelpful? CHECK
Wow, you must be a *great* kernel maintainer!
Thanks for making us all so very, very proud.
Rusty.
Quoted 3 lines · Rusty Russell
Quoted 1 line
Fix the virtio bus instead.
Incoherent? CHECK
Sorry, I don't undesratnd here. Incoherent with what?
Quoted 1 line
Rude to bug reporter? CHECK
Maybe it's my english. I apologize all, who understood my replies that way, sorry for that, it was not intentional.
Quoted 1 line
Unhelpful? CHECK
I don't know, I expect people to ask for concrete implementation details, if they don't know. Ok, pointing to the relevant documentation next time would be better, I agree.
PATCH 2/2 virtio: do not statically allocate root device
In reply to Mark McLoughlinApparently we shouldn't be statically allocating the root device object, so dynamically allocate it instead.
Also add a release() function to avoid this warning:
Device 'virtio-pci' does not have a release() function, it is broken and must be fixed
--- drivers/virtio/virtio_pci.c | 48 +++++++++++++++++++++++++++++++++++------- 1 files changed, 40 insertions(+), 8 deletions(-)
drivers/virtio/virtio_pci.c +40 -8
@@ -73,10 +73,42 @@ MODULE_DEVICE_TABLE(pci, virtio_pci_id_table);/* A PCI device has it's own struct device and so does a virtio device so * we create a place for the virtio devices to show up in sysfs. I think it * would make more sense for virtio to not insist on having it's own device. */ -static struct device virtio_pci_root = { - .parent =NULL , - .init_name ="virtio-pci" , -}; +static struct device *virtio_pci_root; + +static void virtio_pci_release_root (struct device *root) +{ +kfree (root); +} + +static int virtio_pci_init_root (void ) +{ +struct device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct device ),GFP_KERNEL ); +if (root ==NULL ) + goto out; + + err =dev_set_name (root,"virtio-pci" ); +if (err) + goto free_root; + + err =device_register (root); +if (err) + goto free_root; + + root->parent =NULL ; + root->release = virtio_pci_release_root; + + virtio_pci_root = root; + +return 0 ; + +free_root: +kfree (root); +out: +return err; +}/* Convert a generic virtio device to our structure */ static struct virtio_pci_device *to_vp_device (struct virtio_device *vdev)
@@ -343,7 +375,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,if (vp_dev ==NULL )return -ENOMEM ; - vp_dev->vdev.dev.parent = &virtio_pci_root; + vp_dev->vdev.dev.parent = virtio_pci_root; vp_dev->vdev.dev.release = virtio_pci_release_dev; vp_dev->vdev.config = &virtio_pci_config_ops; vp_dev->pci_dev = pci_dev;
@@ -437,13 +469,13 @@ static int __init virtio_pci_init(void) {int err; - err =device_register (&virtio_pci_root); + err =virtio_pci_init_root ();if (err)return err; err =pci_register_driver (&virtio_pci_driver);if (err) -device_unregister (&virtio_pci_root); +device_unregister (virtio_pci_root);return err; }
@@ -452,8 +484,8 @@ module_init(virtio_pci_init); static void __exit virtio_pci_exit(void) { -device_unregister (&virtio_pci_root);pci_unregister_driver (&virtio_pci_driver); +device_unregister (virtio_pci_root); }module_exit (virtio_pci_exit);
Signature · 1 line
1.5.4.3
PATCH 1/2 virtio: add PCI device release() function
In reply to Greg KHAdd a release() function for virtio_pci devices so as to avoid:
Device 'virtio0' does not have a release() function, it is broken and must be fixed
Move the code to free the resources associated with the device from virtio_pci_remove() into this new function. virtio_pci_remove() now merely unregisters the device which should cause the final ref to be dropped and virtio_pci_release_dev() to be called.
--- drivers/virtio/virtio_pci.c | 21 +++++++++++++++------ 1 files changed, 15 insertions(+), 6 deletions(-)
drivers/virtio/virtio_pci.c +15 -6
@@ -307,6 +307,20 @@ static struct virtio_config_ops virtio_pci_config_ops = { .finalize_features = vp_finalize_features, }; +static void virtio_pci_release_dev (struct device *_d) +{ + struct virtio_device *dev = container_of(_d, struct virtio_device, dev); +struct virtio_pci_device *vp_dev =to_vp_device (dev); +struct pci_dev *pci_dev = vp_dev->pci_dev; + +free_irq (pci_dev->irq, vp_dev); +pci_set_drvdata (pci_dev,NULL ); +pci_iounmap (pci_dev, vp_dev->ioaddr); +pci_release_regions (pci_dev); +pci_disable_device (pci_dev); +kfree (vp_dev); +} +/* the PCI probing function */ static int __devinit virtio_pci_probe (struct pci_dev *pci_dev,const struct pci_device_id *id)
@@ -330,6 +344,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,return -ENOMEM ; vp_dev->vdev.dev.parent = &virtio_pci_root; + vp_dev->vdev.dev.release = virtio_pci_release_dev; vp_dev->vdev.config = &virtio_pci_config_ops; vp_dev->pci_dev = pci_dev;INIT_LIST_HEAD (&vp_dev->virtqueues);
@@ -389,12 +404,6 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev)struct virtio_pci_device *vp_dev =pci_get_drvdata (pci_dev);unregister_virtio_device (&vp_dev->vdev); -free_irq (pci_dev->irq, vp_dev); -pci_set_drvdata (pci_dev,NULL ); -pci_iounmap (pci_dev, vp_dev->ioaddr); -pci_release_regions (pci_dev); -pci_disable_device (pci_dev); -kfree (vp_dev); }#ifdef CONFIG_PM
Signature · 1 line
1.5.4.3
Quoted 12 lines · Rusty Russell
Quoted 10 lines · On Saturday 06 December 2008 01:37:06 Mark McLoughlin wrote:
Another example of a lack of an explicit dependency causing problems is Fedora's mkinitrd having this hack:
if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fiwhich basically says "if this is a virtio device, don't forget to include
virtio_pciin the initrd too!". Now, mkinitrd is full of hacks, but this is a particularly unusual one.
Quoted 5 lines
Um, I don't know what this does, sorry.
I have no idea how Fedora chooses what to put in an initrd; I can't think of a sensible way of deciding what goes in and what doesn't other than lists and heuristics.
Fedora's mkinitrd creates an initrd suitable to boot the machine you run mkinitrd on, rather than creating an initrd suitable to boot any machine.
So, it goes "ah, / is mounted from /dev/vda, we need to include virtio_blk and it's dependencies". It does that in a generic way that works well for most setups:
1) Find the device name (e.g. vda) below /sys/block
2) Follow the 'device' link to e.g. /sys/devices/virtio-pci/virtio1
3) Find the module need for this through either 'modalias' or the 'driver/module' symlink
4) Use modprobe to list any dependencies of that module
Clearly, virtio-pci won't be pulled in by any of this so we've added a hack to say "oh, it's a virtio device, let's include virtio_pci just in case".
It's not even the case that mkinitrd needs to know how to include the the module for the bus, because in our case that's virtio.ko ... we've pretty effectively hidden the the bus *implementation* from userspace.
I don't think this is worth wasting too much time fixing, that's why I'm thinking we should just make virtio_pci built-in by default with CONFIG_KVM_GUEST.
Quoted 4 lines
But there really is no explicit dependency between virtio modules and
virtio_pci. There just is for kvm/x86 at the moment, since that is how they use virtio. Running over another bus is certainly possible, though may never happen for x86 (happens today for s390).
Right, and in the case of both kvm/s390 and lguest the bus implementation is built-in, not a module.
Cheers,
Mark.
Re: [PATCH 2/2] virtio: do not statically allocate root device
In reply to Mark McLoughlinQuoted 7 lines · Mark McLoughlin
Apparently we shouldn't be statically allocating the root device object, so dynamically allocate it instead.
Also add a
release()function to avoid this warning:Device 'virtio-pci' does not have a
release()function, it is broken and must be fixed
Is it really better to dynamically allocate the root device than statically allocate it? Is the advice that we shouldn't statically allocate a device really a suggestion that if you're doing that, you're using struct device wrong?
If so, this conversion should be equally wrong. Have you chosen to keep this device so that your initrd work-around continues to work as-is? What exactly is the work around and is there a less hackish way we could support it?
Regards,
Anthony Liguori
Quoted 93 lines
Signed-off-by Mark McLoughlin <[email protected]>Cc Anthony Liguori <[email protected]>--- drivers/virtio/virtio_pci.c | 48 +++++++++++++++++++++++++++++++++++------- 1 files changed, 40 insertions(+), 8 deletions(-)drivers/virtio/virtio_pci.c +40
-8@@ -73,10 +73,42 @@ MODULE_DEVICE_TABLE(pci, virtio_pci_id_table);/* A PCI device has it's own struct device and so does a virtio device so * we create a place for the virtio devices to show up in sysfs. I think it * would make more sense for virtio to not insist on having it's own device. */ -static struct device virtio_pci_root = { - .parent =NULL , - .init_name ="virtio-pci" , -}; +static struct device *virtio_pci_root; + +static void virtio_pci_release_root (struct device *root) +{ +kfree (root); +} + +static int virtio_pci_init_root (void ) +{ +struct device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct device ),GFP_KERNEL ); +if (root ==NULL ) + goto out; + + err =dev_set_name (root,"virtio-pci" ); +if (err) + goto free_root; + + err =device_register (root); +if (err) + goto free_root; + + root->parent =NULL ; + root->release = virtio_pci_release_root; + + virtio_pci_root = root; + +return 0 ; + +free_root: +kfree (root); +out: +return err; +}/* Convert a generic virtio device to our structure */ static struct virtio_pci_device *to_vp_device (struct virtio_device *vdev)@@ -343,7 +375,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,if (vp_dev ==NULL )return -ENOMEM ; - vp_dev->vdev.dev.parent = &virtio_pci_root; + vp_dev->vdev.dev.parent = virtio_pci_root; vp_dev->vdev.dev.release = virtio_pci_release_dev; vp_dev->vdev.config = &virtio_pci_config_ops; vp_dev->pci_dev = pci_dev;@@ -437,13 +469,13 @@ static int __init virtio_pci_init(void) {int err; - err =device_register (&virtio_pci_root); + err =virtio_pci_init_root ();if (err)return err; err =pci_register_driver (&virtio_pci_driver);if (err) -device_unregister (&virtio_pci_root); +device_unregister (virtio_pci_root);return err; }@@ -452,8 +484,8 @@ module_init(virtio_pci_init); static void __exit virtio_pci_exit(void) { -device_unregister (&virtio_pci_root);pci_unregister_driver (&virtio_pci_driver); +device_unregister (virtio_pci_root); }module_exit (virtio_pci_exit);
Quoted 43 lines · Mark McLoughlin
Quoted 13 lines · Rusty Russell
Quoted 11 lines · On Saturday 06 December 2008 01:37:06 Mark McLoughlin wrote:
Another example of a lack of an explicit dependency causing problems is Fedora's mkinitrd having this hack:
if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fiwhich basically says "if this is a virtio device, don't forget to include
virtio_pciin the initrd too!". Now, mkinitrd is full of hacks, but this is a particularly unusual one.Quoted 6 lines
Um, I don't know what this does, sorry.
I have no idea how Fedora chooses what to put in an initrd; I can't think of a sensible way of deciding what goes in and what doesn't other than lists and heuristics.
Fedora's mkinitrd creates an initrd suitable to boot the machine you run mkinitrd on, rather than creating an initrd suitable to boot any machine.
So, it goes "ah, / is mounted from
/dev/vda, we need to includevirtio_blkand it's dependencies". It does that in a generic way that works well for most setups:1) Find the device name (e.g. vda) below
/sys/block2) Follow the 'device' link to e.g.
/sys/devices/virtio-pci/virtio13) Find the module need for this through either 'modalias' or the 'driver/module' symlink
4) Use modprobe to list any dependencies of that module
Clearly, virtio-pci won't be pulled in by any of this so we've added a hack to say "oh, it's a virtio device, let's include
virtio_pcijust in case".
Quoted 8 lines
It's not even the case that mkinitrd needs to know how to include the the module for the bus, because in our case that's virtio.ko ... we've pretty effectively hidden the the bus *implementation* from userspace.
I don't think this is worth wasting too much time fixing, that's why I'm thinking we should just make
virtio_pcibuilt-in by default withCONFIG_KVM_GUEST.
What if we have multiple virtio transports? Is there a way that we can expose the relationship with virtio-blk and virtio-pci in sysfs? We have a struct device for the PCI device, it's just a matter of making the link visible.
Regards,
Anthony Liguori
Regards,
Anthony Liguori
Quoted 13 lines
Quoted 5 lines
But there really is no explicit dependency between virtio modules and
virtio_pci. There just is for kvm/x86 at the moment, since that is how they use virtio. Running over another bus is certainly possible, though may never happen for x86 (happens today for s390).Right, and in the case of both kvm/s390 and lguest the bus implementation is built-in, not a module.
Cheers,
Mark.
Re: [PATCH 2/2] virtio: do not statically allocate root device
In reply to Anthony LiguoriQuoted 6 lines · Anthony Liguori
Quoted 5 lines · Mark McLoughlin
Apparently we shouldn't be statically allocating the root device object, so dynamically allocate it instead.
Also add a
release()function to avoid this warning:
Quoted 7 lines
Quoted 2 lines
Device 'virtio-pci' does not have a
release()function, it is broken and must be fixedIs it really better to dynamically allocate the root device than statically allocate it? Is the advice that we shouldn't statically allocate a device really a suggestion that if you're doing that, you're using struct device wrong?
There are other statically allocated devices in tree[1]. It seems this is actively discouraged, though.
AFAICT, the platform_bus device is there for a similar reason to ours - i.e. to group devices together in sysfs.
Quoted 2 lines
If so, this conversion should be equally wrong. Have you chosen to keep this device so that your initrd work-around continues to work as-is?
I choose to keep it because:
a) I'm trying to fix the warning spew from 'rmmod virtio_pci' without breaking anything else
b) The grouping under /sys/devices/{virtio-pci,lguest,kvm_s390} is useful IMHO and there are precedents (e.g. /sys/devices/platform)
c) It's better to not gratuitously move stuff around where we know it will break something
Quoted 2 lines
What exactly is the work around and is there a less hackish way we could support it?
Being discussed elsewhere in the thread.
Cheers,
Mark.
[1] - git-grep 'struct device .* = {' next-20081204 next-20081204:arch/cris/arch-v32/drivers/iop_fw_load.c:static struct device iop_spu_device[2] = { next-20081204:arch/cris/arch-v32/drivers/iop_fw_load.c:static struct device iop_mpu_device = { next-20081204:arch/ia64/kernel/pci-dma.c:struct device fallback_dev = { next-20081204:arch/parisc/kernel/drivers.c:static struct device root = { next-20081204:arch/powerpc/kernel/ibmebus.c:static struct device ibmebus_bus_device = { /* fake "parent" device */ next-20081204:arch/powerpc/platforms/ps3/system-bus.c:static struct device ps3_system_bus = { next-20081204:arch/x86/kernel/pci-dma.c:struct device x86_dma_fallback_dev = { next-20081204:drivers/base/isa.c:static struct device isa_bus = { next-20081204:drivers/base/platform.c:struct device platform_bus = { next-20081204:drivers/idle/i7300_idle.c:static struct device dummy_dma_dev = { next-20081204:drivers/ieee1394/nodemgr.c:static struct device nodemgr_dev_template_ud = { next-20081204:drivers/ieee1394/nodemgr.c:static struct device nodemgr_dev_template_ne = { next-20081204:drivers/ieee1394/nodemgr.c:struct device nodemgr_dev_template_host = { next-20081204:drivers/lguest/lguest_device.c:static struct device lguest_root = { next-20081204:drivers/misc/sgi-gru/grumain.c:static struct device gru_device = { next-20081204:drivers/misc/sgi-xp/xp_main.c:struct device xp_dbg_subname = { next-20081204:drivers/misc/sgi-xp/xpc_main.c:struct device xpc_part_dbg_subname = { next-20081204:drivers/misc/sgi-xp/xpc_main.c:struct device xpc_chan_dbg_subname = { next-20081204:drivers/misc/sgi-xp/xpnet.c:struct device xpnet_dbg_subname = {
...
next-20081204:drivers/rapidio/rio-driver.c:static struct device rio_bus = { next-20081204:drivers/scsi/scsi_debug.c:static struct device pseudo_primary = { next-20081204:drivers/sh/maple/maple.c:static struct device maple_bus = { next-20081204:drivers/sh/superhyway/superhyway.c:static struct device superhyway_bus_device = { next-20081204:drivers/virtio/virtio_pci.c:static struct device virtio_pci_root = { next-20081204:drivers/w1/w1.c:struct device w1_master_device = { next-20081204:drivers/w1/w1.c:struct device w1_slave_device = { next-20081204:samples/firmware_class/firmware_sample_driver.c:static struct device ghost_device = { next-20081204:samples/firmware_class/firmware_sample_firmware_class.c:static struct device my_device = {
Quoted 48 lines · Anthony Liguori
Quoted 47 lines · Mark McLoughlin
Quoted 13 lines · Rusty Russell
Quoted 11 lines · On Saturday 06 December 2008 01:37:06 Mark McLoughlin wrote:
Another example of a lack of an explicit dependency causing problems is Fedora's mkinitrd having this hack:
if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fiwhich basically says "if this is a virtio device, don't forget to include
virtio_pciin the initrd too!". Now, mkinitrd is full of hacks, but this is a particularly unusual one.Quoted 6 lines
Um, I don't know what this does, sorry.
I have no idea how Fedora chooses what to put in an initrd; I can't think of a sensible way of deciding what goes in and what doesn't other than lists and heuristics.
Fedora's mkinitrd creates an initrd suitable to boot the machine you run mkinitrd on, rather than creating an initrd suitable to boot any machine.
So, it goes "ah, / is mounted from
/dev/vda, we need to includevirtio_blkand it's dependencies". It does that in a generic way that works well for most setups:1) Find the device name (e.g. vda) below
/sys/block2) Follow the 'device' link to e.g.
/sys/devices/virtio-pci/virtio13) Find the module need for this through either 'modalias' or the 'driver/module' symlink
4) Use modprobe to list any dependencies of that module
Clearly, virtio-pci won't be pulled in by any of this so we've added a hack to say "oh, it's a virtio device, let's include
virtio_pcijust in case".It's not even the case that mkinitrd needs to know how to include the the module for the bus, because in our case that's virtio.ko ... we've pretty effectively hidden the the bus *implementation* from userspace.
Quoted 6 lines
Quoted 4 lines
I don't think this is worth wasting too much time fixing, that's why I'm thinking we should just make
virtio_pcibuilt-in by default withCONFIG_KVM_GUEST.What if we have multiple virtio transports?
I don't think that's so much an an issue (just build in any transport supported by KVM), but rather that you might build a non-pv_ops kernel to run on QEMU which would benefit from using virtio drivers ...
Quoted 4 lines
Is there a way that we can
expose the relationship with virtio-blk and virtio-pci in sysfs? We have a struct device for the PCI device, it's just a matter of making the link visible.
It feels a bit like busy work to generalise this since only virtio_pci can be built as a module, but here's a patch.
The mkinitrd hack turns into:
# Handle finding virtio bus implementations if [ -L ./virtio_module ] ; then
findmodule $(basename $(readlink ./virtio_module))
else if echo $PWD | grep -q /virtio-pci/ ; then
findmodule virtio_pci
fi; fi
Cheers,
Mark.
[PATCH] virtio: add a 'virtio_module' sysfs symlink
Add a way for userspace to determine which virtio bus transport a given device is associated with.
This will be used by Fedora mkinitrd to generically determine e.g. that virtio_pci is needed to mount a given root filesystem.
--- drivers/virtio/virtio.c | 21 ++++++++++++++++++++- drivers/virtio/virtio_pci.c | 1 + include/linux/virtio_config.h | 2 ++ 3 files changed, 23 insertions(+), 1 deletions(-)
drivers/virtio/virtio.c +20 -1
@@ -189,13 +189,32 @@ int register_virtio_device(struct virtio_device *dev)* matching driver. */ err =device_register (&dev->dev);if (err) -add_status (dev,VIRTIO_CONFIG_S_FAILED ); + goto out; + +/* Create a virtio_module symlink */ +if (dev->config->owner) { +struct module_kobject *mk = &dev->config->owner->mkobj; + + err =sysfs_create_link (&dev->dev.kobj, &mk->kobj, +"virtio_module" ); +if (err) + goto unreg; + } + +return 0 ; + +unreg: +device_unregister (&dev->dev); +out: +add_status (dev,VIRTIO_CONFIG_S_FAILED );return err; }EXPORT_SYMBOL_GPL (register_virtio_device);void unregister_virtio_device (struct virtio_device *dev) { +if (dev->config->owner) +sysfs_remove_link (&dev->dev.kobj,"virtio_module" );device_unregister (&dev->dev); }EXPORT_SYMBOL_GPL (unregister_virtio_device);
drivers/virtio/virtio_pci.c +1 -0
@@ -328,6 +328,7 @@ static void vp_del_vq(struct virtqueue *vq) }static struct virtio_config_ops virtio_pci_config_ops = { + .owner =THIS_MODULE , .get = vp_get, .set = vp_set, .get_status = vp_get_status,
include/linux/virtio_config.h +2 -0
@@ -33,6 +33,7 @@/** * virtio_config_ops - operations for configuring a virtio device +* @owner: the module implementing these ops, usually THIS_MODULE * @get: read the value of a configuration field * vdev: the virtio_device * offset: the offset of the configuration field
@@ -68,6 +69,7 @@*/ struct virtio_config_ops { +struct module *owner;void (*get)(struct virtio_device *vdev,unsigned offset,void *buf,unsigned len); void (*set)(struct virtio_device *vdev, unsigned offset,
Signature · 1 line
1.6.0.3
Anthony Liguori
Acked-byQuoted 19 lines · Mark McLoughlin
On Mon, 2008-12-08 at 08:46 -0600, Anthony Liguori wrote:
It feels a bit like busy work to generalise this since only
virtio_pcican be built as a module, but here's a patch.The mkinitrd hack turns into:
# Handle finding virtio bus implementations if [ -L ./virtio_module ] ; then
findmodule $(basename $(readlink ./virtio_module))
else if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fi; fiCheers,
Mark.[PATCH] virtio: add a '
virtio_module' sysfs symlink
Quoted 8 lines
Add a way for userspace to determine which virtio bus transport a given device is associated with.
This will be used by Fedora mkinitrd to generically determine e.g. that
virtio_pciis needed to mount a given root filesystem.Signed-off-by Mark McLoughlin <[email protected]>
Quoted 77 lines
--- drivers/virtio/virtio.c | 21 ++++++++++++++++++++- drivers/virtio/virtio_pci.c | 1 + include/linux/virtio_config.h | 2 ++ 3 files changed, 23 insertions(+), 1 deletions(-)drivers/virtio/virtio.c +20
-1@@ -189,13 +189,32 @@ int register_virtio_device(struct virtio_device *dev)* matching driver. */ err =device_register (&dev->dev);if (err) -add_status (dev,VIRTIO_CONFIG_S_FAILED ); + goto out; + +/* Create a virtio_module symlink */ +if (dev->config->owner) { +struct module_kobject *mk = &dev->config->owner->mkobj; + + err =sysfs_create_link (&dev->dev.kobj, &mk->kobj, +"virtio_module" ); +if (err) + goto unreg; + } + +return 0 ; + +unreg: +device_unregister (&dev->dev); +out: +add_status (dev,VIRTIO_CONFIG_S_FAILED );return err; }EXPORT_SYMBOL_GPL (register_virtio_device);void unregister_virtio_device (struct virtio_device *dev) { +if (dev->config->owner) +sysfs_remove_link (&dev->dev.kobj,"virtio_module" );device_unregister (&dev->dev); }EXPORT_SYMBOL_GPL (unregister_virtio_device);drivers/virtio/virtio_pci.c +1
-0@@ -328,6 +328,7 @@ static void vp_del_vq(struct virtqueue *vq) }static struct virtio_config_ops virtio_pci_config_ops = { + .owner =THIS_MODULE , .get = vp_get, .set = vp_set, .get_status = vp_get_status,include/linux/virtio_config.h +2
-0@@ -33,6 +33,7 @@/** * virtio_config_ops - operations for configuring a virtio device +* @owner: the module implementing these ops, usually THIS_MODULE * @get: read the value of a configuration field * vdev: the virtio_device * offset: the offset of the configuration field @@ -68,6 +69,7 @@*/ struct virtio_config_ops { +struct module *owner;void (*get)(struct virtio_device *vdev,unsigned offset,void *buf,unsigned len); void (*set)(struct virtio_device *vdev, unsigned offset,
Quoted 76 lines · Mark McLoughlin
Quoted 47 lines · Anthony Liguori
Quoted 46 lines · Mark McLoughlin
Quoted 13 lines · Rusty Russell
Quoted 11 lines · On Saturday 06 December 2008 01:37:06 Mark McLoughlin wrote:
Another example of a lack of an explicit dependency causing problems is Fedora's mkinitrd having this hack:
if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fiwhich basically says "if this is a virtio device, don't forget to include
virtio_pciin the initrd too!". Now, mkinitrd is full of hacks, but this is a particularly unusual one.Quoted 6 lines
Um, I don't know what this does, sorry.
I have no idea how Fedora chooses what to put in an initrd; I can't think of a sensible way of deciding what goes in and what doesn't other than lists and heuristics.
Fedora's mkinitrd creates an initrd suitable to boot the machine you run mkinitrd on, rather than creating an initrd suitable to boot any machine.
So, it goes "ah, / is mounted from
/dev/vda, we need to includevirtio_blkand it's dependencies". It does that in a generic way that works well for most setups:1) Find the device name (e.g. vda) below
/sys/block2) Follow the 'device' link to e.g.
/sys/devices/virtio-pci/virtio13) Find the module need for this through either 'modalias' or the 'driver/module' symlink
4) Use modprobe to list any dependencies of that module
Clearly, virtio-pci won't be pulled in by any of this so we've added a hack to say "oh, it's a virtio device, let's include
virtio_pcijust in case".It's not even the case that mkinitrd needs to know how to include the the module for the bus, because in our case that's virtio.ko ... we've pretty effectively hidden the the bus *implementation* from userspace.
Quoted 6 lines
Quoted 4 lines
I don't think this is worth wasting too much time fixing, that's why I'm thinking we should just make
virtio_pcibuilt-in by default withCONFIG_KVM_GUEST.What if we have multiple virtio transports?
I don't think that's so much an an issue (just build in any transport supported by KVM), but rather that you might build a non-pv_ops kernel to run on QEMU which would benefit from using virtio drivers ...
Quoted 4 lines
Is there a way that we can
expose the relationship with virtio-blk and virtio-pci in sysfs? We have a struct device for the PCI device, it's just a matter of making the link visible.It feels a bit like busy work to generalise this since only
virtio_pcican be built as a module, but here's a patch.The mkinitrd hack turns into:
# Handle finding virtio bus implementations if [ -L ./virtio_module ] ; then
findmodule $(basename $(readlink ./virtio_module))
else if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fi; fi
Quoted 4 lines
Cheers,
Mark.[PATCH] virtio: add a '
virtio_module' sysfs symlink
Doesn't the device have a "driver" link already? If yes, the driver it points to should have a "module" link.
Thanks,
Kay
Quoted 6 lines · Rusty Russell
Quoted 4 lines · On Thursday 04 December 2008 23:14:31 Mark McLoughlin wrote:
Nothing takes a ref on
virtio_pci, so even if you have devices in use, rmmod will attempt to unload the module.Fix by simply making each device take a ref on the module.
Quoted 7 lines
Hi Mark,
Taking a reference to oneself is almost always wrong. I'm a little
surprised that a successful call topci_device->probedoesn't bump the module count though.Jesse?
Looks like the PCI bus type's probe function does take a device reference, which should get called from driver_register when the driver calls pci_register_driver... Is that not happening in the virtio case?
Signature · 1 line
Jesse Barnes, Intel Open Source Technology Center
Quoted 77 lines · Kay Sievers
Quoted 76 lines · Mark McLoughlin
Quoted 47 lines · Anthony Liguori
Quoted 46 lines · Mark McLoughlin
Quoted 13 lines · Rusty Russell
Quoted 11 lines · On Saturday 06 December 2008 01:37:06 Mark McLoughlin wrote:
Another example of a lack of an explicit dependency causing problems is Fedora's mkinitrd having this hack:
if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fiwhich basically says "if this is a virtio device, don't forget to include
virtio_pciin the initrd too!". Now, mkinitrd is full of hacks, but this is a particularly unusual one.Quoted 6 lines
Um, I don't know what this does, sorry.
I have no idea how Fedora chooses what to put in an initrd; I can't think of a sensible way of deciding what goes in and what doesn't other than lists and heuristics.
Fedora's mkinitrd creates an initrd suitable to boot the machine you run mkinitrd on, rather than creating an initrd suitable to boot any machine.
So, it goes "ah, / is mounted from
/dev/vda, we need to includevirtio_blkand it's dependencies". It does that in a generic way that works well for most setups:1) Find the device name (e.g. vda) below
/sys/block2) Follow the 'device' link to e.g.
/sys/devices/virtio-pci/virtio13) Find the module need for this through either 'modalias' or the 'driver/module' symlink
4) Use modprobe to list any dependencies of that module
Clearly, virtio-pci won't be pulled in by any of this so we've added a hack to say "oh, it's a virtio device, let's include
virtio_pcijust in case".It's not even the case that mkinitrd needs to know how to include the the module for the bus, because in our case that's virtio.ko ... we've pretty effectively hidden the the bus *implementation* from userspace.
Quoted 6 lines
Quoted 4 lines
I don't think this is worth wasting too much time fixing, that's why I'm thinking we should just make
virtio_pcibuilt-in by default withCONFIG_KVM_GUEST.What if we have multiple virtio transports?
I don't think that's so much an an issue (just build in any transport supported by KVM), but rather that you might build a non-pv_ops kernel to run on QEMU which would benefit from using virtio drivers ...
Quoted 4 lines
Is there a way that we can
expose the relationship with virtio-blk and virtio-pci in sysfs? We have a struct device for the PCI device, it's just a matter of making the link visible.It feels a bit like busy work to generalise this since only
virtio_pcican be built as a module, but here's a patch.The mkinitrd hack turns into:
# Handle finding virtio bus implementations if [ -L ./virtio_module ] ; then
findmodule $(basename $(readlink ./virtio_module))
else if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fi; fi
Quoted 7 lines
Quoted 4 lines
Cheers,
Mark.[PATCH] virtio: add a '
virtio_module' sysfs symlinkDoesn't the device have a "driver" link already? If yes, the driver it points to should have a "module" link.
The virtio bus is an abstraction that has several different backend implementations - currently virtio-pci, lguest and kvm-s390.
So yes, the driver/module link gives us the device driver, but the virtio_module link is to the virtio bus driver (aka implementation, transport, backend, ...):
$> basename $(readlink virtio_module) virtio_pci $> basename $(readlink driver/module) virtio_net
Cheers,
Mark.
Quoted 86 lines · Mark McLoughlin
Quoted 77 lines · Kay Sievers
Quoted 76 lines · Mark McLoughlin
Quoted 47 lines · Anthony Liguori
Quoted 46 lines · Mark McLoughlin
Quoted 13 lines · Rusty Russell
Quoted 11 lines · On Saturday 06 December 2008 01:37:06 Mark McLoughlin wrote:
Another example of a lack of an explicit dependency causing problems is Fedora's mkinitrd having this hack:
if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fiwhich basically says "if this is a virtio device, don't forget to include
virtio_pciin the initrd too!". Now, mkinitrd is full of hacks, but this is a particularly unusual one.Quoted 6 lines
Um, I don't know what this does, sorry.
I have no idea how Fedora chooses what to put in an initrd; I can't think of a sensible way of deciding what goes in and what doesn't other than lists and heuristics.
Fedora's mkinitrd creates an initrd suitable to boot the machine you run mkinitrd on, rather than creating an initrd suitable to boot any machine.
So, it goes "ah, / is mounted from
/dev/vda, we need to includevirtio_blkand it's dependencies". It does that in a generic way that works well for most setups:1) Find the device name (e.g. vda) below
/sys/block2) Follow the 'device' link to e.g.
/sys/devices/virtio-pci/virtio13) Find the module need for this through either 'modalias' or the 'driver/module' symlink
4) Use modprobe to list any dependencies of that module
Clearly, virtio-pci won't be pulled in by any of this so we've added a hack to say "oh, it's a virtio device, let's include
virtio_pcijust in case".It's not even the case that mkinitrd needs to know how to include the the module for the bus, because in our case that's virtio.ko ... we've pretty effectively hidden the the bus *implementation* from userspace.
Quoted 6 lines
Quoted 4 lines
I don't think this is worth wasting too much time fixing, that's why I'm thinking we should just make
virtio_pcibuilt-in by default withCONFIG_KVM_GUEST.What if we have multiple virtio transports?
I don't think that's so much an an issue (just build in any transport supported by KVM), but rather that you might build a non-pv_ops kernel to run on QEMU which would benefit from using virtio drivers ...
Quoted 4 lines
Is there a way that we can
expose the relationship with virtio-blk and virtio-pci in sysfs? We have a struct device for the PCI device, it's just a matter of making the link visible.It feels a bit like busy work to generalise this since only
virtio_pcican be built as a module, but here's a patch.The mkinitrd hack turns into:
# Handle finding virtio bus implementations if [ -L ./virtio_module ] ; then
findmodule $(basename $(readlink ./virtio_module))
else if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fi; fiQuoted 4 lines
Quoted 1 line
[PATCH] virtio: add a '
virtio_module' sysfs symlinkDoesn't the device have a "driver" link already? If yes, the driver it points to should have a "module" link.
The virtio bus is an abstraction that has several different backend implementations - currently virtio-pci, lguest and kvm-s390.
Quoted 8 lines
So yes, the driver/module link gives us the device driver, but the
virtio_modulelink is to the virtio bus driver (aka implementation, transport, backend, ...):$> basename $(readlink
virtio_module)
virtio_pci
$> basename $(readlink driver/module)
virtio_net
I see. But why not just call it "module", like we do in all other places, when it points to /sys/module/.
To find dependent modules, you would walk up the chain of parents, and include everything that is found by looking for "driver/module" and "module" links?
Wouldn't that make it completely generic, without any virtio specific hacks?
Kay
cover Clean up virtio device object handling [was Re: [PATCH] virtio: make PCI devices take a virtio_pci module ref]
(Moved from kvm@vger to virtualization@linux-foundation, changed subject, cleaned up cc list)
Quoted 96 lines · Kay Sievers
Quoted 86 lines · Mark McLoughlin
Quoted 77 lines · Kay Sievers
Quoted 76 lines · Mark McLoughlin
Quoted 47 lines · Anthony Liguori
Quoted 46 lines · Mark McLoughlin
Quoted 13 lines · Rusty Russell
Quoted 11 lines · On Saturday 06 December 2008 01:37:06 Mark McLoughlin wrote:
Another example of a lack of an explicit dependency causing problems is Fedora's mkinitrd having this hack:
if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fiwhich basically says "if this is a virtio device, don't forget to include
virtio_pciin the initrd too!". Now, mkinitrd is full of hacks, but this is a particularly unusual one.Quoted 6 lines
Um, I don't know what this does, sorry.
I have no idea how Fedora chooses what to put in an initrd; I can't think of a sensible way of deciding what goes in and what doesn't other than lists and heuristics.
Fedora's mkinitrd creates an initrd suitable to boot the machine you run mkinitrd on, rather than creating an initrd suitable to boot any machine.
So, it goes "ah, / is mounted from
/dev/vda, we need to includevirtio_blkand it's dependencies". It does that in a generic way that works well for most setups:1) Find the device name (e.g. vda) below
/sys/block2) Follow the 'device' link to e.g.
/sys/devices/virtio-pci/virtio13) Find the module need for this through either 'modalias' or the 'driver/module' symlink
4) Use modprobe to list any dependencies of that module
Clearly, virtio-pci won't be pulled in by any of this so we've added a hack to say "oh, it's a virtio device, let's include
virtio_pcijust in case".It's not even the case that mkinitrd needs to know how to include the the module for the bus, because in our case that's virtio.ko ... we've pretty effectively hidden the the bus *implementation* from userspace.
Quoted 6 lines
Quoted 4 lines
I don't think this is worth wasting too much time fixing, that's why I'm thinking we should just make
virtio_pcibuilt-in by default withCONFIG_KVM_GUEST.What if we have multiple virtio transports?
I don't think that's so much an an issue (just build in any transport supported by KVM), but rather that you might build a non-pv_ops kernel to run on QEMU which would benefit from using virtio drivers ...
Quoted 4 lines
Is there a way that we can
expose the relationship with virtio-blk and virtio-pci in sysfs? We have a struct device for the PCI device, it's just a matter of making the link visible.It feels a bit like busy work to generalise this since only
virtio_pcican be built as a module, but here's a patch.The mkinitrd hack turns into:
# Handle finding virtio bus implementations if [ -L ./virtio_module ] ; then
findmodule $(basename $(readlink ./virtio_module))
else if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fi; fiQuoted 4 lines
Quoted 1 line
[PATCH] virtio: add a '
virtio_module' sysfs symlinkDoesn't the device have a "driver" link already? If yes, the driver it points to should have a "module" link.
The virtio bus is an abstraction that has several different backend implementations - currently virtio-pci, lguest and kvm-s390.
Quoted 8 lines
So yes, the driver/module link gives us the device driver, but the
virtio_modulelink is to the virtio bus driver (aka implementation, transport, backend, ...):$> basename $(readlink
virtio_module)
virtio_pci
$> basename $(readlink driver/module)
virtio_net
Quoted 8 lines
I see. But why not just call it "module", like we do in all other places, when it points to
/sys/module/.To find dependent modules, you would walk up the chain of parents, and include everything that is found by looking for "driver/module" and "module" links?
Wouldn't that make it completely generic, without any virtio specific hacks?
Yeah, that sounds much better - a minor detail is that it'd be better to hang the symlink off each virtio implementation's root object rather than off each device.
To that end, I've hacked up register_virtio_root_device() which fixes the fact that we statically allocate root objects and gives us a sane place to add this generic symlink.
It might make sense to add this to the core, though - e.g. device_register_root() - and that would also allow us use the same approach as module_add_driver() to add the module symlink for built-in modules.
Cheers,
Mark.
PATCH 2/6 virtio: add register_virtio_root_device()
In reply to Mark McLoughlinAdd a function to allocate a root device object to group the devices from a given virtio implementation.
Also add a 'module' sysfs symlink to allow so that userspace can generically determine which virtio implementation a device is associated with. This will be used by Fedora mkinitrd to generically determine e.g. that virtio_pci is needed to mount a given root filesystem.
--- drivers/virtio/virtio.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/virtio.h | 10 ++++++ 2 files changed, 81 insertions(+), 0 deletions(-)
drivers/virtio/virtio.c +71 -0
@@ -1,6 +1,7 @@#include <linux/virtio.h> #include <linux/spinlock.h> #include <linux/virtio_config.h> +#include <linux/err.h> /* Unique numbering for virtio devices. */ static unsigned int dev_index;
@@ -200,6 +201,76 @@ void unregister_virtio_device(struct virtio_device *dev) }EXPORT_SYMBOL_GPL (unregister_virtio_device); +/* A root device for virtio devices from a given backend. This makes them +* appear as /sys/devices/{name}/0,1,2 not /sys/devices/0,1,2. It also allows +* us to have a /sys/devices/{name}/module symlink to the backend module. */ +struct virtio_root_device +{ +struct device dev; +struct module *owner; +}; + +static struct virtio_root_device *to_virtio_root (struct device *dev) +{ + return container_of(dev, struct virtio_root_device, dev); +} + +static void release_virtio_root_device (struct device *dev) +{ +struct virtio_root_device *root =to_virtio_root (dev); +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" ); +kfree (root); +} + +struct device *__register_virtio_root_device (const char *name, +struct module *owner) +{ +struct virtio_root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct virtio_root_device ),GFP_KERNEL ); +if (!root) + goto out; + + err =dev_set_name (&root->dev, name); +if (err) + goto free_root; + + err =device_register (&root->dev); +if (err) + goto free_root; + + root->dev.parent =NULL ; + root->dev.release = release_virtio_root_device; + +if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) { +device_unregister (&root->dev); +return ERR_PTR (err); + } + + root->owner = owner; + } + +return &root->dev; + +free_root: +kfree (root); +out: +return ERR_PTR (err); +} +EXPORT_SYMBOL_GPL (__register_virtio_root_device); + +void unregister_virtio_root_device (struct device *root) +{ +device_unregister (root); +} +EXPORT_SYMBOL_GPL (unregister_virtio_root_device); +static int virtio_init (void ) {if (bus_register (&virtio_bus) !=0 )
include/linux/virtio.h +10 -0
@@ -93,6 +93,16 @@ struct virtio_deviceint register_virtio_device (struct virtio_device *dev);void unregister_virtio_device (struct virtio_device *dev); +/* A root device is a dummy device used to group virtio devices from each +* implementation. */ +struct device *__register_virtio_root_device (const char *name, +struct module *owner); +static inline struct device *register_virtio_root_device (const char *name) +{ +return __register_virtio_root_device (name,THIS_MODULE ); +} +void unregister_virtio_root_device (struct device *root); +/** * virtio_driver - operations for a virtio I/O driver * @driver: underlying device driver (populate name and owner).
Signature · 1 line
1.5.4.3
PATCH 1/6 virtio: add PCI device release() function
In reply to Mark McLoughlinAdd a release() function for virtio_pci devices so as to avoid:
Device 'virtio0' does not have a release() function, it is broken and must be fixed
Move the code to free the resources associated with the device from virtio_pci_remove() into this new function. virtio_pci_remove() now merely unregisters the device which should cause the final ref to be dropped and virtio_pci_release_dev() to be called.
--- drivers/virtio/virtio_pci.c | 21 +++++++++++++++------ 1 files changed, 15 insertions(+), 6 deletions(-)
drivers/virtio/virtio_pci.c +15 -6
@@ -307,6 +307,20 @@ static struct virtio_config_ops virtio_pci_config_ops = { .finalize_features = vp_finalize_features, }; +static void virtio_pci_release_dev (struct device *_d) +{ + struct virtio_device *dev = container_of(_d, struct virtio_device, dev); +struct virtio_pci_device *vp_dev =to_vp_device (dev); +struct pci_dev *pci_dev = vp_dev->pci_dev; + +free_irq (pci_dev->irq, vp_dev); +pci_set_drvdata (pci_dev,NULL ); +pci_iounmap (pci_dev, vp_dev->ioaddr); +pci_release_regions (pci_dev); +pci_disable_device (pci_dev); +kfree (vp_dev); +} +/* the PCI probing function */ static int __devinit virtio_pci_probe (struct pci_dev *pci_dev,const struct pci_device_id *id)
@@ -330,6 +344,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,return -ENOMEM ; vp_dev->vdev.dev.parent = &virtio_pci_root; + vp_dev->vdev.dev.release = virtio_pci_release_dev; vp_dev->vdev.config = &virtio_pci_config_ops; vp_dev->pci_dev = pci_dev;INIT_LIST_HEAD (&vp_dev->virtqueues);
@@ -389,12 +404,6 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev)struct virtio_pci_device *vp_dev =pci_get_drvdata (pci_dev);unregister_virtio_device (&vp_dev->vdev); -free_irq (pci_dev->irq, vp_dev); -pci_set_drvdata (pci_dev,NULL ); -pci_iounmap (pci_dev, vp_dev->ioaddr); -pci_release_regions (pci_dev); -pci_disable_device (pci_dev); -kfree (vp_dev); }#ifdef CONFIG_PM
Signature · 1 line
1.5.4.3
PATCH 5/6 kvm-s390: use register_virtio_root_device()
In reply to Mark McLoughlinThis is basically a no-op change, since it does exactly the same thing as s390_root_dev_register() when the caller isn't a module.
--- drivers/s390/kvm/kvm_virtio.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/s390/kvm/kvm_virtio.c +2 -2
@@ -335,7 +335,7 @@ static int __init kvm_devices_init(void)if (!MACHINE_IS_KVM )return -ENODEV ; - kvm_root =s390_root_dev_register ("kvm_s390" ); + kvm_root =register_virtio_root_device ("kvm_s390" );if (IS_ERR (kvm_root)) { rc =PTR_ERR (kvm_root);printk (KERN_ERR "Could not register kvm_s390 root device" );
@@ -344,7 +344,7 @@ static int __init kvm_devices_init(void) rc =vmem_add_mapping (real_memory_size,PAGE_SIZE );if (rc) { -s390_root_dev_unregister (kvm_root); +unregister_virtio_root_device (kvm_root);return rc; }
Signature · 1 line
1.5.4.3
PATCH 4/6 lguest: do not statically allocate root device
In reply to Mark McLoughlinWe shouldn't be statically allocating the root device object, so dynamically allocate it using register_virtio_root_device() instead.
--- drivers/lguest/lguest_device.c | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-)
drivers/lguest/lguest_device.c +4 -6
@@ -321,10 +321,7 @@ static struct virtio_config_ops lguest_config_ops = {/* The root device for the lguest virtio devices. This makes them appear as * /sys/devices/lguest/0,1,2 not /sys/devices/0,1,2. */ -static struct device lguest_root = { - .parent =NULL , - .bus_id ="lguest" , -}; +static struct device *lguest_root;/*D:120 This is the core of the lguest bus: actually adding a new device. * It's a separate function because it's neater that way, and because an
@@ -351,7 +348,7 @@ static void add_lguest_device(struct lguest_device_desc *d, }/* This devices' parent is the lguest/ dir. */ - ldev->vdev.dev.parent = &lguest_root; + ldev->vdev.dev.parent = lguest_root;/* We have a unique device index thanks to the dev_index counter. */ ldev->vdev.id.device = d->type;/* We have a simple set of routines for querying the device's
@@ -407,7 +404,8 @@ static int __init lguest_devices_init(void)if (strcmp (pv_info.name,"lguest" ) !=0 )return 0 ; -if (device_register (&lguest_root) !=0 ) + lguest_root =register_virtio_root_device ("lguest" ); +if (IS_ERR (lguest_root))panic ("Could not register lguest root" );/* Devices are in a single page above top of "normal" mem */
Signature · 1 line
1.5.4.3
PATCH 6/6 lguest: struct device - replace bus_id with dev_name()
In reply to Mark McLoughlinbus_id is gradually being removed, so use dev_name() instead.
--- drivers/lguest/lguest_device.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/lguest/lguest_device.c +1 -1
@@ -272,7 +272,7 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev,* the interrupt as a source of randomness: it'd be nice to have that * back.. */ err =request_irq (lvq->config.irq, vring_interrupt,IRQF_SHARED , - vdev->dev.bus_id, vq); +dev_name (&vdev->dev), vq);if (err) goto destroy_vring;
Signature · 1 line
1.5.4.3
PATCH 3/6 virtio: do not statically allocate root device
In reply to Mark McLoughlinWe shouldn't be statically allocating the root device object, so dynamically allocate it using register_virtio_root_device() instead.
Also avoids this warning from 'rmmod virtio_pci':
Device 'virtio-pci' does not have a release() function, it is broken and must be fixed
--- drivers/virtio/virtio_pci.c | 17 +++++++---------- 1 files changed, 7 insertions(+), 10 deletions(-)
drivers/virtio/virtio_pci.c +7 -10
@@ -73,10 +73,7 @@ MODULE_DEVICE_TABLE(pci, virtio_pci_id_table);/* A PCI device has it's own struct device and so does a virtio device so * we create a place for the virtio devices to show up in sysfs. I think it * would make more sense for virtio to not insist on having it's own device. */ -static struct device virtio_pci_root = { - .parent =NULL , - .init_name ="virtio-pci" , -}; +static struct device *virtio_pci_root;/* Convert a generic virtio device to our structure */ static struct virtio_pci_device *to_vp_device (struct virtio_device *vdev)
@@ -343,7 +340,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,if (vp_dev ==NULL )return -ENOMEM ; - vp_dev->vdev.dev.parent = &virtio_pci_root; + vp_dev->vdev.dev.parent = virtio_pci_root; vp_dev->vdev.dev.release = virtio_pci_release_dev; vp_dev->vdev.config = &virtio_pci_config_ops; vp_dev->pci_dev = pci_dev;
@@ -437,13 +434,13 @@ static int __init virtio_pci_init(void) {int err; - err =device_register (&virtio_pci_root); -if (err) -return err; + virtio_pci_root =register_virtio_root_device ("virtio-pci" ); +if (IS_ERR (virtio_pci_root)) +return PTR_ERR (virtio_pci_root); err =pci_register_driver (&virtio_pci_driver);if (err) -device_unregister (&virtio_pci_root); +device_unregister (virtio_pci_root);return err; }
@@ -452,8 +449,8 @@ module_init(virtio_pci_init); static void __exit virtio_pci_exit(void) { -device_unregister (&virtio_pci_root);pci_unregister_driver (&virtio_pci_driver); +unregister_virtio_root_device (virtio_pci_root); }module_exit (virtio_pci_exit);
Signature · 1 line
1.5.4.3
Re: [PATCH 0/6] Clean up virtio device object handling [was Re: [PATCH] virtio: make PCI devices take a virtio_pci module ref]
In reply to Mark McLoughlinQuoted 106 lines · Mark McLoughlin
(Moved from kvm@vger to virtualization@linux-foundation, changed subject, cleaned up cc list)
Quoted 103 lines · Kay Sievers
Quoted 86 lines · Mark McLoughlin
Quoted 77 lines · Kay Sievers
Quoted 76 lines · Mark McLoughlin
Quoted 47 lines · Anthony Liguori
Quoted 46 lines · Mark McLoughlin
Quoted 13 lines · Rusty Russell
Quoted 11 lines · On Saturday 06 December 2008 01:37:06 Mark McLoughlin wrote:
Another example of a lack of an explicit dependency causing problems is Fedora's mkinitrd having this hack:
if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fiwhich basically says "if this is a virtio device, don't forget to include
virtio_pciin the initrd too!". Now, mkinitrd is full of hacks, but this is a particularly unusual one.Quoted 6 lines
Um, I don't know what this does, sorry.
I have no idea how Fedora chooses what to put in an initrd; I can't think of a sensible way of deciding what goes in and what doesn't other than lists and heuristics.
Fedora's mkinitrd creates an initrd suitable to boot the machine you run mkinitrd on, rather than creating an initrd suitable to boot any machine.
So, it goes "ah, / is mounted from
/dev/vda, we need to includevirtio_blkand it's dependencies". It does that in a generic way that works well for most setups:1) Find the device name (e.g. vda) below
/sys/block2) Follow the 'device' link to e.g.
/sys/devices/virtio-pci/virtio13) Find the module need for this through either 'modalias' or the 'driver/module' symlink
4) Use modprobe to list any dependencies of that module
Clearly, virtio-pci won't be pulled in by any of this so we've added a hack to say "oh, it's a virtio device, let's include
virtio_pcijust in case".It's not even the case that mkinitrd needs to know how to include the the module for the bus, because in our case that's virtio.ko ... we've pretty effectively hidden the the bus *implementation* from userspace.
Quoted 6 lines
Quoted 4 lines
I don't think this is worth wasting too much time fixing, that's why I'm thinking we should just make
virtio_pcibuilt-in by default withCONFIG_KVM_GUEST.What if we have multiple virtio transports?
I don't think that's so much an an issue (just build in any transport supported by KVM), but rather that you might build a non-pv_ops kernel to run on QEMU which would benefit from using virtio drivers ...
Quoted 4 lines
Is there a way that we can
expose the relationship with virtio-blk and virtio-pci in sysfs? We have a struct device for the PCI device, it's just a matter of making the link visible.It feels a bit like busy work to generalise this since only
virtio_pcican be built as a module, but here's a patch.The mkinitrd hack turns into:
# Handle finding virtio bus implementations if [ -L ./virtio_module ] ; then
findmodule $(basename $(readlink ./virtio_module))
else if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fi; fiQuoted 4 lines
Quoted 1 line
[PATCH] virtio: add a '
virtio_module' sysfs symlinkDoesn't the device have a "driver" link already? If yes, the driver it points to should have a "module" link.
The virtio bus is an abstraction that has several different backend implementations - currently virtio-pci, lguest and kvm-s390.
Quoted 8 lines
So yes, the driver/module link gives us the device driver, but the
virtio_modulelink is to the virtio bus driver (aka implementation, transport, backend, ...):$> basename $(readlink
virtio_module)
virtio_pci
$> basename $(readlink driver/module)
virtio_netI see. But why not just call it "module", like we do in all other places, when it points to
/sys/module/.To find dependent modules, you would walk up the chain of parents, and include everything that is found by looking for "driver/module" and "module" links?
Quoted 5 lines
Quoted 1 line
Wouldn't that make it completely generic, without any virtio specific hacks?
Yeah, that sounds much better - a minor detail is that it'd be better to hang the symlink off each virtio implementation's root object rather than off each device.
Sounds good, if the devices below can never be from different modules at the same time.
Quoted 3 lines
To that end, I've hacked up
register_virtio_root_device()which fixes the fact that we statically allocate root objects and gives us a sane place to add this generic symlink.
Fine.
Quoted 4 lines
It might make sense to add this to the core, though - e.g.
device_register_root()- and that would also allow us use the same approach asmodule_add_driver()to add the module symlink for built-in modules.
Sure, I see no problem moving that over when things work out as expected.
Looks all fine from a short look over it. Also thanks for converting to allocated struct device, and the bus_id conversion.
Kay
Re: [PATCH 0/6] Clean up virtio device object handling [was Re: [PATCH] virtio: make PCI devices take a virtio_pci module ref]
In reply to Mark McLoughlinQuoted 106 lines · Mark McLoughlin
(Moved from kvm@vger to virtualization@linux-foundation, changed subject, cleaned up cc list)
Quoted 103 lines · Kay Sievers
Quoted 86 lines · Mark McLoughlin
Quoted 77 lines · Kay Sievers
Quoted 76 lines · Mark McLoughlin
Quoted 47 lines · Anthony Liguori
Quoted 46 lines · Mark McLoughlin
Quoted 13 lines · Rusty Russell
Quoted 11 lines · On Saturday 06 December 2008 01:37:06 Mark McLoughlin wrote:
Another example of a lack of an explicit dependency causing problems is Fedora's mkinitrd having this hack:
if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fiwhich basically says "if this is a virtio device, don't forget to include
virtio_pciin the initrd too!". Now, mkinitrd is full of hacks, but this is a particularly unusual one.Quoted 6 lines
Um, I don't know what this does, sorry.
I have no idea how Fedora chooses what to put in an initrd; I can't think of a sensible way of deciding what goes in and what doesn't other than lists and heuristics.
Fedora's mkinitrd creates an initrd suitable to boot the machine you run mkinitrd on, rather than creating an initrd suitable to boot any machine.
So, it goes "ah, / is mounted from
/dev/vda, we need to includevirtio_blkand it's dependencies". It does that in a generic way that works well for most setups:1) Find the device name (e.g. vda) below
/sys/block2) Follow the 'device' link to e.g.
/sys/devices/virtio-pci/virtio13) Find the module need for this through either 'modalias' or the 'driver/module' symlink
4) Use modprobe to list any dependencies of that module
Clearly, virtio-pci won't be pulled in by any of this so we've added a hack to say "oh, it's a virtio device, let's include
virtio_pcijust in case".It's not even the case that mkinitrd needs to know how to include the the module for the bus, because in our case that's virtio.ko ... we've pretty effectively hidden the the bus *implementation* from userspace.
Quoted 6 lines
Quoted 4 lines
I don't think this is worth wasting too much time fixing, that's why I'm thinking we should just make
virtio_pcibuilt-in by default withCONFIG_KVM_GUEST.What if we have multiple virtio transports?
I don't think that's so much an an issue (just build in any transport supported by KVM), but rather that you might build a non-pv_ops kernel to run on QEMU which would benefit from using virtio drivers ...
Quoted 4 lines
Is there a way that we can
expose the relationship with virtio-blk and virtio-pci in sysfs? We have a struct device for the PCI device, it's just a matter of making the link visible.It feels a bit like busy work to generalise this since only
virtio_pcican be built as a module, but here's a patch.The mkinitrd hack turns into:
# Handle finding virtio bus implementations if [ -L ./virtio_module ] ; then
findmodule $(basename $(readlink ./virtio_module))
else if echo $PWD | grep -q /virtio-pci/ ; then
findmodulevirtio_pci
fi; fiQuoted 4 lines
Quoted 1 line
[PATCH] virtio: add a '
virtio_module' sysfs symlinkDoesn't the device have a "driver" link already? If yes, the driver it points to should have a "module" link.
The virtio bus is an abstraction that has several different backend implementations - currently virtio-pci, lguest and kvm-s390.
Quoted 8 lines
So yes, the driver/module link gives us the device driver, but the
virtio_modulelink is to the virtio bus driver (aka implementation, transport, backend, ...):$> basename $(readlink
virtio_module)
virtio_pci
$> basename $(readlink driver/module)
virtio_netI see. But why not just call it "module", like we do in all other places, when it points to
/sys/module/.To find dependent modules, you would walk up the chain of parents, and include everything that is found by looking for "driver/module" and "module" links?
Quoted 5 lines
Quoted 1 line
Wouldn't that make it completely generic, without any virtio specific hacks?
Yeah, that sounds much better - a minor detail is that it'd be better to hang the symlink off each virtio implementation's root object rather than off each device.
Sounds good, if the devices below can never be from different modules at the same time.
Quoted 3 lines
To that end, I've hacked up
register_virtio_root_device()which fixes the fact that we statically allocate root objects and gives us a sane place to add this generic symlink.
Fine.
Quoted 4 lines
It might make sense to add this to the core, though - e.g.
device_register_root()- and that would also allow us use the same approach asmodule_add_driver()to add the module symlink for built-in modules.
Sure, I see no problem moving that over when things work out as expected.
Looks all fine from a short look over it. Also thanks for converting to allocated struct device, and the bus_id conversion.
Kay
Re: [PATCH 5/6] kvm-s390: use register_virtio_root_device()
In reply to Mark McLoughlinAm Mittwoch, 10. Dezember 2008 schrieb Mark McLoughlin:
Quoted 3 lines
This is basically a no-op change, since it does exactly the same thing as
s390_root_dev_register()when the caller isn't a module.
Ok, I gave it a short test and it seems to work.
Some comments: I agree with your comment in patch0, that a generic device_register_root() function might be useful.
Quoted 2 lines
drivers/s390/kvm/kvm_virtio.c +0
-0
[...]
Quoted 2 lines
drivers/s390/kvm/kvm_virtio.c +1
-1- kvm_root =s390_root_dev_register ("kvm_s390" ); + kvm_root =register_virtio_root_device ("kvm_s390" );
[...]
drivers/s390/kvm/kvm_virtio.c static int __init kvm_devices_init(void) · line 347
Quoted 2 lines
drivers/s390/kvm/kvm_virtio.c +1
-1-s390_root_dev_unregister (kvm_root); +unregister_virtio_root_device (kvm_root);
You can now remove the include <asm/s390_rdev.h>
Re: [PATCH 5/6] kvm-s390: use register_virtio_root_device()
In reply to Mark McLoughlinAm Mittwoch, 10. Dezember 2008 schrieb Mark McLoughlin:
Quoted 3 lines
This is basically a no-op change, since it does exactly the same thing as
s390_root_dev_register()when the caller isn't a module.
Ok, I gave it a short test and it seems to work.
Some comments: I agree with your comment in patch0, that a generic device_register_root() function might be useful.
Quoted 2 lines
drivers/s390/kvm/kvm_virtio.c +0
-0
[...]
Quoted 2 lines
drivers/s390/kvm/kvm_virtio.c +1
-1- kvm_root =s390_root_dev_register ("kvm_s390" ); + kvm_root =register_virtio_root_device ("kvm_s390" );
[...]
drivers/s390/kvm/kvm_virtio.c static int __init kvm_devices_init(void) · line 347
Quoted 2 lines
drivers/s390/kvm/kvm_virtio.c +1
-1-s390_root_dev_unregister (kvm_root); +unregister_virtio_root_device (kvm_root);
You can now remove the include <asm/s390_rdev.h>
Re: [PATCH 5/6] kvm-s390: use register_virtio_root_device()
Quoted 8 lines · Christian Borntraeger
Am Mittwoch, 10. Dezember 2008 schrieb Mark McLoughlin:
Quoted 3 lines
This is basically a no-op change, since it does exactly the same thing as
s390_root_dev_register()when the caller isn't a module.Ok, I gave it a short test and it seems to work.
Some comments: I agree with your comment in patch0, that a genericdevice_register_root()function might be useful.
Indeed, if this is a simple replacement, we want a generic function. I'll take a look at the patches.
Quoted 11 lines
Quoted 3 lines
drivers/s390/kvm/kvm_virtio.c +0
-0[...]
Quoted 2 lines
drivers/s390/kvm/kvm_virtio.c +1
-1- kvm_root =s390_root_dev_register ("kvm_s390" ); + kvm_root =register_virtio_root_device ("kvm_s390" );[...]
drivers/s390/kvm/kvm_virtio.c static int __init kvm_devices_init(void) · line 347
Quoted 2 lines
drivers/s390/kvm/kvm_virtio.c +1
-1-s390_root_dev_unregister (kvm_root); +unregister_virtio_root_device (kvm_root);You can now remove the include <
asm/s390_rdev.h>
Re: [PATCH 2/6] virtio: add register_virtio_root_device()
In reply to Mark McLoughlinQuoted 8 lines · Mark McLoughlin
Add a function to allocate a root device object to group the devices from a given virtio implementation.
Also add a 'module' sysfs symlink to allow so that userspace can generically determine which virtio implementation a device is associated with. This will be used by Fedora mkinitrd to generically determine e.g. that
virtio_pciis needed to mount a given root filesystem.
Nothing about this is really virtio-specific (just as s390_root_dev_register() is not really s390-specific), and a 'module' symlink doesn't really hurt in a generic implementation, even if it is unneeded. I'm voting to put this in some generic, always built-in code (or have the users select it) so we could also use it from s390.
Quoted 34 lines
Signed-off-by Mark McLoughlin <[email protected]>--- drivers/virtio/virtio.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/virtio.h | 10 ++++++ 2 files changed, 81 insertions(+), 0 deletions(-)drivers/virtio/virtio.c +12
-0@@ -1,6 +1,7 @@#include <linux/virtio.h> #include <linux/spinlock.h> #include <linux/virtio_config.h> +#include <linux/err.h> /* Unique numbering for virtio devices. */ static unsigned int dev_index;@@ -200,6 +201,76 @@ void unregister_virtio_device(struct virtio_device *dev) }EXPORT_SYMBOL_GPL (unregister_virtio_device); +/* A root device for virtio devices from a given backend. This makes them +* appear as /sys/devices/{name}/0,1,2 not /sys/devices/0,1,2. It also allows +* us to have a /sys/devices/{name}/module symlink to the backend module. */ +struct virtio_root_device +{ +struct device dev; +struct module *owner; +}; + +static struct virtio_root_device *to_virtio_root (struct device *dev) +{
drivers/virtio/virtio.c void unregister_virtio_device(struct virtio_device *dev) · line 224
Quoted 10 lines
drivers/virtio/virtio.c +10
-0+ return container_of(dev, struct virtio_root_device, dev); +} + +static void release_virtio_root_device (struct device *dev) +{ +struct virtio_root_device *root =to_virtio_root (dev); +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" ); +kfree (root); +}
Can this code be a module? If yes, move the release callback to a build-in as there are races with release-functions in modules.
Quoted 11 lines
drivers/virtio/virtio.c +11
-0+ +struct device *__register_virtio_root_device (const char *name, +struct module *owner) +{ +struct virtio_root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct virtio_root_device ),GFP_KERNEL ); +if (!root) + goto out; +
drivers/virtio/virtio.c void unregister_virtio_device(struct virtio_device *dev) · line 245
Quoted 10 lines
drivers/virtio/virtio.c +10
-0+ err =dev_set_name (&root->dev, name); +if (err) + goto free_root; + + err =device_register (&root->dev); +if (err) + goto free_root; + + root->dev.parent =NULL ; + root->dev.release = release_virtio_root_device;
You must set ->release before calling device_register(), and setting the parent is unneeded.
Quoted 7 lines
drivers/virtio/virtio.c +7
-0+ +if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) { +device_unregister (&root->dev);
drivers/virtio/virtio.c void unregister_virtio_device(struct virtio_device *dev) · line 262
Quoted 10 lines
drivers/virtio/virtio.c +10
-0+return ERR_PTR (err); + } + + root->owner = owner; + } + +return &root->dev; + +free_root: +kfree (root);
You need to call device_put() if you called device_register().
Quoted 37 lines
drivers/virtio/virtio.c +11
-0+out: +return ERR_PTR (err); +} +EXPORT_SYMBOL_GPL (__register_virtio_root_device); + +void unregister_virtio_root_device (struct device *root) +{ +device_unregister (root); +} +EXPORT_SYMBOL_GPL (unregister_virtio_root_device); +static int virtio_init (void ) {if (bus_register (&virtio_bus) !=0 )include/linux/virtio.h +10
-0@@ -93,6 +93,16 @@ struct virtio_deviceint register_virtio_device (struct virtio_device *dev);void unregister_virtio_device (struct virtio_device *dev); +/* A root device is a dummy device used to group virtio devices from each +* implementation. */ +struct device *__register_virtio_root_device (const char *name, +struct module *owner); +static inline struct device *register_virtio_root_device (const char *name) +{ +return __register_virtio_root_device (name,THIS_MODULE ); +} +void unregister_virtio_root_device (struct device *root); +/** * virtio_driver - operations for a virtio I/O driver * @driver: underlying device driver (populate name and owner). Signature · 1 line
1.5.4.3
Re: [PATCH 2/6] virtio: add register_virtio_root_device()
In reply to Mark McLoughlinQuoted 8 lines · Mark McLoughlin
Add a function to allocate a root device object to group the devices from a given virtio implementation.
Also add a 'module' sysfs symlink to allow so that userspace can generically determine which virtio implementation a device is associated with. This will be used by Fedora mkinitrd to generically determine e.g. that
virtio_pciis needed to mount a given root filesystem.
Nothing about this is really virtio-specific (just as s390_root_dev_register() is not really s390-specific), and a 'module' symlink doesn't really hurt in a generic implementation, even if it is unneeded. I'm voting to put this in some generic, always built-in code (or have the users select it) so we could also use it from s390.
Quoted 34 lines
Signed-off-by Mark McLoughlin <[email protected]>--- drivers/virtio/virtio.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/virtio.h | 10 ++++++ 2 files changed, 81 insertions(+), 0 deletions(-)drivers/virtio/virtio.c +12
-0@@ -1,6 +1,7 @@#include <linux/virtio.h> #include <linux/spinlock.h> #include <linux/virtio_config.h> +#include <linux/err.h> /* Unique numbering for virtio devices. */ static unsigned int dev_index;@@ -200,6 +201,76 @@ void unregister_virtio_device(struct virtio_device *dev) }EXPORT_SYMBOL_GPL (unregister_virtio_device); +/* A root device for virtio devices from a given backend. This makes them +* appear as /sys/devices/{name}/0,1,2 not /sys/devices/0,1,2. It also allows +* us to have a /sys/devices/{name}/module symlink to the backend module. */ +struct virtio_root_device +{ +struct device dev; +struct module *owner; +}; + +static struct virtio_root_device *to_virtio_root (struct device *dev) +{
drivers/virtio/virtio.c void unregister_virtio_device(struct virtio_device *dev) · line 224
Quoted 10 lines
drivers/virtio/virtio.c +10
-0+ return container_of(dev, struct virtio_root_device, dev); +} + +static void release_virtio_root_device (struct device *dev) +{ +struct virtio_root_device *root =to_virtio_root (dev); +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" ); +kfree (root); +}
Can this code be a module? If yes, move the release callback to a build-in as there are races with release-functions in modules.
Quoted 11 lines
drivers/virtio/virtio.c +11
-0+ +struct device *__register_virtio_root_device (const char *name, +struct module *owner) +{ +struct virtio_root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct virtio_root_device ),GFP_KERNEL ); +if (!root) + goto out; +
drivers/virtio/virtio.c void unregister_virtio_device(struct virtio_device *dev) · line 245
Quoted 10 lines
drivers/virtio/virtio.c +10
-0+ err =dev_set_name (&root->dev, name); +if (err) + goto free_root; + + err =device_register (&root->dev); +if (err) + goto free_root; + + root->dev.parent =NULL ; + root->dev.release = release_virtio_root_device;
You must set ->release before calling device_register(), and setting the parent is unneeded.
Quoted 7 lines
drivers/virtio/virtio.c +7
-0+ +if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) { +device_unregister (&root->dev);
drivers/virtio/virtio.c void unregister_virtio_device(struct virtio_device *dev) · line 262
Quoted 10 lines
drivers/virtio/virtio.c +10
-0+return ERR_PTR (err); + } + + root->owner = owner; + } + +return &root->dev; + +free_root: +kfree (root);
You need to call device_put() if you called device_register().
Quoted 37 lines
drivers/virtio/virtio.c +11
-0+out: +return ERR_PTR (err); +} +EXPORT_SYMBOL_GPL (__register_virtio_root_device); + +void unregister_virtio_root_device (struct device *root) +{ +device_unregister (root); +} +EXPORT_SYMBOL_GPL (unregister_virtio_root_device); +static int virtio_init (void ) {if (bus_register (&virtio_bus) !=0 )include/linux/virtio.h +10
-0@@ -93,6 +93,16 @@ struct virtio_deviceint register_virtio_device (struct virtio_device *dev);void unregister_virtio_device (struct virtio_device *dev); +/* A root device is a dummy device used to group virtio devices from each +* implementation. */ +struct device *__register_virtio_root_device (const char *name, +struct module *owner); +static inline struct device *register_virtio_root_device (const char *name) +{ +return __register_virtio_root_device (name,THIS_MODULE ); +} +void unregister_virtio_root_device (struct device *root); +/** * virtio_driver - operations for a virtio I/O driver * @driver: underlying device driver (populate name and owner). Signature · 1 line
1.5.4.3
Re: [PATCH 2/6] virtio: add register_virtio_root_device()
Quoted 12 lines · Cornelia Huck
Quoted 8 lines · Mark McLoughlin
Add a function to allocate a root device object to group the devices from a given virtio implementation.
Also add a 'module' sysfs symlink to allow so that userspace can generically determine which virtio implementation a device is associated with. This will be used by Fedora mkinitrd to generically determine e.g. that
virtio_pciis needed to mount a given root filesystem.
Quoted 5 lines
Nothing about this is really virtio-specific (just as
s390_root_dev_register()is not really s390-specific), and a 'module' symlink doesn't really hurt in a generic implementation, even if it is unneeded. I'm voting to put this in some generic, always built-in code (or have the users select it) so we could also use it from s390.
Okay, coming up ...
Quoted 38 lines
Quoted 38 lines
Signed-off-by Mark McLoughlin <[email protected]>--- drivers/virtio/virtio.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/virtio.h | 10 ++++++ 2 files changed, 81 insertions(+), 0 deletions(-)drivers/virtio/virtio.c +17
-0@@ -1,6 +1,7 @@#include <linux/virtio.h> #include <linux/spinlock.h> #include <linux/virtio_config.h> +#include <linux/err.h> /* Unique numbering for virtio devices. */ static unsigned int dev_index;@@ -200,6 +201,76 @@ void unregister_virtio_device(struct virtio_device *dev) }EXPORT_SYMBOL_GPL (unregister_virtio_device); +/* A root device for virtio devices from a given backend. This makes them +* appear as /sys/devices/{name}/0,1,2 not /sys/devices/0,1,2. It also allows +* us to have a /sys/devices/{name}/module symlink to the backend module. */ +struct virtio_root_device +{ +struct device dev; +struct module *owner; +}; + +static struct virtio_root_device *to_virtio_root (struct device *dev) +{ + return container_of(dev, struct virtio_root_device, dev); +} + +static void release_virtio_root_device (struct device *dev) +{
Quoted 8 lines
drivers/virtio/virtio.c void unregister_virtio_device(struct virtio_device *dev) · line 224
Quoted 5 lines
drivers/virtio/virtio.c +5
-0+struct virtio_root_device *root =to_virtio_root (dev); +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" ); +kfree (root); +}Can this code be a module? If yes, move the release callback to a build-in as there are races with release-functions in modules.
Not sure I fully understand the issue here, but it won't be an problem with it if we move to driver core.
Quoted 15 lines
Quoted 15 lines
drivers/virtio/virtio.c +15
-0+struct device *__register_virtio_root_device (const char *name, +struct module *owner) +{ +struct virtio_root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct virtio_root_device ),GFP_KERNEL ); +if (!root) + goto out; + + err =dev_set_name (&root->dev, name); +if (err) + goto free_root; + + err =device_register (&root->dev);
Quoted 8 lines
drivers/virtio/virtio.c void unregister_virtio_device(struct virtio_device *dev) · line 245
Quoted 5 lines
drivers/virtio/virtio.c +5
-0+if (err) + goto free_root; + + root->dev.parent =NULL ; + root->dev.release = release_virtio_root_device;You must set ->release before calling
device_register(), and setting the parent is unneeded.
Okay.
Quoted 10 lines
Quoted 10 lines
drivers/virtio/virtio.c +10
-0+if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) { +device_unregister (&root->dev); +return ERR_PTR (err); + } + + root->owner = owner;
Quoted 8 lines
drivers/virtio/virtio.c void unregister_virtio_device(struct virtio_device *dev) · line 262
Quoted 6 lines
drivers/virtio/virtio.c +6
-0+ } + +return &root->dev; + +free_root: +kfree (root);You need to call
device_put()if you calleddevice_register().
Oh, I missed that subtlety. So the rules are:
1) To release before calling device_register(), use kfree()
2) To release if device_register() failed, put_device()
3) To release once device_register() succeeds, device_unregister()
Cheers,
Mark.
PATCH 1/4 driver core: add root_device_register()
In reply to Mark McLoughlinAdd support for allocating root device objects which group device objects under /sys/devices directories.
Also add a sysfs 'module' symlink which points to the owner of the root device object. This will be used in virtio to allow userspace to determine which virtio bus implementation a given device is associated with.
--- drivers/base/core.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 11 ++++++ 2 files changed, 99 insertions(+), 0 deletions(-)
drivers/base/core.c +88 -0
@@ -1196,6 +1196,94 @@ EXPORT_SYMBOL_GPL(put_device);EXPORT_SYMBOL_GPL (device_create_file);EXPORT_SYMBOL_GPL (device_remove_file); +struct root_device +{ +struct device dev; +struct module *owner; +}; + +static void root_device_release (struct device *dev) +{ + struct root_device *root = container_of(dev, struct root_device, dev); + +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" ); + +kfree (root); +} + +/** +* __root_device_register - allocate and register a root device +* @name: root device name +* @owner: owner module of the root device, usually THIS_MODULE +* +* This function allocates a root device and registers it +* using device_register(). In order to free the returned +* device, use root_device_unregister(). +* +* Root devices are dummy devices which allow other devices +* to be grouped under /sys/devices. Use this function to +* allocate a root device and then use it as the parent of +* any device which should appear under /sys/devices/{name} +* +* The /sys/devices/{name} directory will also contain a +* 'module' symlink which points to the @owner directory +* in sysfs. +*/ +struct device *__root_device_register (const char *name,struct module *owner) +{ +struct root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct root_device ),GFP_KERNEL ); +if (!root) +return ERR_PTR (err); + + err =dev_set_name (&root->dev, name); +if (err) { +kfree (root); +return ERR_PTR (err); + } + + root->dev.release = root_device_release; + + err =device_register (&root->dev); +if (err) { +put_device (&root->dev); +return ERR_PTR (err); + } + +if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) {; +device_unregister (&root->dev); +return ERR_PTR (err); + } + root->owner = owner; + } + +return &root->dev; +} +EXPORT_SYMBOL_GPL (__root_device_register); + +/** +* root_device_unregister - unregister and free a root device +* @root: device going away. +* +* We simply release @root using device_unregister(). If @root +* has a reference count of one, the device will be freed +* after it has been unregistered. Otherwise, the structure +* will stick around until the final reference is dropped +* using put_device(). +*/ +void root_device_unregister (struct device *root) +{ +device_unregister (root); +} +EXPORT_SYMBOL_GPL (root_device_unregister); +static void device_create_release (struct device *dev) {
include/linux/device.h +11 -0
@@ -483,6 +483,17 @@ extern int device_rename(struct device *dev, char *new_name);extern int device_move (struct device *dev,struct device *new_parent);/* +* Root device objects for grouping under /sys/devices +*/ +extern struct device *__root_device_register (const char *name, +struct module *owner); +static inline struct device *root_device_register (const char *name) +{ +return __root_device_register (name,THIS_MODULE ); +} +extern void root_device_unregister (struct device *root); + +/* * Manual binding of a device to driver. See drivers/base/bus.c * for information on use. */
Signature · 1 line
1.5.4.3
PATCH 3/4 lguest: do not statically allocate root device
In reply to Mark McLoughlinWe shouldn't be statically allocating the root device object, so dynamically allocate it using root_device_register() instead.
--- drivers/lguest/lguest_device.c | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-)
drivers/lguest/lguest_device.c +4 -6
@@ -321,10 +321,7 @@ static struct virtio_config_ops lguest_config_ops = {/* The root device for the lguest virtio devices. This makes them appear as * /sys/devices/lguest/0,1,2 not /sys/devices/0,1,2. */ -static struct device lguest_root = { - .parent =NULL , - .bus_id ="lguest" , -}; +static struct device *lguest_root;/*D:120 This is the core of the lguest bus: actually adding a new device. * It's a separate function because it's neater that way, and because an
@@ -351,7 +348,7 @@ static void add_lguest_device(struct lguest_device_desc *d, }/* This devices' parent is the lguest/ dir. */ - ldev->vdev.dev.parent = &lguest_root; + ldev->vdev.dev.parent = lguest_root;/* We have a unique device index thanks to the dev_index counter. */ ldev->vdev.id.device = d->type;/* We have a simple set of routines for querying the device's
@@ -407,7 +404,8 @@ static int __init lguest_devices_init(void)if (strcmp (pv_info.name,"lguest" ) !=0 )return 0 ; -if (device_register (&lguest_root) !=0 ) + lguest_root =root_device_register ("lguest" ); +if (IS_ERR (lguest_root))panic ("Could not register lguest root" );/* Devices are in a single page above top of "normal" mem */
Signature · 1 line
1.5.4.3
PATCH 2/4 virtio: do not statically allocate root device
In reply to Mark McLoughlinWe shouldn't be statically allocating the root device object, so dynamically allocate it using root_device_register() instead.
Also avoids this warning from 'rmmod virtio_pci':
Device 'virtio-pci' does not have a release() function, it is broken and must be fixed
--- drivers/virtio/virtio_pci.c | 17 +++++++---------- 1 files changed, 7 insertions(+), 10 deletions(-)
drivers/virtio/virtio_pci.c +7 -10
@@ -73,10 +73,7 @@ MODULE_DEVICE_TABLE(pci, virtio_pci_id_table);/* A PCI device has it's own struct device and so does a virtio device so * we create a place for the virtio devices to show up in sysfs. I think it * would make more sense for virtio to not insist on having it's own device. */ -static struct device virtio_pci_root = { - .parent =NULL , - .init_name ="virtio-pci" , -}; +static struct device *virtio_pci_root;/* Convert a generic virtio device to our structure */ static struct virtio_pci_device *to_vp_device (struct virtio_device *vdev)
@@ -343,7 +340,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,if (vp_dev ==NULL )return -ENOMEM ; - vp_dev->vdev.dev.parent = &virtio_pci_root; + vp_dev->vdev.dev.parent = virtio_pci_root; vp_dev->vdev.dev.release = virtio_pci_release_dev; vp_dev->vdev.config = &virtio_pci_config_ops; vp_dev->pci_dev = pci_dev;
@@ -437,13 +434,13 @@ static int __init virtio_pci_init(void) {int err; - err =device_register (&virtio_pci_root); -if (err) -return err; + virtio_pci_root =root_device_register ("virtio-pci" ); +if (IS_ERR (virtio_pci_root)) +return PTR_ERR (virtio_pci_root); err =pci_register_driver (&virtio_pci_driver);if (err) -device_unregister (&virtio_pci_root); +device_unregister (virtio_pci_root);return err; }
@@ -452,8 +449,8 @@ module_init(virtio_pci_init); static void __exit virtio_pci_exit(void) { -device_unregister (&virtio_pci_root);pci_unregister_driver (&virtio_pci_driver); +root_device_unregister (virtio_pci_root); }module_exit (virtio_pci_exit);
Signature · 1 line
1.5.4.3
PATCH 4/4 s390: remove s390_root_dev_*()
In reply to Mark McLoughlinReplace s390_root_dev_register() with root_device_register() etc.
--- arch/s390/include/asm/s390_rdev.h | 15 ----------- drivers/s390/Makefile | 2 +- drivers/s390/block/dcssblk.c | 11 +++---- drivers/s390/crypto/ap_bus.c | 7 ++--- drivers/s390/kvm/kvm_virtio.c | 5 +-- drivers/s390/net/cu3088.c | 7 ++--- drivers/s390/net/qeth_core_main.c | 7 ++--- drivers/s390/net/qeth_l2_main.c | 2 - drivers/s390/net/qeth_l3_main.c | 2 - drivers/s390/s390_rdev.c | 51 ------------------------------------- net/iucv/iucv.c | 5 +-- 11 files changed, 19 insertions(+), 95 deletions(-) delete mode 100644 arch/s390/include/asm/s390_rdev.h delete mode 100644 drivers/s390/s390_rdev.c
arch/s390/include/asm/s390_rdev.h deleted +0 -15
@@ -1,15 +0,0 @@ -/* -* include/asm-s390/ccwdev.h -* -* Copyright (C) 2002,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation -* Author(s): Cornelia Huck <[email protected]> -* Carsten Otte <[email protected]> -* -* Interface for s390 root device -*/ - -#ifndef _S390_RDEV_H_ -#define _S390_RDEV_H_ -extern struct device *s390_root_dev_register (const char *); -extern void s390_root_dev_unregister (struct device *); -#endif /* _S390_RDEV_H_ */
drivers/s390/Makefile +1 -1
@@ -4,7 +4,7 @@ CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w -obj-y += s390mach.o sysinfo.o s390_rdev.o +obj-y += s390mach.o sysinfo.o obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/ drivers-y += drivers/s390/built-in.o
drivers/s390/block/dcssblk.c +5 -6
@@ -15,7 +15,6 @@#include <asm/io.h> #include <linux/completion.h> #include <linux/interrupt.h> -#include <asm/s390_rdev.h> //#define DCSSBLK_DEBUG /* Debug messages on/off */ #define DCSSBLK_NAME "dcssblk"
@@ -951,7 +950,7 @@ dcssblk_check_params(void) static void __exitdcssblk_exit (void ) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);unregister_blkdev (dcssblk_major,DCSSBLK_NAME ); }
@@ -960,22 +959,22 @@ dcssblk_init(void) {int rc; - dcssblk_root_dev =s390_root_dev_register ("dcssblk" ); + dcssblk_root_dev =root_device_register ("dcssblk" );if (IS_ERR (dcssblk_root_dev))return PTR_ERR (dcssblk_root_dev); rc =device_create_file (dcssblk_root_dev, &dev_attr_add);if (rc) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } rc =device_create_file (dcssblk_root_dev, &dev_attr_remove);if (rc) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } rc =register_blkdev (0 ,DCSSBLK_NAME );if (rc <0 ) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } dcssblk_major = rc;
drivers/s390/crypto/ap_bus.c +3 -4
@@ -32,7 +32,6 @@#include <linux/notifier.h> #include <linux/kthread.h> #include <linux/mutex.h> -#include <asm/s390_rdev.h> #include <asm/reset.h> #include <linux/hrtimer.h> #include <linux/ktime.h>
@@ -1358,7 +1357,7 @@ int __init ap_module_init(void) }/* Create /sys/devices/ap. */ - ap_root_device =s390_root_dev_register ("ap" ); + ap_root_device =root_device_register ("ap" ); rc =IS_ERR (ap_root_device) ?PTR_ERR (ap_root_device) :0 ;if (rc) goto out_bus;
@@ -1401,7 +1400,7 @@ out_work:hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue); out_root: -s390_root_dev_unregister (ap_root_device); +root_device_unregister (ap_root_device); out_bus:while (i--)bus_remove_file (&ap_bus_type, ap_bus_attrs[i]);
@@ -1432,7 +1431,7 @@ void ap_module_exit(void)hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue);tasklet_kill (&ap_tasklet); -s390_root_dev_unregister (ap_root_device); +root_device_unregister (ap_root_device);while ((dev =bus_find_device (&ap_bus_type,NULL ,NULL , __ap_match_all))) {
drivers/s390/kvm/kvm_virtio.c +2 -3
@@ -24,7 +24,6 @@#include <asm/kvm_virtio.h> #include <asm/setup.h> #include <asm/s390_ext.h> -#include <asm/s390_rdev.h> #define VIRTIO_SUBCODE_64 0x0D00
@@ -335,7 +334,7 @@ static int __init kvm_devices_init(void)if (!MACHINE_IS_KVM )return -ENODEV ; - kvm_root =s390_root_dev_register ("kvm_s390" ); + kvm_root =root_device_register ("kvm_s390" );if (IS_ERR (kvm_root)) { rc =PTR_ERR (kvm_root);printk (KERN_ERR "Could not register kvm_s390 root device" );
@@ -344,7 +343,7 @@ static int __init kvm_devices_init(void) rc =vmem_add_mapping (real_memory_size,PAGE_SIZE );if (rc) { -s390_root_dev_unregister (kvm_root); +root_device_unregister (kvm_root);return rc; }
drivers/s390/net/cu3088.c +3 -4
@@ -25,7 +25,6 @@#include <linux/module.h> #include <linux/err.h> -#include <asm/s390_rdev.h> #include <asm/ccwdev.h> #include <asm/ccwgroup.h>
@@ -120,12 +119,12 @@ cu3088_init (void) {int rc; - cu3088_root_dev =s390_root_dev_register ("cu3088" ); + cu3088_root_dev =root_device_register ("cu3088" );if (IS_ERR (cu3088_root_dev))return PTR_ERR (cu3088_root_dev); rc =ccw_driver_register (&cu3088_driver);if (rc) -s390_root_dev_unregister (cu3088_root_dev); +root_device_unregister (cu3088_root_dev);return rc; }
@@ -134,7 +133,7 @@ static void __exitcu3088_exit (void) {ccw_driver_unregister (&cu3088_driver); -s390_root_dev_unregister (cu3088_root_dev); +root_device_unregister (cu3088_root_dev); }MODULE_DEVICE_TABLE (ccw,cu3088_ids);
drivers/s390/net/qeth_core_main.c +3 -4
@@ -21,7 +21,6 @@#include <asm/ebcdic.h> #include <asm/io.h> -#include <asm/s390_rdev.h> #include "qeth_core.h" #include "qeth_core_offl.h"
@@ -4465,7 +4464,7 @@ static int __init qeth_core_init(void) &driver_attr_group);if (rc) goto driver_err; - qeth_core_root_dev =s390_root_dev_register ("qeth" ); + qeth_core_root_dev =root_device_register ("qeth" ); rc =IS_ERR (qeth_core_root_dev) ?PTR_ERR (qeth_core_root_dev) :0 ;if (rc) goto register_err;
@@ -4479,7 +4478,7 @@ static int __init qeth_core_init(void)return 0 ; slab_err: -s390_root_dev_unregister (qeth_core_root_dev); +root_device_unregister (qeth_core_root_dev); register_err:driver_remove_file (&qeth_core_ccwgroup_driver.driver, &driver_attr_group);
@@ -4496,7 +4495,7 @@ out_err: static void __exit qeth_core_exit(void) { -s390_root_dev_unregister (qeth_core_root_dev); +root_device_unregister (qeth_core_root_dev);driver_remove_file (&qeth_core_ccwgroup_driver.driver, &driver_attr_group);ccwgroup_driver_unregister (&qeth_core_ccwgroup_driver);
drivers/s390/net/qeth_l2_main.c +0 -2
@@ -17,8 +17,6 @@#include <linux/mii.h> #include <linux/ip.h> -#include <asm/s390_rdev.h> -#include "qeth_core.h" #include "qeth_core_offl.h"
drivers/s390/net/qeth_l3_main.c +0 -2
@@ -23,8 +23,6 @@#include <net/ip.h> #include <net/arp.h> -#include <asm/s390_rdev.h> -#include "qeth_l3.h" #include "qeth_core_offl.h"
drivers/s390/s390_rdev.c deleted +0 -51
51 lines not on this page · raw message
net/iucv/iucv.c +2 -3
@@ -47,7 +47,6 @@#include <asm/ebcdic.h> #include <asm/io.h> #include <asm/s390_ext.h> -#include <asm/s390_rdev.h> #include <asm/smp.h> /*
@@ -1609,7 +1608,7 @@ static int __init iucv_init(void) rc =register_external_interrupt (0x4000 , iucv_external_interrupt);if (rc) goto out; - iucv_root =s390_root_dev_register ("iucv" ); + iucv_root =root_device_register ("iucv" );if (IS_ERR (iucv_root)) { rc =PTR_ERR (iucv_root); goto out_int;
@@ -1653,7 +1652,7 @@ out_free:kfree (iucv_irq_data[cpu]); iucv_irq_data[cpu] =NULL ; } -s390_root_dev_unregister (iucv_root); +root_device_unregister (iucv_root); out_int:unregister_external_interrupt (0x4000 , iucv_external_interrupt); out:
Signature · 1 line
1.5.4.3
Re: [PATCH 2/6] virtio: add register_virtio_root_device()
In reply to Cornelia HuckQuoted 12 lines · Cornelia Huck
Quoted 8 lines · Mark McLoughlin
Add a function to allocate a root device object to group the devices from a given virtio implementation.
Also add a 'module' sysfs symlink to allow so that userspace can generically determine which virtio implementation a device is associated with. This will be used by Fedora mkinitrd to generically determine e.g. that
virtio_pciis needed to mount a given root filesystem.
Quoted 5 lines
Nothing about this is really virtio-specific (just as
s390_root_dev_register()is not really s390-specific), and a 'module' symlink doesn't really hurt in a generic implementation, even if it is unneeded. I'm voting to put this in some generic, always built-in code (or have the users select it) so we could also use it from s390.
Okay, coming up ...
Quoted 38 lines
Quoted 38 lines
Signed-off-by Mark McLoughlin <[email protected]>--- drivers/virtio/virtio.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/virtio.h | 10 ++++++ 2 files changed, 81 insertions(+), 0 deletions(-)drivers/virtio/virtio.c +17
-0@@ -1,6 +1,7 @@#include <linux/virtio.h> #include <linux/spinlock.h> #include <linux/virtio_config.h> +#include <linux/err.h> /* Unique numbering for virtio devices. */ static unsigned int dev_index;@@ -200,6 +201,76 @@ void unregister_virtio_device(struct virtio_device *dev) }EXPORT_SYMBOL_GPL (unregister_virtio_device); +/* A root device for virtio devices from a given backend. This makes them +* appear as /sys/devices/{name}/0,1,2 not /sys/devices/0,1,2. It also allows +* us to have a /sys/devices/{name}/module symlink to the backend module. */ +struct virtio_root_device +{ +struct device dev; +struct module *owner; +}; + +static struct virtio_root_device *to_virtio_root (struct device *dev) +{ + return container_of(dev, struct virtio_root_device, dev); +} + +static void release_virtio_root_device (struct device *dev) +{
Quoted 8 lines
drivers/virtio/virtio.c void unregister_virtio_device(struct virtio_device *dev) · line 224
Quoted 5 lines
drivers/virtio/virtio.c +5
-0+struct virtio_root_device *root =to_virtio_root (dev); +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" ); +kfree (root); +}Can this code be a module? If yes, move the release callback to a build-in as there are races with release-functions in modules.
Not sure I fully understand the issue here, but it won't be an problem with it if we move to driver core.
Quoted 15 lines
Quoted 15 lines
drivers/virtio/virtio.c +15
-0+struct device *__register_virtio_root_device (const char *name, +struct module *owner) +{ +struct virtio_root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct virtio_root_device ),GFP_KERNEL ); +if (!root) + goto out; + + err =dev_set_name (&root->dev, name); +if (err) + goto free_root; + + err =device_register (&root->dev);
Quoted 8 lines
drivers/virtio/virtio.c void unregister_virtio_device(struct virtio_device *dev) · line 245
Quoted 5 lines
drivers/virtio/virtio.c +5
-0+if (err) + goto free_root; + + root->dev.parent =NULL ; + root->dev.release = release_virtio_root_device;You must set ->release before calling
device_register(), and setting the parent is unneeded.
Okay.
Quoted 10 lines
Quoted 10 lines
drivers/virtio/virtio.c +10
-0+if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) { +device_unregister (&root->dev); +return ERR_PTR (err); + } + + root->owner = owner;
Quoted 8 lines
drivers/virtio/virtio.c void unregister_virtio_device(struct virtio_device *dev) · line 262
Quoted 6 lines
drivers/virtio/virtio.c +6
-0+ } + +return &root->dev; + +free_root: +kfree (root);You need to call
device_put()if you calleddevice_register().
Oh, I missed that subtlety. So the rules are:
1) To release before calling device_register(), use kfree()
2) To release if device_register() failed, put_device()
3) To release once device_register() succeeds, device_unregister()
Cheers,
Mark.
Re: [PATCH 1/4] driver core: add root_device_register()
In reply to Mark McLoughlinQuoted 7 lines · Mark McLoughlin
Add support for allocating root device objects which group device objects under
/sys/devicesdirectories.Also add a sysfs 'module' symlink which points to the owner of the root device object. This will be used in virtio to allow userspace to determine which virtio bus implementation a given device is associated with.
I was just hacking up a similar patch :)
Quoted 17 lines
Signed-off-by Mark McLoughlin <[email protected]>--- drivers/base/core.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 11 ++++++ 2 files changed, 99 insertions(+), 0 deletions(-)drivers/base/core.c +2
-0@@ -1196,6 +1196,94 @@ EXPORT_SYMBOL_GPL(put_device);EXPORT_SYMBOL_GPL (device_create_file);EXPORT_SYMBOL_GPL (device_remove_file); +struct root_device +{
drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1210
Quoted 10 lines
drivers/base/core.c +10
-0+struct device dev; +struct module *owner; +}; + +static void root_device_release (struct device *dev) +{ + struct root_device *root = container_of(dev, struct root_device, dev); + +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" );
I'd rather remove the link before you unregister.
Quoted 11 lines
drivers/base/core.c +11
-0+ +kfree (root); +} + +/** +* __root_device_register - allocate and register a root device +* @name: root device name +* @owner: owner module of the root device, usually THIS_MODULE +* +* This function allocates a root device and registers it +* using device_register(). In order to free the returned
drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1231
Quoted 10 lines
drivers/base/core.c +10
-0+* device, use root_device_unregister(). +* +* Root devices are dummy devices which allow other devices +* to be grouped under /sys/devices. Use this function to +* allocate a root device and then use it as the parent of +* any device which should appear under /sys/devices/{name} +* +* The /sys/devices/{name} directory will also contain a +* 'module' symlink which points to the @owner directory +* in sysfs.
* Note: You probably want to use root_device_register().
Quoted 19 lines
drivers/base/core.c +19
-0+*/ +struct device *__root_device_register (const char *name,struct module *owner) +{ +struct root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct root_device ),GFP_KERNEL ); +if (!root) +return ERR_PTR (err); + + err =dev_set_name (&root->dev, name); +if (err) { +kfree (root); +return ERR_PTR (err); + } + + root->dev.release = root_device_release; + + err =device_register (&root->dev);
drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1260
Quoted 10 lines
drivers/base/core.c +10
-0+if (err) { +put_device (&root->dev); +return ERR_PTR (err); + } + +if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) {;
Stray ';'
Quoted 9 lines
drivers/base/core.c +9
-0+device_unregister (&root->dev); +return ERR_PTR (err); + } + root->owner = owner; + } + +return &root->dev; +} +EXPORT_SYMBOL_GPL (__root_device_register);
drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1279
Quoted 10 lines
drivers/base/core.c +10
-0+ +/** +* root_device_unregister - unregister and free a root device +* @root: device going away. +* +* We simply release @root using device_unregister(). If @root +* has a reference count of one, the device will be freed +* after it has been unregistered. Otherwise, the structure +* will stick around until the final reference is dropped +* using put_device().
I don't think you'll need to explain device handling here. How about this:
root_device_unregister - unregister a root device
@root: device going away
This function unregisters and cleans up a device that was created by root_device_register().
drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1282
Quoted 3 lines
drivers/base/core.c +3
-0+*/ +void root_device_unregister (struct device *root) +{
Clean up the symlink here.
Quoted 32 lines
drivers/base/core.c +4
-0+device_unregister (root); +} +EXPORT_SYMBOL_GPL (root_device_unregister); +static void device_create_release (struct device *dev) {include/linux/device.h +11
-0@@ -483,6 +483,17 @@ extern int device_rename(struct device *dev, char *new_name);extern int device_move (struct device *dev,struct device *new_parent);/* +* Root device objects for grouping under /sys/devices +*/ +extern struct device *__root_device_register (const char *name, +struct module *owner); +static inline struct device *root_device_register (const char *name) +{ +return __root_device_register (name,THIS_MODULE ); +} +extern void root_device_unregister (struct device *root); + +/* * Manual binding of a device to driver. See drivers/base/bus.c * for information on use. */ Signature · 1 line
1.5.4.3
Re: [PATCH 1/4] driver core: add root_device_register()
In reply to Mark McLoughlinQuoted 7 lines · Mark McLoughlin
Add support for allocating root device objects which group device objects under
/sys/devicesdirectories.Also add a sysfs 'module' symlink which points to the owner of the root device object. This will be used in virtio to allow userspace to determine which virtio bus implementation a given device is associated with.
I was just hacking up a similar patch :)
Quoted 17 lines
Signed-off-by Mark McLoughlin <[email protected]>--- drivers/base/core.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 11 ++++++ 2 files changed, 99 insertions(+), 0 deletions(-)drivers/base/core.c +2
-0@@ -1196,6 +1196,94 @@ EXPORT_SYMBOL_GPL(put_device);EXPORT_SYMBOL_GPL (device_create_file);EXPORT_SYMBOL_GPL (device_remove_file); +struct root_device +{
drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1210
Quoted 10 lines
drivers/base/core.c +10
-0+struct device dev; +struct module *owner; +}; + +static void root_device_release (struct device *dev) +{ + struct root_device *root = container_of(dev, struct root_device, dev); + +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" );
I'd rather remove the link before you unregister.
Quoted 11 lines
drivers/base/core.c +11
-0+ +kfree (root); +} + +/** +* __root_device_register - allocate and register a root device +* @name: root device name +* @owner: owner module of the root device, usually THIS_MODULE +* +* This function allocates a root device and registers it +* using device_register(). In order to free the returned
drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1231
Quoted 10 lines
drivers/base/core.c +10
-0+* device, use root_device_unregister(). +* +* Root devices are dummy devices which allow other devices +* to be grouped under /sys/devices. Use this function to +* allocate a root device and then use it as the parent of +* any device which should appear under /sys/devices/{name} +* +* The /sys/devices/{name} directory will also contain a +* 'module' symlink which points to the @owner directory +* in sysfs.
* Note: You probably want to use root_device_register().
Quoted 19 lines
drivers/base/core.c +19
-0+*/ +struct device *__root_device_register (const char *name,struct module *owner) +{ +struct root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct root_device ),GFP_KERNEL ); +if (!root) +return ERR_PTR (err); + + err =dev_set_name (&root->dev, name); +if (err) { +kfree (root); +return ERR_PTR (err); + } + + root->dev.release = root_device_release; + + err =device_register (&root->dev);
drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1260
Quoted 10 lines
drivers/base/core.c +10
-0+if (err) { +put_device (&root->dev); +return ERR_PTR (err); + } + +if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) {;
Stray ';'
Quoted 9 lines
drivers/base/core.c +9
-0+device_unregister (&root->dev); +return ERR_PTR (err); + } + root->owner = owner; + } + +return &root->dev; +} +EXPORT_SYMBOL_GPL (__root_device_register);
drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1279
Quoted 10 lines
drivers/base/core.c +10
-0+ +/** +* root_device_unregister - unregister and free a root device +* @root: device going away. +* +* We simply release @root using device_unregister(). If @root +* has a reference count of one, the device will be freed +* after it has been unregistered. Otherwise, the structure +* will stick around until the final reference is dropped +* using put_device().
I don't think you'll need to explain device handling here. How about this:
root_device_unregister - unregister a root device
@root: device going away
This function unregisters and cleans up a device that was created by root_device_register().
drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1282
Quoted 3 lines
drivers/base/core.c +3
-0+*/ +void root_device_unregister (struct device *root) +{
Clean up the symlink here.
Quoted 32 lines
drivers/base/core.c +4
-0+device_unregister (root); +} +EXPORT_SYMBOL_GPL (root_device_unregister); +static void device_create_release (struct device *dev) {include/linux/device.h +11
-0@@ -483,6 +483,17 @@ extern int device_rename(struct device *dev, char *new_name);extern int device_move (struct device *dev,struct device *new_parent);/* +* Root device objects for grouping under /sys/devices +*/ +extern struct device *__root_device_register (const char *name, +struct module *owner); +static inline struct device *root_device_register (const char *name) +{ +return __root_device_register (name,THIS_MODULE ); +} +extern void root_device_unregister (struct device *root); + +/* * Manual binding of a device to driver. See drivers/base/bus.c * for information on use. */ Signature · 1 line
1.5.4.3
Re: [PATCH 4/4] s390: remove s390_root_dev_*()
In reply to Mark McLoughlin(adding cc:s)
Quoted 1 line · Mark McLoughlin
Replace
s390_root_dev_register()withroot_device_register()etc.
Nice, one more special case generalized :) I'll give it a run.
Quoted 360 lines
Signed-off-by Mark McLoughlin <[email protected]>--- arch/s390/include/asm/s390_rdev.h | 15 ----------- drivers/s390/Makefile | 2 +- drivers/s390/block/dcssblk.c | 11 +++---- drivers/s390/crypto/ap_bus.c | 7 ++--- drivers/s390/kvm/kvm_virtio.c | 5 +-- drivers/s390/net/cu3088.c | 7 ++--- drivers/s390/net/qeth_core_main.c | 7 ++--- drivers/s390/net/qeth_l2_main.c | 2 - drivers/s390/net/qeth_l3_main.c | 2 - drivers/s390/s390_rdev.c | 51 ------------------------------------- net/iucv/iucv.c | 5 +-- 11 files changed, 19 insertions(+), 95 deletions(-) delete mode 100644 arch/s390/include/asm/s390_rdev.h delete mode 100644 drivers/s390/s390_rdev.carch/s390/include/asm/s390_rdev.h deleted +0
-15@@ -1,15 +0,0 @@ -/* -* include/asm-s390/ccwdev.h -* -* Copyright (C) 2002,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation -* Author(s): Cornelia Huck <[email protected]> -* Carsten Otte <[email protected]> -* -* Interface for s390 root device -*/ - -#ifndef _S390_RDEV_H_ -#define _S390_RDEV_H_ -extern struct device *s390_root_dev_register (const char *); -extern void s390_root_dev_unregister (struct device *); -#endif /* _S390_RDEV_H_ */ drivers/s390/Makefile +1
-1@@ -4,7 +4,7 @@ CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w -obj-y += s390mach.o sysinfo.o s390_rdev.o +obj-y += s390mach.o sysinfo.o obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/ drivers-y += drivers/s390/built-in.odrivers/s390/block/dcssblk.c +5
-6@@ -15,7 +15,6 @@#include <asm/io.h> #include <linux/completion.h> #include <linux/interrupt.h> -#include <asm/s390_rdev.h> //#define DCSSBLK_DEBUG /* Debug messages on/off */ #define DCSSBLK_NAME "dcssblk"@@ -951,7 +950,7 @@ dcssblk_check_params(void) static void __exitdcssblk_exit (void ) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);unregister_blkdev (dcssblk_major,DCSSBLK_NAME ); }@@ -960,22 +959,22 @@ dcssblk_init(void) {int rc; - dcssblk_root_dev =s390_root_dev_register ("dcssblk" ); + dcssblk_root_dev =root_device_register ("dcssblk" );if (IS_ERR (dcssblk_root_dev))return PTR_ERR (dcssblk_root_dev); rc =device_create_file (dcssblk_root_dev, &dev_attr_add);if (rc) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } rc =device_create_file (dcssblk_root_dev, &dev_attr_remove);if (rc) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } rc =register_blkdev (0 ,DCSSBLK_NAME );if (rc <0 ) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } dcssblk_major = rc;drivers/s390/crypto/ap_bus.c +3
-4@@ -32,7 +32,6 @@#include <linux/notifier.h> #include <linux/kthread.h> #include <linux/mutex.h> -#include <asm/s390_rdev.h> #include <asm/reset.h> #include <linux/hrtimer.h> #include <linux/ktime.h> @@ -1358,7 +1357,7 @@ int __init ap_module_init(void) }/* Create /sys/devices/ap. */ - ap_root_device =s390_root_dev_register ("ap" ); + ap_root_device =root_device_register ("ap" ); rc =IS_ERR (ap_root_device) ?PTR_ERR (ap_root_device) :0 ;if (rc) goto out_bus;@@ -1401,7 +1400,7 @@ out_work:hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue); out_root: -s390_root_dev_unregister (ap_root_device); +root_device_unregister (ap_root_device); out_bus:while (i--)bus_remove_file (&ap_bus_type, ap_bus_attrs[i]);@@ -1432,7 +1431,7 @@ void ap_module_exit(void)hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue);tasklet_kill (&ap_tasklet); -s390_root_dev_unregister (ap_root_device); +root_device_unregister (ap_root_device);while ((dev =bus_find_device (&ap_bus_type,NULL ,NULL , __ap_match_all))) {drivers/s390/kvm/kvm_virtio.c +2
-3@@ -24,7 +24,6 @@#include <asm/kvm_virtio.h> #include <asm/setup.h> #include <asm/s390_ext.h> -#include <asm/s390_rdev.h> #define VIRTIO_SUBCODE_64 0x0D00@@ -335,7 +334,7 @@ static int __init kvm_devices_init(void)if (!MACHINE_IS_KVM )return -ENODEV ; - kvm_root =s390_root_dev_register ("kvm_s390" ); + kvm_root =root_device_register ("kvm_s390" );if (IS_ERR (kvm_root)) { rc =PTR_ERR (kvm_root);printk (KERN_ERR "Could not register kvm_s390 root device" );@@ -344,7 +343,7 @@ static int __init kvm_devices_init(void) rc =vmem_add_mapping (real_memory_size,PAGE_SIZE );if (rc) { -s390_root_dev_unregister (kvm_root); +root_device_unregister (kvm_root);return rc; }drivers/s390/net/cu3088.c +3
-4@@ -25,7 +25,6 @@#include <linux/module.h> #include <linux/err.h> -#include <asm/s390_rdev.h> #include <asm/ccwdev.h> #include <asm/ccwgroup.h> @@ -120,12 +119,12 @@ cu3088_init (void) {int rc; - cu3088_root_dev =s390_root_dev_register ("cu3088" ); + cu3088_root_dev =root_device_register ("cu3088" );if (IS_ERR (cu3088_root_dev))return PTR_ERR (cu3088_root_dev); rc =ccw_driver_register (&cu3088_driver);if (rc) -s390_root_dev_unregister (cu3088_root_dev); +root_device_unregister (cu3088_root_dev);return rc; }@@ -134,7 +133,7 @@ static void __exitcu3088_exit (void) {ccw_driver_unregister (&cu3088_driver); -s390_root_dev_unregister (cu3088_root_dev); +root_device_unregister (cu3088_root_dev); }MODULE_DEVICE_TABLE (ccw,cu3088_ids);drivers/s390/net/qeth_core_main.c +3
-4@@ -21,7 +21,6 @@#include <asm/ebcdic.h> #include <asm/io.h> -#include <asm/s390_rdev.h> #include "qeth_core.h" #include "qeth_core_offl.h" @@ -4465,7 +4464,7 @@ static int __init qeth_core_init(void) &driver_attr_group);if (rc) goto driver_err; - qeth_core_root_dev =s390_root_dev_register ("qeth" ); + qeth_core_root_dev =root_device_register ("qeth" ); rc =IS_ERR (qeth_core_root_dev) ?PTR_ERR (qeth_core_root_dev) :0 ;if (rc) goto register_err;@@ -4479,7 +4478,7 @@ static int __init qeth_core_init(void)return 0 ; slab_err: -s390_root_dev_unregister (qeth_core_root_dev); +root_device_unregister (qeth_core_root_dev); register_err:driver_remove_file (&qeth_core_ccwgroup_driver.driver, &driver_attr_group);@@ -4496,7 +4495,7 @@ out_err: static void __exit qeth_core_exit(void) { -s390_root_dev_unregister (qeth_core_root_dev); +root_device_unregister (qeth_core_root_dev);driver_remove_file (&qeth_core_ccwgroup_driver.driver, &driver_attr_group);ccwgroup_driver_unregister (&qeth_core_ccwgroup_driver);drivers/s390/net/qeth_l2_main.c +0
-2@@ -17,8 +17,6 @@#include <linux/mii.h> #include <linux/ip.h> -#include <asm/s390_rdev.h> -#include "qeth_core.h" #include "qeth_core_offl.h" drivers/s390/net/qeth_l3_main.c +0
-2@@ -23,8 +23,6 @@#include <net/ip.h> #include <net/arp.h> -#include <asm/s390_rdev.h> -#include "qeth_l3.h" #include "qeth_core_offl.h" drivers/s390/s390_rdev.c deleted +0
-51@@ -1,51 +0,0 @@ -/* -* drivers/s390/s390_rdev.c -* s390 root device -* -* Copyright (C) 2002, 2005 IBM Deutschland Entwicklung GmbH, -* IBM Corporation -* Author(s): Cornelia Huck ([email protected]) -* Carsten Otte ([email protected]) -*/ - -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/device.h> -#include <asm/s390_rdev.h> - -static void -s390_root_dev_release (struct device *dev) -{ -kfree (dev); -} - -struct device * -s390_root_dev_register (const char *name) -{ -struct device *dev; -int ret; - -if (!strlen (name)) -return ERR_PTR (-EINVAL ); - dev =kzalloc (sizeof (struct device ),GFP_KERNEL ); -if (!dev) -return ERR_PTR (-ENOMEM ); -dev_set_name (dev, name); - dev->release = s390_root_dev_release; - ret =device_register (dev); -if (ret) { -kfree (dev); -return ERR_PTR (ret); - } -return dev; -} - -void -s390_root_dev_unregister (struct device *dev) -{ -if (dev) -device_unregister (dev); -} - -EXPORT_SYMBOL (s390_root_dev_register); -EXPORT_SYMBOL (s390_root_dev_unregister);net/iucv/iucv.c +2
-3@@ -47,7 +47,6 @@#include <asm/ebcdic.h> #include <asm/io.h> #include <asm/s390_ext.h> -#include <asm/s390_rdev.h> #include <asm/smp.h> /* @@ -1609,7 +1608,7 @@ static int __init iucv_init(void) rc =register_external_interrupt (0x4000 , iucv_external_interrupt);if (rc) goto out; - iucv_root =s390_root_dev_register ("iucv" ); + iucv_root =root_device_register ("iucv" );if (IS_ERR (iucv_root)) { rc =PTR_ERR (iucv_root); goto out_int;@@ -1653,7 +1652,7 @@ out_free:kfree (iucv_irq_data[cpu]); iucv_irq_data[cpu] =NULL ; } -s390_root_dev_unregister (iucv_root); +root_device_unregister (iucv_root); out_int:unregister_external_interrupt (0x4000 , iucv_external_interrupt); out:Signature · 1 line
1.5.4.3
Signature · 3 lines
Cornelia Huck Linux for zSeries Developer Tel.: +49-7031-16-4837, Mail: [email protected]
Re: [PATCH 4/4] s390: remove s390_root_dev_*()
In reply to Mark McLoughlin(adding cc:s)
Quoted 1 line · Mark McLoughlin
Replace
s390_root_dev_register()withroot_device_register()etc.
Nice, one more special case generalized :) I'll give it a run.
Quoted 360 lines
Signed-off-by Mark McLoughlin <[email protected]>--- arch/s390/include/asm/s390_rdev.h | 15 ----------- drivers/s390/Makefile | 2 +- drivers/s390/block/dcssblk.c | 11 +++---- drivers/s390/crypto/ap_bus.c | 7 ++--- drivers/s390/kvm/kvm_virtio.c | 5 +-- drivers/s390/net/cu3088.c | 7 ++--- drivers/s390/net/qeth_core_main.c | 7 ++--- drivers/s390/net/qeth_l2_main.c | 2 - drivers/s390/net/qeth_l3_main.c | 2 - drivers/s390/s390_rdev.c | 51 ------------------------------------- net/iucv/iucv.c | 5 +-- 11 files changed, 19 insertions(+), 95 deletions(-) delete mode 100644 arch/s390/include/asm/s390_rdev.h delete mode 100644 drivers/s390/s390_rdev.carch/s390/include/asm/s390_rdev.h deleted +0
-15@@ -1,15 +0,0 @@ -/* -* include/asm-s390/ccwdev.h -* -* Copyright (C) 2002,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation -* Author(s): Cornelia Huck <[email protected]> -* Carsten Otte <[email protected]> -* -* Interface for s390 root device -*/ - -#ifndef _S390_RDEV_H_ -#define _S390_RDEV_H_ -extern struct device *s390_root_dev_register (const char *); -extern void s390_root_dev_unregister (struct device *); -#endif /* _S390_RDEV_H_ */ drivers/s390/Makefile +1
-1@@ -4,7 +4,7 @@ CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w -obj-y += s390mach.o sysinfo.o s390_rdev.o +obj-y += s390mach.o sysinfo.o obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/ drivers-y += drivers/s390/built-in.odrivers/s390/block/dcssblk.c +5
-6@@ -15,7 +15,6 @@#include <asm/io.h> #include <linux/completion.h> #include <linux/interrupt.h> -#include <asm/s390_rdev.h> //#define DCSSBLK_DEBUG /* Debug messages on/off */ #define DCSSBLK_NAME "dcssblk"@@ -951,7 +950,7 @@ dcssblk_check_params(void) static void __exitdcssblk_exit (void ) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);unregister_blkdev (dcssblk_major,DCSSBLK_NAME ); }@@ -960,22 +959,22 @@ dcssblk_init(void) {int rc; - dcssblk_root_dev =s390_root_dev_register ("dcssblk" ); + dcssblk_root_dev =root_device_register ("dcssblk" );if (IS_ERR (dcssblk_root_dev))return PTR_ERR (dcssblk_root_dev); rc =device_create_file (dcssblk_root_dev, &dev_attr_add);if (rc) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } rc =device_create_file (dcssblk_root_dev, &dev_attr_remove);if (rc) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } rc =register_blkdev (0 ,DCSSBLK_NAME );if (rc <0 ) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } dcssblk_major = rc;drivers/s390/crypto/ap_bus.c +3
-4@@ -32,7 +32,6 @@#include <linux/notifier.h> #include <linux/kthread.h> #include <linux/mutex.h> -#include <asm/s390_rdev.h> #include <asm/reset.h> #include <linux/hrtimer.h> #include <linux/ktime.h> @@ -1358,7 +1357,7 @@ int __init ap_module_init(void) }/* Create /sys/devices/ap. */ - ap_root_device =s390_root_dev_register ("ap" ); + ap_root_device =root_device_register ("ap" ); rc =IS_ERR (ap_root_device) ?PTR_ERR (ap_root_device) :0 ;if (rc) goto out_bus;@@ -1401,7 +1400,7 @@ out_work:hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue); out_root: -s390_root_dev_unregister (ap_root_device); +root_device_unregister (ap_root_device); out_bus:while (i--)bus_remove_file (&ap_bus_type, ap_bus_attrs[i]);@@ -1432,7 +1431,7 @@ void ap_module_exit(void)hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue);tasklet_kill (&ap_tasklet); -s390_root_dev_unregister (ap_root_device); +root_device_unregister (ap_root_device);while ((dev =bus_find_device (&ap_bus_type,NULL ,NULL , __ap_match_all))) {drivers/s390/kvm/kvm_virtio.c +2
-3@@ -24,7 +24,6 @@#include <asm/kvm_virtio.h> #include <asm/setup.h> #include <asm/s390_ext.h> -#include <asm/s390_rdev.h> #define VIRTIO_SUBCODE_64 0x0D00@@ -335,7 +334,7 @@ static int __init kvm_devices_init(void)if (!MACHINE_IS_KVM )return -ENODEV ; - kvm_root =s390_root_dev_register ("kvm_s390" ); + kvm_root =root_device_register ("kvm_s390" );if (IS_ERR (kvm_root)) { rc =PTR_ERR (kvm_root);printk (KERN_ERR "Could not register kvm_s390 root device" );@@ -344,7 +343,7 @@ static int __init kvm_devices_init(void) rc =vmem_add_mapping (real_memory_size,PAGE_SIZE );if (rc) { -s390_root_dev_unregister (kvm_root); +root_device_unregister (kvm_root);return rc; }drivers/s390/net/cu3088.c +3
-4@@ -25,7 +25,6 @@#include <linux/module.h> #include <linux/err.h> -#include <asm/s390_rdev.h> #include <asm/ccwdev.h> #include <asm/ccwgroup.h> @@ -120,12 +119,12 @@ cu3088_init (void) {int rc; - cu3088_root_dev =s390_root_dev_register ("cu3088" ); + cu3088_root_dev =root_device_register ("cu3088" );if (IS_ERR (cu3088_root_dev))return PTR_ERR (cu3088_root_dev); rc =ccw_driver_register (&cu3088_driver);if (rc) -s390_root_dev_unregister (cu3088_root_dev); +root_device_unregister (cu3088_root_dev);return rc; }@@ -134,7 +133,7 @@ static void __exitcu3088_exit (void) {ccw_driver_unregister (&cu3088_driver); -s390_root_dev_unregister (cu3088_root_dev); +root_device_unregister (cu3088_root_dev); }MODULE_DEVICE_TABLE (ccw,cu3088_ids);drivers/s390/net/qeth_core_main.c +3
-4@@ -21,7 +21,6 @@#include <asm/ebcdic.h> #include <asm/io.h> -#include <asm/s390_rdev.h> #include "qeth_core.h" #include "qeth_core_offl.h" @@ -4465,7 +4464,7 @@ static int __init qeth_core_init(void) &driver_attr_group);if (rc) goto driver_err; - qeth_core_root_dev =s390_root_dev_register ("qeth" ); + qeth_core_root_dev =root_device_register ("qeth" ); rc =IS_ERR (qeth_core_root_dev) ?PTR_ERR (qeth_core_root_dev) :0 ;if (rc) goto register_err;@@ -4479,7 +4478,7 @@ static int __init qeth_core_init(void)return 0 ; slab_err: -s390_root_dev_unregister (qeth_core_root_dev); +root_device_unregister (qeth_core_root_dev); register_err:driver_remove_file (&qeth_core_ccwgroup_driver.driver, &driver_attr_group);@@ -4496,7 +4495,7 @@ out_err: static void __exit qeth_core_exit(void) { -s390_root_dev_unregister (qeth_core_root_dev); +root_device_unregister (qeth_core_root_dev);driver_remove_file (&qeth_core_ccwgroup_driver.driver, &driver_attr_group);ccwgroup_driver_unregister (&qeth_core_ccwgroup_driver);drivers/s390/net/qeth_l2_main.c +0
-2@@ -17,8 +17,6 @@#include <linux/mii.h> #include <linux/ip.h> -#include <asm/s390_rdev.h> -#include "qeth_core.h" #include "qeth_core_offl.h" drivers/s390/net/qeth_l3_main.c +0
-2@@ -23,8 +23,6 @@#include <net/ip.h> #include <net/arp.h> -#include <asm/s390_rdev.h> -#include "qeth_l3.h" #include "qeth_core_offl.h" drivers/s390/s390_rdev.c deleted +0
-51@@ -1,51 +0,0 @@ -/* -* drivers/s390/s390_rdev.c -* s390 root device -* -* Copyright (C) 2002, 2005 IBM Deutschland Entwicklung GmbH, -* IBM Corporation -* Author(s): Cornelia Huck ([email protected]) -* Carsten Otte ([email protected]) -*/ - -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/device.h> -#include <asm/s390_rdev.h> - -static void -s390_root_dev_release (struct device *dev) -{ -kfree (dev); -} - -struct device * -s390_root_dev_register (const char *name) -{ -struct device *dev; -int ret; - -if (!strlen (name)) -return ERR_PTR (-EINVAL ); - dev =kzalloc (sizeof (struct device ),GFP_KERNEL ); -if (!dev) -return ERR_PTR (-ENOMEM ); -dev_set_name (dev, name); - dev->release = s390_root_dev_release; - ret =device_register (dev); -if (ret) { -kfree (dev); -return ERR_PTR (ret); - } -return dev; -} - -void -s390_root_dev_unregister (struct device *dev) -{ -if (dev) -device_unregister (dev); -} - -EXPORT_SYMBOL (s390_root_dev_register); -EXPORT_SYMBOL (s390_root_dev_unregister);net/iucv/iucv.c +2
-3@@ -47,7 +47,6 @@#include <asm/ebcdic.h> #include <asm/io.h> #include <asm/s390_ext.h> -#include <asm/s390_rdev.h> #include <asm/smp.h> /* @@ -1609,7 +1608,7 @@ static int __init iucv_init(void) rc =register_external_interrupt (0x4000 , iucv_external_interrupt);if (rc) goto out; - iucv_root =s390_root_dev_register ("iucv" ); + iucv_root =root_device_register ("iucv" );if (IS_ERR (iucv_root)) { rc =PTR_ERR (iucv_root); goto out_int;@@ -1653,7 +1652,7 @@ out_free:kfree (iucv_irq_data[cpu]); iucv_irq_data[cpu] =NULL ; } -s390_root_dev_unregister (iucv_root); +root_device_unregister (iucv_root); out_int:unregister_external_interrupt (0x4000 , iucv_external_interrupt); out:Signature · 1 line
1.5.4.3
Signature · 3 lines
Cornelia Huck Linux for zSeries Developer Tel.: +49-7031-16-4837, Mail: [email protected]
Re: [PATCH 1/4] driver core: add root_device_register()
In reply to Cornelia HuckAdd support for allocating root device objects which group device objects under /sys/devices directories.
Also add a sysfs 'module' symlink which points to the owner of the root device object. This symlink will be used in virtio to allow userspace to determine which virtio bus implementation a given device is associated with.
[Includes suggestions from Cornelia Huck]
--- drivers/base/core.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 11 ++++++ 2 files changed, 98 insertions(+), 0 deletions(-)
drivers/base/core.c +87 -0
@@ -1196,6 +1196,93 @@ EXPORT_SYMBOL_GPL(put_device);EXPORT_SYMBOL_GPL (device_create_file);EXPORT_SYMBOL_GPL (device_remove_file); +struct root_device +{ +struct device dev; +struct module *owner; +}; + +static void root_device_release (struct device *dev) +{ +kfree (dev); +} + +/** +* __root_device_register - allocate and register a root device +* @name: root device name +* @owner: owner module of the root device, usually THIS_MODULE +* +* This function allocates a root device and registers it +* using device_register(). In order to free the returned +* device, use root_device_unregister(). +* +* Root devices are dummy devices which allow other devices +* to be grouped under /sys/devices. Use this function to +* allocate a root device and then use it as the parent of +* any device which should appear under /sys/devices/{name} +* +* The /sys/devices/{name} directory will also contain a +* 'module' symlink which points to the @owner directory +* in sysfs. +* +* Note: You probably want to use root_device_register(). +*/ +struct device *__root_device_register (const char *name,struct module *owner) +{ +struct root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct root_device ),GFP_KERNEL ); +if (!root) +return ERR_PTR (err); + + err =dev_set_name (&root->dev, name); +if (err) { +kfree (root); +return ERR_PTR (err); + } + + root->dev.release = root_device_release; + + err =device_register (&root->dev); +if (err) { +put_device (&root->dev); +return ERR_PTR (err); + } + +if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) { +device_unregister (&root->dev); +return ERR_PTR (err); + } + root->owner = owner; + } + +return &root->dev; +} +EXPORT_SYMBOL_GPL (__root_device_register); + +/** +* root_device_unregister - unregister and free a root device +* @root: device going away. +* +* This function unregisters and cleans up a device that was created by +* root_device_register(). +*/ +void root_device_unregister (struct device *dev) +{ + struct root_device *root = container_of(dev, struct root_device, dev); + +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" ); + +device_unregister (dev); +} +EXPORT_SYMBOL_GPL (root_device_unregister); +static void device_create_release (struct device *dev) {
include/linux/device.h +11 -0
@@ -483,6 +483,17 @@ extern int device_rename(struct device *dev, char *new_name);extern int device_move (struct device *dev,struct device *new_parent);/* +* Root device objects for grouping under /sys/devices +*/ +extern struct device *__root_device_register (const char *name, +struct module *owner); +static inline struct device *root_device_register (const char *name) +{ +return __root_device_register (name,THIS_MODULE ); +} +extern void root_device_unregister (struct device *root); + +/* * Manual binding of a device to driver. See drivers/base/bus.c * for information on use. */
Signature · 1 line
1.5.4.3
Re: [PATCH 1/4] driver core: add root_device_register()
In reply to Cornelia HuckAdd support for allocating root device objects which group device objects under /sys/devices directories.
Also add a sysfs 'module' symlink which points to the owner of the root device object. This symlink will be used in virtio to allow userspace to determine which virtio bus implementation a given device is associated with.
[Includes suggestions from Cornelia Huck]
--- drivers/base/core.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 11 ++++++ 2 files changed, 98 insertions(+), 0 deletions(-)
drivers/base/core.c +87 -0
@@ -1196,6 +1196,93 @@ EXPORT_SYMBOL_GPL(put_device);EXPORT_SYMBOL_GPL (device_create_file);EXPORT_SYMBOL_GPL (device_remove_file); +struct root_device +{ +struct device dev; +struct module *owner; +}; + +static void root_device_release (struct device *dev) +{ +kfree (dev); +} + +/** +* __root_device_register - allocate and register a root device +* @name: root device name +* @owner: owner module of the root device, usually THIS_MODULE +* +* This function allocates a root device and registers it +* using device_register(). In order to free the returned +* device, use root_device_unregister(). +* +* Root devices are dummy devices which allow other devices +* to be grouped under /sys/devices. Use this function to +* allocate a root device and then use it as the parent of +* any device which should appear under /sys/devices/{name} +* +* The /sys/devices/{name} directory will also contain a +* 'module' symlink which points to the @owner directory +* in sysfs. +* +* Note: You probably want to use root_device_register(). +*/ +struct device *__root_device_register (const char *name,struct module *owner) +{ +struct root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct root_device ),GFP_KERNEL ); +if (!root) +return ERR_PTR (err); + + err =dev_set_name (&root->dev, name); +if (err) { +kfree (root); +return ERR_PTR (err); + } + + root->dev.release = root_device_release; + + err =device_register (&root->dev); +if (err) { +put_device (&root->dev); +return ERR_PTR (err); + } + +if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) { +device_unregister (&root->dev); +return ERR_PTR (err); + } + root->owner = owner; + } + +return &root->dev; +} +EXPORT_SYMBOL_GPL (__root_device_register); + +/** +* root_device_unregister - unregister and free a root device +* @root: device going away. +* +* This function unregisters and cleans up a device that was created by +* root_device_register(). +*/ +void root_device_unregister (struct device *dev) +{ + struct root_device *root = container_of(dev, struct root_device, dev); + +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" ); + +device_unregister (dev); +} +EXPORT_SYMBOL_GPL (root_device_unregister); +static void device_create_release (struct device *dev) {
include/linux/device.h +11 -0
@@ -483,6 +483,17 @@ extern int device_rename(struct device *dev, char *new_name);extern int device_move (struct device *dev,struct device *new_parent);/* +* Root device objects for grouping under /sys/devices +*/ +extern struct device *__root_device_register (const char *name, +struct module *owner); +static inline struct device *root_device_register (const char *name) +{ +return __root_device_register (name,THIS_MODULE ); +} +extern void root_device_unregister (struct device *root); + +/* * Manual binding of a device to driver. See drivers/base/bus.c * for information on use. */
Signature · 1 line
1.5.4.3
Re: [PATCH 1/4] driver core: add root_device_register()
Quoted 6 lines · Mark McLoughlin
drivers/base/core.c +0
-0@@ -1196,6 +1196,93 @@ EXPORT_SYMBOL_GPL(put_device);EXPORT_SYMBOL_GPL (device_create_file);
drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1206
Quoted 10 lines
drivers/base/core.c +8
-0EXPORT_SYMBOL_GPL (device_remove_file); +struct root_device +{ +struct device dev; +struct module *owner; +}; + +static void root_device_release (struct device *dev) +{
You need to get the root device here and free that.
Quoted 2 lines
drivers/base/core.c +2
-0+kfree (dev); +}
Re: [PATCH 1/4] driver core: add root_device_register()
In reply to Mark McLoughlinQuoted 6 lines · Mark McLoughlin
drivers/base/core.c +0
-0@@ -1196,6 +1196,93 @@ EXPORT_SYMBOL_GPL(put_device);EXPORT_SYMBOL_GPL (device_create_file);
drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1206
Quoted 10 lines
drivers/base/core.c +8
-0EXPORT_SYMBOL_GPL (device_remove_file); +struct root_device +{ +struct device dev; +struct module *owner; +}; + +static void root_device_release (struct device *dev) +{
You need to get the root device here and free that.
Quoted 2 lines
drivers/base/core.c +2
-0+kfree (dev); +}
Re: [PATCH 1/4] driver core: add root_device_register()
Quoted 22 lines · Cornelia Huck
Quoted 6 lines · Mark McLoughlin
drivers/base/core.c +0
-0@@ -1196,6 +1196,93 @@ EXPORT_SYMBOL_GPL(put_device);EXPORT_SYMBOL_GPL (device_create_file);drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1206
Quoted 10 lines
drivers/base/core.c +8
-0EXPORT_SYMBOL_GPL (device_remove_file); +struct root_device +{ +struct device dev; +struct module *owner; +}; + +static void root_device_release (struct device *dev) +{You need to get the root device here and free that.
Quoted 2 lines
drivers/base/core.c EXPORT_SYMBOL_GPL(put_device); · line 1208
Quoted 2 lines
drivers/base/core.c +2
-0+kfree (dev); +}
Yeah, I just figured it was a little overkill given the structure definition is three lines away. Here it is, though.
Cheers,
Mark.
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] driver core: add root_device_register()
Add support for allocating root device objects which group device objects under /sys/devices directories.
Also add a sysfs 'module' symlink which points to the owner of the root device object. This symlink will be used in virtio to allow userspace to determine which virtio bus implementation a given device is associated with.
[Includes suggestions from Cornelia Huck]
--- drivers/base/core.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 11 ++++++ 2 files changed, 100 insertions(+), 0 deletions(-)
drivers/base/core.c +89 -0
@@ -1196,6 +1196,95 @@ EXPORT_SYMBOL_GPL(put_device);EXPORT_SYMBOL_GPL (device_create_file);EXPORT_SYMBOL_GPL (device_remove_file); +struct root_device +{ +struct device dev; +struct module *owner; +}; + +#define to_root_device (dev) container_of(dev, struct root_device, dev) + +static void root_device_release (struct device *dev) +{ +kfree (to_root_device (dev)); +} + +/** +* __root_device_register - allocate and register a root device +* @name: root device name +* @owner: owner module of the root device, usually THIS_MODULE +* +* This function allocates a root device and registers it +* using device_register(). In order to free the returned +* device, use root_device_unregister(). +* +* Root devices are dummy devices which allow other devices +* to be grouped under /sys/devices. Use this function to +* allocate a root device and then use it as the parent of +* any device which should appear under /sys/devices/{name} +* +* The /sys/devices/{name} directory will also contain a +* 'module' symlink which points to the @owner directory +* in sysfs. +* +* Note: You probably want to use root_device_register(). +*/ +struct device *__root_device_register (const char *name,struct module *owner) +{ +struct root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct root_device ),GFP_KERNEL ); +if (!root) +return ERR_PTR (err); + + err =dev_set_name (&root->dev, name); +if (err) { +kfree (root); +return ERR_PTR (err); + } + + root->dev.release = root_device_release; + + err =device_register (&root->dev); +if (err) { +put_device (&root->dev); +return ERR_PTR (err); + } + +if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) { +device_unregister (&root->dev); +return ERR_PTR (err); + } + root->owner = owner; + } + +return &root->dev; +} +EXPORT_SYMBOL_GPL (__root_device_register); + +/** +* root_device_unregister - unregister and free a root device +* @root: device going away. +* +* This function unregisters and cleans up a device that was created by +* root_device_register(). +*/ +void root_device_unregister (struct device *dev) +{ +struct root_device *root =to_root_device (dev); + +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" ); + +device_unregister (dev); +} +EXPORT_SYMBOL_GPL (root_device_unregister); +static void device_create_release (struct device *dev) {
include/linux/device.h +11 -0
@@ -483,6 +483,17 @@ extern int device_rename(struct device *dev, char *new_name);extern int device_move (struct device *dev,struct device *new_parent);/* +* Root device objects for grouping under /sys/devices +*/ +extern struct device *__root_device_register (const char *name, +struct module *owner); +static inline struct device *root_device_register (const char *name) +{ +return __root_device_register (name,THIS_MODULE ); +} +extern void root_device_unregister (struct device *root); + +/* * Manual binding of a device to driver. See drivers/base/bus.c * for information on use. */
Signature · 1 line
1.6.0.3
Cornelia Huck
Acked-byRe: [PATCH 1/4] driver core: add root_device_register()
Quoted 2 lines · Mark McLoughlin
Yeah, I just figured it was a little overkill given the structure definition is three lines away. Here it is, though.
As you use it twice, I think it makes the code more readable.
Quoted 10 lines
Cheers,
Mark.From: Mark McLoughlin <[email protected]>
Subject: [PATCH] driver core: addroot_device_register()Add support for allocating root device objects which group device objects under
/sys/devicesdirectories.
Quoted 8 lines
Also add a sysfs 'module' symlink which points to the owner of the root device object. This symlink will be used in virtio to allow userspace to determine which virtio bus implementation a given device is associated with.
[Includes suggestions from Cornelia Huck]
Signed-off-by Mark McLoughlin <[email protected]>
Quoted 130 lines
--- drivers/base/core.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 11 ++++++ 2 files changed, 100 insertions(+), 0 deletions(-)drivers/base/core.c +89
-0@@ -1196,6 +1196,95 @@ EXPORT_SYMBOL_GPL(put_device);EXPORT_SYMBOL_GPL (device_create_file);EXPORT_SYMBOL_GPL (device_remove_file); +struct root_device +{ +struct device dev; +struct module *owner; +}; + +#define to_root_device (dev) container_of(dev, struct root_device, dev) + +static void root_device_release (struct device *dev) +{ +kfree (to_root_device (dev)); +} + +/** +* __root_device_register - allocate and register a root device +* @name: root device name +* @owner: owner module of the root device, usually THIS_MODULE +* +* This function allocates a root device and registers it +* using device_register(). In order to free the returned +* device, use root_device_unregister(). +* +* Root devices are dummy devices which allow other devices +* to be grouped under /sys/devices. Use this function to +* allocate a root device and then use it as the parent of +* any device which should appear under /sys/devices/{name} +* +* The /sys/devices/{name} directory will also contain a +* 'module' symlink which points to the @owner directory +* in sysfs. +* +* Note: You probably want to use root_device_register(). +*/ +struct device *__root_device_register (const char *name,struct module *owner) +{ +struct root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct root_device ),GFP_KERNEL ); +if (!root) +return ERR_PTR (err); + + err =dev_set_name (&root->dev, name); +if (err) { +kfree (root); +return ERR_PTR (err); + } + + root->dev.release = root_device_release; + + err =device_register (&root->dev); +if (err) { +put_device (&root->dev); +return ERR_PTR (err); + } + +if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) { +device_unregister (&root->dev); +return ERR_PTR (err); + } + root->owner = owner; + } + +return &root->dev; +} +EXPORT_SYMBOL_GPL (__root_device_register); + +/** +* root_device_unregister - unregister and free a root device +* @root: device going away. +* +* This function unregisters and cleans up a device that was created by +* root_device_register(). +*/ +void root_device_unregister (struct device *dev) +{ +struct root_device *root =to_root_device (dev); + +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" ); + +device_unregister (dev); +} +EXPORT_SYMBOL_GPL (root_device_unregister); +static void device_create_release (struct device *dev) {include/linux/device.h +11
-0@@ -483,6 +483,17 @@ extern int device_rename(struct device *dev, char *new_name);extern int device_move (struct device *dev,struct device *new_parent);/* +* Root device objects for grouping under /sys/devices +*/ +extern struct device *__root_device_register (const char *name, +struct module *owner); +static inline struct device *root_device_register (const char *name) +{ +return __root_device_register (name,THIS_MODULE ); +} +extern void root_device_unregister (struct device *root); + +/* * Manual binding of a device to driver. See drivers/base/bus.c * for information on use. */ Signature · 1 line
1.6.0.3
Cornelia Huck
Acked-byRe: [PATCH 1/4] driver core: add root_device_register()
In reply to Mark McLoughlinQuoted 2 lines · Mark McLoughlin
Yeah, I just figured it was a little overkill given the structure definition is three lines away. Here it is, though.
As you use it twice, I think it makes the code more readable.
Quoted 10 lines
Cheers,
Mark.From: Mark McLoughlin <[email protected]>
Subject: [PATCH] driver core: addroot_device_register()Add support for allocating root device objects which group device objects under
/sys/devicesdirectories.
Quoted 8 lines
Also add a sysfs 'module' symlink which points to the owner of the root device object. This symlink will be used in virtio to allow userspace to determine which virtio bus implementation a given device is associated with.
[Includes suggestions from Cornelia Huck]
Signed-off-by Mark McLoughlin <[email protected]>
Quoted 130 lines
--- drivers/base/core.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 11 ++++++ 2 files changed, 100 insertions(+), 0 deletions(-)drivers/base/core.c +89
-0@@ -1196,6 +1196,95 @@ EXPORT_SYMBOL_GPL(put_device);EXPORT_SYMBOL_GPL (device_create_file);EXPORT_SYMBOL_GPL (device_remove_file); +struct root_device +{ +struct device dev; +struct module *owner; +}; + +#define to_root_device (dev) container_of(dev, struct root_device, dev) + +static void root_device_release (struct device *dev) +{ +kfree (to_root_device (dev)); +} + +/** +* __root_device_register - allocate and register a root device +* @name: root device name +* @owner: owner module of the root device, usually THIS_MODULE +* +* This function allocates a root device and registers it +* using device_register(). In order to free the returned +* device, use root_device_unregister(). +* +* Root devices are dummy devices which allow other devices +* to be grouped under /sys/devices. Use this function to +* allocate a root device and then use it as the parent of +* any device which should appear under /sys/devices/{name} +* +* The /sys/devices/{name} directory will also contain a +* 'module' symlink which points to the @owner directory +* in sysfs. +* +* Note: You probably want to use root_device_register(). +*/ +struct device *__root_device_register (const char *name,struct module *owner) +{ +struct root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct root_device ),GFP_KERNEL ); +if (!root) +return ERR_PTR (err); + + err =dev_set_name (&root->dev, name); +if (err) { +kfree (root); +return ERR_PTR (err); + } + + root->dev.release = root_device_release; + + err =device_register (&root->dev); +if (err) { +put_device (&root->dev); +return ERR_PTR (err); + } + +if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) { +device_unregister (&root->dev); +return ERR_PTR (err); + } + root->owner = owner; + } + +return &root->dev; +} +EXPORT_SYMBOL_GPL (__root_device_register); + +/** +* root_device_unregister - unregister and free a root device +* @root: device going away. +* +* This function unregisters and cleans up a device that was created by +* root_device_register(). +*/ +void root_device_unregister (struct device *dev) +{ +struct root_device *root =to_root_device (dev); + +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" ); + +device_unregister (dev); +} +EXPORT_SYMBOL_GPL (root_device_unregister); +static void device_create_release (struct device *dev) {include/linux/device.h +11
-0@@ -483,6 +483,17 @@ extern int device_rename(struct device *dev, char *new_name);extern int device_move (struct device *dev,struct device *new_parent);/* +* Root device objects for grouping under /sys/devices +*/ +extern struct device *__root_device_register (const char *name, +struct module *owner); +static inline struct device *root_device_register (const char *name) +{ +return __root_device_register (name,THIS_MODULE ); +} +extern void root_device_unregister (struct device *root); + +/* * Manual binding of a device to driver. See drivers/base/bus.c * for information on use. */ Signature · 1 line
1.6.0.3
Re: [PATCH 4/4] s390: remove s390_root_dev_*()
In reply to Cornelia HuckQuoted 6 lines · Cornelia Huck
Quoted 1 line · Mark McLoughlin
Replace
s390_root_dev_register()withroot_device_register()etc.Nice, one more special case generalized :) I'll give it a run.
You missed one occurrence in iucv (see below); with that patch applied, everything seems to work as expected, both for root devices created by built-ins and by modules.
--- net/iucv/iucv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/iucv/iucv.c +1 -1
@@ -1682,7 +1682,7 @@ static void __exit iucv_exit(void)kfree (iucv_irq_data[cpu]); iucv_irq_data[cpu] =NULL ; } -s390_root_dev_unregister (iucv_root); +root_device_unregister (iucv_root);bus_unregister (&iucv_bus);unregister_external_interrupt (0x4000 , iucv_external_interrupt); }
Re: [PATCH 4/4] s390: remove s390_root_dev_*()
In reply to Cornelia HuckQuoted 6 lines · Cornelia Huck
Quoted 1 line · Mark McLoughlin
Replace
s390_root_dev_register()withroot_device_register()etc.Nice, one more special case generalized :) I'll give it a run.
You missed one occurrence in iucv (see below); with that patch applied, everything seems to work as expected, both for root devices created by built-ins and by modules.
--- net/iucv/iucv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/iucv/iucv.c +1 -1
@@ -1682,7 +1682,7 @@ static void __exit iucv_exit(void)kfree (iucv_irq_data[cpu]); iucv_irq_data[cpu] =NULL ; } -s390_root_dev_unregister (iucv_root); +root_device_unregister (iucv_root);bus_unregister (&iucv_bus);unregister_external_interrupt (0x4000 , iucv_external_interrupt); }
Re: [PATCH 4/4] s390: remove s390_root_dev_*()
In reply to Cornelia HuckQuoted 10 lines · Cornelia Huck
Quoted 6 lines · Cornelia Huck
Quoted 1 line · Mark McLoughlin
Replace
s390_root_dev_register()withroot_device_register()etc.Nice, one more special case generalized :) I'll give it a run.
You missed one occurrence in iucv (see below);
Oops.
Quoted 3 lines
with that patch applied,
everything seems to work as expected, both for root devices created by built-ins and by modules.
Thanks,
Mark.
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] s390: remove s390_root_dev_*()
Replace s390_root_dev_register() with root_device_register() etc.
[Includes fix from Cornelia Huck]
--- arch/s390/include/asm/s390_rdev.h | 15 ----------- drivers/s390/Makefile | 2 +- drivers/s390/block/dcssblk.c | 11 +++---- drivers/s390/crypto/ap_bus.c | 7 ++--- drivers/s390/kvm/kvm_virtio.c | 5 +-- drivers/s390/net/cu3088.c | 7 ++--- drivers/s390/net/qeth_core_main.c | 7 ++--- drivers/s390/net/qeth_l2_main.c | 2 - drivers/s390/net/qeth_l3_main.c | 2 - drivers/s390/s390_rdev.c | 51 ------------------------------------- net/iucv/iucv.c | 7 ++--- 11 files changed, 20 insertions(+), 96 deletions(-) delete mode 100644 arch/s390/include/asm/s390_rdev.h delete mode 100644 drivers/s390/s390_rdev.c
arch/s390/include/asm/s390_rdev.h deleted +0 -15
@@ -1,15 +0,0 @@ -/* -* include/asm-s390/ccwdev.h -* -* Copyright (C) 2002,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation -* Author(s): Cornelia Huck <[email protected]> -* Carsten Otte <[email protected]> -* -* Interface for s390 root device -*/ - -#ifndef _S390_RDEV_H_ -#define _S390_RDEV_H_ -extern struct device *s390_root_dev_register (const char *); -extern void s390_root_dev_unregister (struct device *); -#endif /* _S390_RDEV_H_ */
drivers/s390/Makefile +1 -1
@@ -4,7 +4,7 @@ CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w -obj-y += s390mach.o sysinfo.o s390_rdev.o +obj-y += s390mach.o sysinfo.o obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/ drivers-y += drivers/s390/built-in.o
drivers/s390/block/dcssblk.c +5 -6
@@ -15,7 +15,6 @@#include <asm/io.h> #include <linux/completion.h> #include <linux/interrupt.h> -#include <asm/s390_rdev.h> //#define DCSSBLK_DEBUG /* Debug messages on/off */ #define DCSSBLK_NAME "dcssblk"
@@ -951,7 +950,7 @@ dcssblk_check_params(void) static void __exitdcssblk_exit (void ) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);unregister_blkdev (dcssblk_major,DCSSBLK_NAME ); }
@@ -960,22 +959,22 @@ dcssblk_init(void) {int rc; - dcssblk_root_dev =s390_root_dev_register ("dcssblk" ); + dcssblk_root_dev =root_device_register ("dcssblk" );if (IS_ERR (dcssblk_root_dev))return PTR_ERR (dcssblk_root_dev); rc =device_create_file (dcssblk_root_dev, &dev_attr_add);if (rc) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } rc =device_create_file (dcssblk_root_dev, &dev_attr_remove);if (rc) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } rc =register_blkdev (0 ,DCSSBLK_NAME );if (rc <0 ) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } dcssblk_major = rc;
drivers/s390/crypto/ap_bus.c +3 -4
@@ -32,7 +32,6 @@#include <linux/notifier.h> #include <linux/kthread.h> #include <linux/mutex.h> -#include <asm/s390_rdev.h> #include <asm/reset.h> #include <linux/hrtimer.h> #include <linux/ktime.h>
@@ -1358,7 +1357,7 @@ int __init ap_module_init(void) }/* Create /sys/devices/ap. */ - ap_root_device =s390_root_dev_register ("ap" ); + ap_root_device =root_device_register ("ap" ); rc =IS_ERR (ap_root_device) ?PTR_ERR (ap_root_device) :0 ;if (rc) goto out_bus;
@@ -1401,7 +1400,7 @@ out_work:hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue); out_root: -s390_root_dev_unregister (ap_root_device); +root_device_unregister (ap_root_device); out_bus:while (i--)bus_remove_file (&ap_bus_type, ap_bus_attrs[i]);
@@ -1432,7 +1431,7 @@ void ap_module_exit(void)hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue);tasklet_kill (&ap_tasklet); -s390_root_dev_unregister (ap_root_device); +root_device_unregister (ap_root_device);while ((dev =bus_find_device (&ap_bus_type,NULL ,NULL , __ap_match_all))) {
drivers/s390/kvm/kvm_virtio.c +2 -3
@@ -24,7 +24,6 @@#include <asm/kvm_virtio.h> #include <asm/setup.h> #include <asm/s390_ext.h> -#include <asm/s390_rdev.h> #define VIRTIO_SUBCODE_64 0x0D00
@@ -335,7 +334,7 @@ static int __init kvm_devices_init(void)if (!MACHINE_IS_KVM )return -ENODEV ; - kvm_root =s390_root_dev_register ("kvm_s390" ); + kvm_root =root_device_register ("kvm_s390" );if (IS_ERR (kvm_root)) { rc =PTR_ERR (kvm_root);printk (KERN_ERR "Could not register kvm_s390 root device" );
@@ -344,7 +343,7 @@ static int __init kvm_devices_init(void) rc =vmem_add_mapping (real_memory_size,PAGE_SIZE );if (rc) { -s390_root_dev_unregister (kvm_root); +root_device_unregister (kvm_root);return rc; }
drivers/s390/net/cu3088.c +3 -4
@@ -25,7 +25,6 @@#include <linux/module.h> #include <linux/err.h> -#include <asm/s390_rdev.h> #include <asm/ccwdev.h> #include <asm/ccwgroup.h>
@@ -120,12 +119,12 @@ cu3088_init (void) {int rc; - cu3088_root_dev =s390_root_dev_register ("cu3088" ); + cu3088_root_dev =root_device_register ("cu3088" );if (IS_ERR (cu3088_root_dev))return PTR_ERR (cu3088_root_dev); rc =ccw_driver_register (&cu3088_driver);if (rc) -s390_root_dev_unregister (cu3088_root_dev); +root_device_unregister (cu3088_root_dev);return rc; }
@@ -134,7 +133,7 @@ static void __exitcu3088_exit (void) {ccw_driver_unregister (&cu3088_driver); -s390_root_dev_unregister (cu3088_root_dev); +root_device_unregister (cu3088_root_dev); }MODULE_DEVICE_TABLE (ccw,cu3088_ids);
drivers/s390/net/qeth_core_main.c +3 -4
@@ -21,7 +21,6 @@#include <asm/ebcdic.h> #include <asm/io.h> -#include <asm/s390_rdev.h> #include "qeth_core.h" #include "qeth_core_offl.h"
@@ -4465,7 +4464,7 @@ static int __init qeth_core_init(void) &driver_attr_group);if (rc) goto driver_err; - qeth_core_root_dev =s390_root_dev_register ("qeth" ); + qeth_core_root_dev =root_device_register ("qeth" ); rc =IS_ERR (qeth_core_root_dev) ?PTR_ERR (qeth_core_root_dev) :0 ;if (rc) goto register_err;
@@ -4479,7 +4478,7 @@ static int __init qeth_core_init(void)return 0 ; slab_err: -s390_root_dev_unregister (qeth_core_root_dev); +root_device_unregister (qeth_core_root_dev); register_err:driver_remove_file (&qeth_core_ccwgroup_driver.driver, &driver_attr_group);
@@ -4496,7 +4495,7 @@ out_err: static void __exit qeth_core_exit(void) { -s390_root_dev_unregister (qeth_core_root_dev); +root_device_unregister (qeth_core_root_dev);driver_remove_file (&qeth_core_ccwgroup_driver.driver, &driver_attr_group);ccwgroup_driver_unregister (&qeth_core_ccwgroup_driver);
drivers/s390/net/qeth_l2_main.c +0 -2
@@ -17,8 +17,6 @@#include <linux/mii.h> #include <linux/ip.h> -#include <asm/s390_rdev.h> -#include "qeth_core.h" #include "qeth_core_offl.h"
drivers/s390/net/qeth_l3_main.c +0 -2
@@ -23,8 +23,6 @@#include <net/ip.h> #include <net/arp.h> -#include <asm/s390_rdev.h> -#include "qeth_l3.h" #include "qeth_core_offl.h"
drivers/s390/s390_rdev.c deleted +0 -51
51 lines not on this page · raw message
net/iucv/iucv.c +3 -4
@@ -47,7 +47,6 @@#include <asm/ebcdic.h> #include <asm/io.h> #include <asm/s390_ext.h> -#include <asm/s390_rdev.h> #include <asm/smp.h> /*
@@ -1609,7 +1608,7 @@ static int __init iucv_init(void) rc =register_external_interrupt (0x4000 , iucv_external_interrupt);if (rc) goto out; - iucv_root =s390_root_dev_register ("iucv" ); + iucv_root =root_device_register ("iucv" );if (IS_ERR (iucv_root)) { rc =PTR_ERR (iucv_root); goto out_int;
@@ -1653,7 +1652,7 @@ out_free:kfree (iucv_irq_data[cpu]); iucv_irq_data[cpu] =NULL ; } -s390_root_dev_unregister (iucv_root); +root_device_unregister (iucv_root); out_int:unregister_external_interrupt (0x4000 , iucv_external_interrupt); out:
@@ -1683,7 +1682,7 @@ static void __exit iucv_exit(void)kfree (iucv_irq_data[cpu]); iucv_irq_data[cpu] =NULL ; } -s390_root_dev_unregister (iucv_root); +root_device_unregister (iucv_root);bus_unregister (&iucv_bus);unregister_external_interrupt (0x4000 , iucv_external_interrupt); }
Signature · 1 line
1.6.0.3
Re: [PATCH 4/4] s390: remove s390_root_dev_*()
In reply to Cornelia HuckQuoted 10 lines · Cornelia Huck
Quoted 6 lines · Cornelia Huck
Quoted 1 line · Mark McLoughlin
Replace
s390_root_dev_register()withroot_device_register()etc.Nice, one more special case generalized :) I'll give it a run.
You missed one occurrence in iucv (see below);
Oops.
Quoted 3 lines
with that patch applied,
everything seems to work as expected, both for root devices created by built-ins and by modules.
Thanks,
Mark.
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] s390: remove s390_root_dev_*()
Replace s390_root_dev_register() with root_device_register() etc.
[Includes fix from Cornelia Huck]
--- arch/s390/include/asm/s390_rdev.h | 15 ----------- drivers/s390/Makefile | 2 +- drivers/s390/block/dcssblk.c | 11 +++---- drivers/s390/crypto/ap_bus.c | 7 ++--- drivers/s390/kvm/kvm_virtio.c | 5 +-- drivers/s390/net/cu3088.c | 7 ++--- drivers/s390/net/qeth_core_main.c | 7 ++--- drivers/s390/net/qeth_l2_main.c | 2 - drivers/s390/net/qeth_l3_main.c | 2 - drivers/s390/s390_rdev.c | 51 ------------------------------------- net/iucv/iucv.c | 7 ++--- 11 files changed, 20 insertions(+), 96 deletions(-) delete mode 100644 arch/s390/include/asm/s390_rdev.h delete mode 100644 drivers/s390/s390_rdev.c
arch/s390/include/asm/s390_rdev.h deleted +0 -15
@@ -1,15 +0,0 @@ -/* -* include/asm-s390/ccwdev.h -* -* Copyright (C) 2002,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation -* Author(s): Cornelia Huck <[email protected]> -* Carsten Otte <[email protected]> -* -* Interface for s390 root device -*/ - -#ifndef _S390_RDEV_H_ -#define _S390_RDEV_H_ -extern struct device *s390_root_dev_register (const char *); -extern void s390_root_dev_unregister (struct device *); -#endif /* _S390_RDEV_H_ */
drivers/s390/Makefile +1 -1
@@ -4,7 +4,7 @@ CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w -obj-y += s390mach.o sysinfo.o s390_rdev.o +obj-y += s390mach.o sysinfo.o obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/ drivers-y += drivers/s390/built-in.o
drivers/s390/block/dcssblk.c +5 -6
@@ -15,7 +15,6 @@#include <asm/io.h> #include <linux/completion.h> #include <linux/interrupt.h> -#include <asm/s390_rdev.h> //#define DCSSBLK_DEBUG /* Debug messages on/off */ #define DCSSBLK_NAME "dcssblk"
@@ -951,7 +950,7 @@ dcssblk_check_params(void) static void __exitdcssblk_exit (void ) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);unregister_blkdev (dcssblk_major,DCSSBLK_NAME ); }
@@ -960,22 +959,22 @@ dcssblk_init(void) {int rc; - dcssblk_root_dev =s390_root_dev_register ("dcssblk" ); + dcssblk_root_dev =root_device_register ("dcssblk" );if (IS_ERR (dcssblk_root_dev))return PTR_ERR (dcssblk_root_dev); rc =device_create_file (dcssblk_root_dev, &dev_attr_add);if (rc) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } rc =device_create_file (dcssblk_root_dev, &dev_attr_remove);if (rc) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } rc =register_blkdev (0 ,DCSSBLK_NAME );if (rc <0 ) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } dcssblk_major = rc;
drivers/s390/crypto/ap_bus.c +3 -4
@@ -32,7 +32,6 @@#include <linux/notifier.h> #include <linux/kthread.h> #include <linux/mutex.h> -#include <asm/s390_rdev.h> #include <asm/reset.h> #include <linux/hrtimer.h> #include <linux/ktime.h>
@@ -1358,7 +1357,7 @@ int __init ap_module_init(void) }/* Create /sys/devices/ap. */ - ap_root_device =s390_root_dev_register ("ap" ); + ap_root_device =root_device_register ("ap" ); rc =IS_ERR (ap_root_device) ?PTR_ERR (ap_root_device) :0 ;if (rc) goto out_bus;
@@ -1401,7 +1400,7 @@ out_work:hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue); out_root: -s390_root_dev_unregister (ap_root_device); +root_device_unregister (ap_root_device); out_bus:while (i--)bus_remove_file (&ap_bus_type, ap_bus_attrs[i]);
@@ -1432,7 +1431,7 @@ void ap_module_exit(void)hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue);tasklet_kill (&ap_tasklet); -s390_root_dev_unregister (ap_root_device); +root_device_unregister (ap_root_device);while ((dev =bus_find_device (&ap_bus_type,NULL ,NULL , __ap_match_all))) {
drivers/s390/kvm/kvm_virtio.c +2 -3
@@ -24,7 +24,6 @@#include <asm/kvm_virtio.h> #include <asm/setup.h> #include <asm/s390_ext.h> -#include <asm/s390_rdev.h> #define VIRTIO_SUBCODE_64 0x0D00
@@ -335,7 +334,7 @@ static int __init kvm_devices_init(void)if (!MACHINE_IS_KVM )return -ENODEV ; - kvm_root =s390_root_dev_register ("kvm_s390" ); + kvm_root =root_device_register ("kvm_s390" );if (IS_ERR (kvm_root)) { rc =PTR_ERR (kvm_root);printk (KERN_ERR "Could not register kvm_s390 root device" );
@@ -344,7 +343,7 @@ static int __init kvm_devices_init(void) rc =vmem_add_mapping (real_memory_size,PAGE_SIZE );if (rc) { -s390_root_dev_unregister (kvm_root); +root_device_unregister (kvm_root);return rc; }
drivers/s390/net/cu3088.c +3 -4
@@ -25,7 +25,6 @@#include <linux/module.h> #include <linux/err.h> -#include <asm/s390_rdev.h> #include <asm/ccwdev.h> #include <asm/ccwgroup.h>
@@ -120,12 +119,12 @@ cu3088_init (void) {int rc; - cu3088_root_dev =s390_root_dev_register ("cu3088" ); + cu3088_root_dev =root_device_register ("cu3088" );if (IS_ERR (cu3088_root_dev))return PTR_ERR (cu3088_root_dev); rc =ccw_driver_register (&cu3088_driver);if (rc) -s390_root_dev_unregister (cu3088_root_dev); +root_device_unregister (cu3088_root_dev);return rc; }
@@ -134,7 +133,7 @@ static void __exitcu3088_exit (void) {ccw_driver_unregister (&cu3088_driver); -s390_root_dev_unregister (cu3088_root_dev); +root_device_unregister (cu3088_root_dev); }MODULE_DEVICE_TABLE (ccw,cu3088_ids);
drivers/s390/net/qeth_core_main.c +3 -4
@@ -21,7 +21,6 @@#include <asm/ebcdic.h> #include <asm/io.h> -#include <asm/s390_rdev.h> #include "qeth_core.h" #include "qeth_core_offl.h"
@@ -4465,7 +4464,7 @@ static int __init qeth_core_init(void) &driver_attr_group);if (rc) goto driver_err; - qeth_core_root_dev =s390_root_dev_register ("qeth" ); + qeth_core_root_dev =root_device_register ("qeth" ); rc =IS_ERR (qeth_core_root_dev) ?PTR_ERR (qeth_core_root_dev) :0 ;if (rc) goto register_err;
@@ -4479,7 +4478,7 @@ static int __init qeth_core_init(void)return 0 ; slab_err: -s390_root_dev_unregister (qeth_core_root_dev); +root_device_unregister (qeth_core_root_dev); register_err:driver_remove_file (&qeth_core_ccwgroup_driver.driver, &driver_attr_group);
@@ -4496,7 +4495,7 @@ out_err: static void __exit qeth_core_exit(void) { -s390_root_dev_unregister (qeth_core_root_dev); +root_device_unregister (qeth_core_root_dev);driver_remove_file (&qeth_core_ccwgroup_driver.driver, &driver_attr_group);ccwgroup_driver_unregister (&qeth_core_ccwgroup_driver);
drivers/s390/net/qeth_l2_main.c +0 -2
@@ -17,8 +17,6 @@#include <linux/mii.h> #include <linux/ip.h> -#include <asm/s390_rdev.h> -#include "qeth_core.h" #include "qeth_core_offl.h"
drivers/s390/net/qeth_l3_main.c +0 -2
@@ -23,8 +23,6 @@#include <net/ip.h> #include <net/arp.h> -#include <asm/s390_rdev.h> -#include "qeth_l3.h" #include "qeth_core_offl.h"
drivers/s390/s390_rdev.c deleted +0 -51
51 lines not on this page · raw message
net/iucv/iucv.c +3 -4
@@ -47,7 +47,6 @@#include <asm/ebcdic.h> #include <asm/io.h> #include <asm/s390_ext.h> -#include <asm/s390_rdev.h> #include <asm/smp.h> /*
@@ -1609,7 +1608,7 @@ static int __init iucv_init(void) rc =register_external_interrupt (0x4000 , iucv_external_interrupt);if (rc) goto out; - iucv_root =s390_root_dev_register ("iucv" ); + iucv_root =root_device_register ("iucv" );if (IS_ERR (iucv_root)) { rc =PTR_ERR (iucv_root); goto out_int;
@@ -1653,7 +1652,7 @@ out_free:kfree (iucv_irq_data[cpu]); iucv_irq_data[cpu] =NULL ; } -s390_root_dev_unregister (iucv_root); +root_device_unregister (iucv_root); out_int:unregister_external_interrupt (0x4000 , iucv_external_interrupt); out:
@@ -1683,7 +1682,7 @@ static void __exit iucv_exit(void)kfree (iucv_irq_data[cpu]); iucv_irq_data[cpu] =NULL ; } -s390_root_dev_unregister (iucv_root); +root_device_unregister (iucv_root);bus_unregister (&iucv_bus);unregister_external_interrupt (0x4000 , iucv_external_interrupt); }
Signature · 1 line
1.6.0.3
Re: [PATCH 4/4] s390: remove s390_root_dev_*()
In reply to Mark McLoughlinQuoted 8 lines · Mark McLoughlin
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] s390: remove s390_root_dev_*()Replace
s390_root_dev_register()withroot_device_register()etc.[Includes fix from Cornelia Huck]
Signed-off-by Mark McLoughlin <[email protected]>
I can carry the patch in my patch queue. Thanks.
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
Re: [PATCH 4/4] s390: remove s390_root_dev_*()
In reply to Mark McLoughlinQuoted 8 lines · Mark McLoughlin
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] s390: remove s390_root_dev_*()Replace
s390_root_dev_register()withroot_device_register()etc.[Includes fix from Cornelia Huck]
Signed-off-by Mark McLoughlin <[email protected]>
I can carry the patch in my patch queue. Thanks.
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
Cornelia Huck
Acked-byRe: [PATCH 4/4] s390: remove s390_root_dev_*()
In reply to Mark McLoughlinQuoted 8 lines · Mark McLoughlin
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] s390: remove s390_root_dev_*()Replace
s390_root_dev_register()withroot_device_register()etc.[Includes fix from Cornelia Huck]
Signed-off-by Mark McLoughlin <[email protected]>
Cornelia Huck
Acked-byRe: [PATCH 4/4] s390: remove s390_root_dev_*()
In reply to Mark McLoughlinQuoted 8 lines · Mark McLoughlin
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] s390: remove s390_root_dev_*()Replace
s390_root_dev_register()withroot_device_register()etc.[Includes fix from Cornelia Huck]
Signed-off-by Mark McLoughlin <[email protected]>
Re: [PATCH 4/4] s390: remove s390_root_dev_*()
In reply to Martin SchwidefskyQuoted 11 lines · Martin Schwidefsky
Quoted 8 lines · Mark McLoughlin
From: Mark McLoughlin <[email protected]>
Subject: [PATCH] s390: remove s390_root_dev_*()Replace
s390_root_dev_register()withroot_device_register()etc.[Includes fix from Cornelia Huck]
Signed-off-by Mark McLoughlin <[email protected]>I can carry the patch in my patch queue. Thanks.
Oops, this depends on another patch. If the other patch is missing it doesn't compile.. So I better not add that patch to my queue. It should be sent together with the patch it depends on.
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
Re: [PATCH 4/4] s390: remove s390_root_dev_*()
In reply to Mark McLoughlinQuoted 18 lines · Mark McLoughlin
Quoted 10 lines · Cornelia Huck
Quoted 6 lines · Cornelia Huck
Quoted 1 line · Mark McLoughlin
Replace
s390_root_dev_register()withroot_device_register()etc.Nice, one more special case generalized :) I'll give it a run.
You missed one occurrence in iucv (see below);
Oops.
Quoted 3 lines
with that patch applied,
everything seems to work as expected, both for root devices created by built-ins and by modules.
Quoted 7 lines
Thanks,
Mark.From: Mark McLoughlin <[email protected]>
Subject: [PATCH] s390: remove s390_root_dev_*()Replace
s390_root_dev_register()withroot_device_register()etc.
Can you resend this whole series, I see lots of replacements in this thread and it would be good to know exactly what I should be reviewing/applying.
thanks,
greg k-h
PATCH 3/4 lguest: do not statically allocate root device
In reply to Mark McLoughlinWe shouldn't be statically allocating the root device object, so dynamically allocate it using root_device_register() instead.
--- drivers/lguest/lguest_device.c | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-)
drivers/lguest/lguest_device.c +4 -6
@@ -321,10 +321,7 @@ static struct virtio_config_ops lguest_config_ops = {/* The root device for the lguest virtio devices. This makes them appear as * /sys/devices/lguest/0,1,2 not /sys/devices/0,1,2. */ -static struct device lguest_root = { - .parent =NULL , - .bus_id ="lguest" , -}; +static struct device *lguest_root;/*D:120 This is the core of the lguest bus: actually adding a new device. * It's a separate function because it's neater that way, and because an
@@ -351,7 +348,7 @@ static void add_lguest_device(struct lguest_device_desc *d, }/* This devices' parent is the lguest/ dir. */ - ldev->vdev.dev.parent = &lguest_root; + ldev->vdev.dev.parent = lguest_root;/* We have a unique device index thanks to the dev_index counter. */ ldev->vdev.id.device = d->type;/* We have a simple set of routines for querying the device's
@@ -407,7 +404,8 @@ static int __init lguest_devices_init(void)if (strcmp (pv_info.name,"lguest" ) !=0 )return 0 ; -if (device_register (&lguest_root) !=0 ) + lguest_root =root_device_register ("lguest" ); +if (IS_ERR (lguest_root))panic ("Could not register lguest root" );/* Devices are in a single page above top of "normal" mem */
Signature · 1 line
1.5.4.3
PATCH 2/4 virtio: do not statically allocate root device
In reply to Mark McLoughlinWe shouldn't be statically allocating the root device object, so dynamically allocate it using root_device_register() instead.
Also avoids this warning from 'rmmod virtio_pci':
Device 'virtio-pci' does not have a release() function, it is broken and must be fixed
--- drivers/virtio/virtio_pci.c | 17 +++++++---------- 1 files changed, 7 insertions(+), 10 deletions(-)
drivers/virtio/virtio_pci.c +7 -10
@@ -73,10 +73,7 @@ MODULE_DEVICE_TABLE(pci, virtio_pci_id_table);/* A PCI device has it's own struct device and so does a virtio device so * we create a place for the virtio devices to show up in sysfs. I think it * would make more sense for virtio to not insist on having it's own device. */ -static struct device virtio_pci_root = { - .parent =NULL , - .init_name ="virtio-pci" , -}; +static struct device *virtio_pci_root;/* Convert a generic virtio device to our structure */ static struct virtio_pci_device *to_vp_device (struct virtio_device *vdev)
@@ -343,7 +340,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,if (vp_dev ==NULL )return -ENOMEM ; - vp_dev->vdev.dev.parent = &virtio_pci_root; + vp_dev->vdev.dev.parent = virtio_pci_root; vp_dev->vdev.dev.release = virtio_pci_release_dev; vp_dev->vdev.config = &virtio_pci_config_ops; vp_dev->pci_dev = pci_dev;
@@ -437,13 +434,13 @@ static int __init virtio_pci_init(void) {int err; - err =device_register (&virtio_pci_root); -if (err) -return err; + virtio_pci_root =root_device_register ("virtio-pci" ); +if (IS_ERR (virtio_pci_root)) +return PTR_ERR (virtio_pci_root); err =pci_register_driver (&virtio_pci_driver);if (err) -device_unregister (&virtio_pci_root); +device_unregister (virtio_pci_root);return err; }
@@ -452,8 +449,8 @@ module_init(virtio_pci_init); static void __exit virtio_pci_exit(void) { -device_unregister (&virtio_pci_root);pci_unregister_driver (&virtio_pci_driver); +root_device_unregister (virtio_pci_root); }module_exit (virtio_pci_exit);
Signature · 1 line
1.5.4.3
PATCH 1/4 driver core: add root_device_register()
In reply to Greg KHAdd support for allocating root device objects which group device objects under /sys/devices directories.
Also add a sysfs 'module' symlink which points to the owner of the root device object. This symlink will be used in virtio to allow userspace to determine which virtio bus implementation a given device is associated with.
[Includes suggestions from Cornelia Huck]
--- drivers/base/core.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 11 ++++++ 2 files changed, 100 insertions(+), 0 deletions(-)
drivers/base/core.c +89 -0
@@ -1196,6 +1196,95 @@ EXPORT_SYMBOL_GPL(put_device);EXPORT_SYMBOL_GPL (device_create_file);EXPORT_SYMBOL_GPL (device_remove_file); +struct root_device +{ +struct device dev; +struct module *owner; +}; + +#define to_root_device (dev) container_of(dev, struct root_device, dev) + +static void root_device_release (struct device *dev) +{ +kfree (to_root_device (dev)); +} + +/** +* __root_device_register - allocate and register a root device +* @name: root device name +* @owner: owner module of the root device, usually THIS_MODULE +* +* This function allocates a root device and registers it +* using device_register(). In order to free the returned +* device, use root_device_unregister(). +* +* Root devices are dummy devices which allow other devices +* to be grouped under /sys/devices. Use this function to +* allocate a root device and then use it as the parent of +* any device which should appear under /sys/devices/{name} +* +* The /sys/devices/{name} directory will also contain a +* 'module' symlink which points to the @owner directory +* in sysfs. +* +* Note: You probably want to use root_device_register(). +*/ +struct device *__root_device_register (const char *name,struct module *owner) +{ +struct root_device *root; +int err = -ENOMEM ; + + root =kzalloc (sizeof (struct root_device ),GFP_KERNEL ); +if (!root) +return ERR_PTR (err); + + err =dev_set_name (&root->dev, name); +if (err) { +kfree (root); +return ERR_PTR (err); + } + + root->dev.release = root_device_release; + + err =device_register (&root->dev); +if (err) { +put_device (&root->dev); +return ERR_PTR (err); + } + +if (owner) { +struct module_kobject *mk = &owner->mkobj; + + err =sysfs_create_link (&root->dev.kobj, &mk->kobj,"module" ); +if (err) { +device_unregister (&root->dev); +return ERR_PTR (err); + } + root->owner = owner; + } + +return &root->dev; +} +EXPORT_SYMBOL_GPL (__root_device_register); + +/** +* root_device_unregister - unregister and free a root device +* @root: device going away. +* +* This function unregisters and cleans up a device that was created by +* root_device_register(). +*/ +void root_device_unregister (struct device *dev) +{ +struct root_device *root =to_root_device (dev); + +if (root->owner) +sysfs_remove_link (&root->dev.kobj,"module" ); + +device_unregister (dev); +} +EXPORT_SYMBOL_GPL (root_device_unregister); +static void device_create_release (struct device *dev) {
include/linux/device.h +11 -0
@@ -484,6 +484,17 @@ extern int device_rename(struct device *dev, char *new_name);extern int device_move (struct device *dev,struct device *new_parent);/* +* Root device objects for grouping under /sys/devices +*/ +extern struct device *__root_device_register (const char *name, +struct module *owner); +static inline struct device *root_device_register (const char *name) +{ +return __root_device_register (name,THIS_MODULE ); +} +extern void root_device_unregister (struct device *root); + +/* * Manual binding of a device to driver. See drivers/base/bus.c * for information on use. */
Signature · 1 line
1.5.4.3
PATCH 4/4 s390: remove s390_root_dev_*()
In reply to Mark McLoughlinReplace s390_root_dev_register() with root_device_register() etc.
[Includes fix from Cornelia Huck]
--- arch/s390/include/asm/s390_rdev.h | 15 ----------- drivers/s390/Makefile | 2 +- drivers/s390/block/dcssblk.c | 11 +++---- drivers/s390/crypto/ap_bus.c | 7 ++--- drivers/s390/kvm/kvm_virtio.c | 5 +-- drivers/s390/net/cu3088.c | 7 ++--- drivers/s390/net/qeth_core_main.c | 7 ++--- drivers/s390/net/qeth_l2_main.c | 2 - drivers/s390/net/qeth_l3_main.c | 2 - drivers/s390/s390_rdev.c | 51 ------------------------------------- net/iucv/iucv.c | 7 ++--- 11 files changed, 20 insertions(+), 96 deletions(-) delete mode 100644 arch/s390/include/asm/s390_rdev.h delete mode 100644 drivers/s390/s390_rdev.c
arch/s390/include/asm/s390_rdev.h deleted +0 -15
@@ -1,15 +0,0 @@ -/* -* include/asm-s390/ccwdev.h -* -* Copyright (C) 2002,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation -* Author(s): Cornelia Huck <[email protected]> -* Carsten Otte <[email protected]> -* -* Interface for s390 root device -*/ - -#ifndef _S390_RDEV_H_ -#define _S390_RDEV_H_ -extern struct device *s390_root_dev_register (const char *); -extern void s390_root_dev_unregister (struct device *); -#endif /* _S390_RDEV_H_ */
drivers/s390/Makefile +1 -1
@@ -4,7 +4,7 @@ CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w -obj-y += s390mach.o sysinfo.o s390_rdev.o +obj-y += s390mach.o sysinfo.o obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/ drivers-y += drivers/s390/built-in.o
drivers/s390/block/dcssblk.c +5 -6
@@ -18,7 +18,6 @@#include <asm/io.h> #include <linux/completion.h> #include <linux/interrupt.h> -#include <asm/s390_rdev.h> #define DCSSBLK_NAME "dcssblk"#define DCSSBLK_MINORS_PER_DISK 1
@@ -946,7 +945,7 @@ dcssblk_check_params(void) static void __exitdcssblk_exit (void ) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);unregister_blkdev (dcssblk_major,DCSSBLK_NAME ); }
@@ -955,22 +954,22 @@ dcssblk_init(void) {int rc; - dcssblk_root_dev =s390_root_dev_register ("dcssblk" ); + dcssblk_root_dev =root_device_register ("dcssblk" );if (IS_ERR (dcssblk_root_dev))return PTR_ERR (dcssblk_root_dev); rc =device_create_file (dcssblk_root_dev, &dev_attr_add);if (rc) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } rc =device_create_file (dcssblk_root_dev, &dev_attr_remove);if (rc) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } rc =register_blkdev (0 ,DCSSBLK_NAME );if (rc <0 ) { -s390_root_dev_unregister (dcssblk_root_dev); +root_device_unregister (dcssblk_root_dev);return rc; } dcssblk_major = rc;
drivers/s390/crypto/ap_bus.c +3 -4
@@ -36,7 +36,6 @@#include <linux/notifier.h> #include <linux/kthread.h> #include <linux/mutex.h> -#include <asm/s390_rdev.h> #include <asm/reset.h> #include <asm/airq.h> #include <asm/atomic.h>
@@ -1522,7 +1521,7 @@ int __init ap_module_init(void) }/* Create /sys/devices/ap. */ - ap_root_device =s390_root_dev_register ("ap" ); + ap_root_device =root_device_register ("ap" ); rc =IS_ERR (ap_root_device) ?PTR_ERR (ap_root_device) :0 ;if (rc) goto out_bus;
@@ -1565,7 +1564,7 @@ out_work:hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue); out_root: -s390_root_dev_unregister (ap_root_device); +root_device_unregister (ap_root_device); out_bus:while (i--)bus_remove_file (&ap_bus_type, ap_bus_attrs[i]);
@@ -1600,7 +1599,7 @@ void ap_module_exit(void)hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue);tasklet_kill (&ap_tasklet); -s390_root_dev_unregister (ap_root_device); +root_device_unregister (ap_root_device);while ((dev =bus_find_device (&ap_bus_type,NULL ,NULL , __ap_match_all))) {
drivers/s390/kvm/kvm_virtio.c +2 -3
@@ -24,7 +24,6 @@#include <asm/kvm_virtio.h> #include <asm/setup.h> #include <asm/s390_ext.h> -#include <asm/s390_rdev.h> #define VIRTIO_SUBCODE_64 0x0D00
@@ -335,7 +334,7 @@ static int __init kvm_devices_init(void)if (!MACHINE_IS_KVM )return -ENODEV ; - kvm_root =s390_root_dev_register ("kvm_s390" ); + kvm_root =root_device_register ("kvm_s390" );if (IS_ERR (kvm_root)) { rc =PTR_ERR (kvm_root);printk (KERN_ERR "Could not register kvm_s390 root device" );
@@ -344,7 +343,7 @@ static int __init kvm_devices_init(void) rc =vmem_add_mapping (real_memory_size,PAGE_SIZE );if (rc) { -s390_root_dev_unregister (kvm_root); +root_device_unregister (kvm_root);return rc; }
drivers/s390/net/cu3088.c +3 -4
@@ -25,7 +25,6 @@#include <linux/module.h> #include <linux/err.h> -#include <asm/s390_rdev.h> #include <asm/ccwdev.h> #include <asm/ccwgroup.h>
@@ -120,12 +119,12 @@ cu3088_init (void) {int rc; - cu3088_root_dev =s390_root_dev_register ("cu3088" ); + cu3088_root_dev =root_device_register ("cu3088" );if (IS_ERR (cu3088_root_dev))return PTR_ERR (cu3088_root_dev); rc =ccw_driver_register (&cu3088_driver);if (rc) -s390_root_dev_unregister (cu3088_root_dev); +root_device_unregister (cu3088_root_dev);return rc; }
@@ -134,7 +133,7 @@ static void __exitcu3088_exit (void) {ccw_driver_unregister (&cu3088_driver); -s390_root_dev_unregister (cu3088_root_dev); +root_device_unregister (cu3088_root_dev); }MODULE_DEVICE_TABLE (ccw,cu3088_ids);
drivers/s390/net/qeth_core_main.c +3 -4
@@ -24,7 +24,6 @@#include <asm/ebcdic.h> #include <asm/io.h> -#include <asm/s390_rdev.h> #include "qeth_core.h" #include "qeth_core_offl.h"
@@ -4497,7 +4496,7 @@ static int __init qeth_core_init(void) &driver_attr_group);if (rc) goto driver_err; - qeth_core_root_dev =s390_root_dev_register ("qeth" ); + qeth_core_root_dev =root_device_register ("qeth" ); rc =IS_ERR (qeth_core_root_dev) ?PTR_ERR (qeth_core_root_dev) :0 ;if (rc) goto register_err;
@@ -4511,7 +4510,7 @@ static int __init qeth_core_init(void)return 0 ; slab_err: -s390_root_dev_unregister (qeth_core_root_dev); +root_device_unregister (qeth_core_root_dev); register_err:driver_remove_file (&qeth_core_ccwgroup_driver.driver, &driver_attr_group);
@@ -4529,7 +4528,7 @@ out_err: static void __exit qeth_core_exit(void) { -s390_root_dev_unregister (qeth_core_root_dev); +root_device_unregister (qeth_core_root_dev);driver_remove_file (&qeth_core_ccwgroup_driver.driver, &driver_attr_group);ccwgroup_driver_unregister (&qeth_core_ccwgroup_driver);
drivers/s390/net/qeth_l2_main.c +0 -2
@@ -20,8 +20,6 @@#include <linux/mii.h> #include <linux/ip.h> -#include <asm/s390_rdev.h> -#include "qeth_core.h" #include "qeth_core_offl.h"
drivers/s390/net/qeth_l3_main.c +0 -2
@@ -26,8 +26,6 @@#include <net/ip.h> #include <net/arp.h> -#include <asm/s390_rdev.h> -#include "qeth_l3.h" #include "qeth_core_offl.h"
drivers/s390/s390_rdev.c deleted +0 -51
51 lines not on this page · raw message
net/iucv/iucv.c +3 -4
@@ -50,7 +50,6 @@#include <asm/ebcdic.h> #include <asm/io.h> #include <asm/s390_ext.h> -#include <asm/s390_rdev.h> #include <asm/smp.h> /*
@@ -1692,7 +1691,7 @@ static int __init iucv_init(void) rc =register_external_interrupt (0x4000 , iucv_external_interrupt);if (rc) goto out; - iucv_root =s390_root_dev_register ("iucv" ); + iucv_root =root_device_register ("iucv" );if (IS_ERR (iucv_root)) { rc =PTR_ERR (iucv_root); goto out_int;
@@ -1736,7 +1735,7 @@ out_free:kfree (iucv_irq_data[cpu]); iucv_irq_data[cpu] =NULL ; } -s390_root_dev_unregister (iucv_root); +root_device_unregister (iucv_root); out_int:unregister_external_interrupt (0x4000 , iucv_external_interrupt); out:
@@ -1766,7 +1765,7 @@ static void __exit iucv_exit(void)kfree (iucv_irq_data[cpu]); iucv_irq_data[cpu] =NULL ; } -s390_root_dev_unregister (iucv_root); +root_device_unregister (iucv_root);bus_unregister (&iucv_bus);unregister_external_interrupt (0x4000 , iucv_external_interrupt); }
Signature · 1 line
1.5.4.3
Re: [PATCH 2/4] virtio: do not statically allocate root device
In reply to Mark McLoughlinQuoted 3 lines · On Monday 15 December 2008 23:28:27 Mark McLoughlin wrote:
We shouldn't be statically allocating the root device object, so dynamically allocate it using
root_device_register()instead.
This and 3/4 which would normally go through me:
Thanks Greg,
Rusty.
Re: [PATCH 2/4] virtio: do not statically allocate root device
In reply to Mark McLoughlinQuoted 3 lines · On Monday 15 December 2008 23:28:27 Mark McLoughlin wrote:
We shouldn't be statically allocating the root device object, so dynamically allocate it using
root_device_register()instead.
This and 3/4 which would normally go through me:
Thanks Greg,
Rusty.