Re: dev->release = (void (*)(struct device *))kfree;

From: Benjamin Herrenschmidt (benh_at_kernel.crashing.org)
Date: 10/25/05

  • Next message: George Anzinger: "Re: [PATCH] 2.6.14-rc5 fails to build with out CONFIG_FUTEX"
    To: Pete Zaitcev <zaitcev@redhat.com>
    Date:	Tue, 25 Oct 2005 14:36:21 +1000
    
    

    On Mon, 2005-10-24 at 20:10 -0700, Pete Zaitcev wrote:
    > I seem to recall the discussion about this, but very dimly. Would someone
    > be so kind to remind me, why the attached patch cannot be used?

    If your struct device becomes a member of your vmlogrdr_priv structure,
    then you need to tie the lifetime of that structure to the one of the
    struct device kobject. Thus, you need to provide a "release" callback
    that frees your entire vmlogrdr_priv structure and of course not free it
    yourself (but simply consider it lost after you have called
    device_unregister).

    In addition, if you are in the module, you get into funky issues since
    you must make sure your free routine doesn't "go away" with your module
    before the object is freed (it may be held a long time in memory by some
    userland thing opening a sysfs file to it). If you set the owner field
    of the kobj, your module should be held there (but may become totally
    un-rmmod'able in some circumstances, how fun...)

    If you need to keep your vmlogrdr_priv structure around a little while
    longer after device_unregister(), just increase it's refcount before
    doing device_unregister() and drop it when you don't need it anymore. It
    will still be unregistered (removed from the various lists) but the
    release() callback won't be called until the last user.

    Ben.

    > -- Pete
    >
    > diff -urp -X dontdiff linux-2.6.14-rc5/drivers/s390/char/vmlogrdr.c linux-2.6.14-rc5-lem/drivers/s390/char/vmlogrdr.c
    > --- linux-2.6.14-rc5/drivers/s390/char/vmlogrdr.c 2005-09-13 01:06:11.000000000 -0700
    > +++ linux-2.6.14-rc5-lem/drivers/s390/char/vmlogrdr.c 2005-10-24 20:05:26.000000000 -0700
    > @@ -74,7 +74,7 @@ struct vmlogrdr_priv_t {
    > int buffer_free;
    > int dev_in_use; /* 1: already opened, 0: not opened*/
    > spinlock_t priv_lock;
    > - struct device *device;
    > + struct device device;
    > struct class_device *class_device;
    > int autorecording;
    > int autopurge;
    > @@ -756,27 +756,14 @@ vmlogrdr_unregister_driver(void) {
    >
    > static int
    > vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) {
    > - struct device *dev;
    > + struct device *dev = &priv->device;
    > int ret;
    >
    > - dev = kmalloc(sizeof(struct device), GFP_KERNEL);
    > - if (dev) {
    > - memset(dev, 0, sizeof(struct device));
    > - snprintf(dev->bus_id, BUS_ID_SIZE, "%s",
    > - priv->internal_name);
    > - dev->bus = &iucv_bus;
    > - dev->parent = iucv_root;
    > - dev->driver = &vmlogrdr_driver;
    > - /*
    > - * The release function could be called after the
    > - * module has been unloaded. It's _only_ task is to
    > - * free the struct. Therefore, we specify kfree()
    > - * directly here. (Probably a little bit obfuscating
    > - * but legitime ...).
    > - */
    > - dev->release = (void (*)(struct device *))kfree;
    > - } else
    > - return -ENOMEM;
    > + memset(dev, 0, sizeof(struct device));
    > + snprintf(dev->bus_id, BUS_ID_SIZE, "%s", priv->internal_name);
    > + dev->bus = &iucv_bus;
    > + dev->parent = iucv_root;
    > + dev->driver = &vmlogrdr_driver;
    > ret = device_register(dev);
    > if (ret)
    > return ret;
    > @@ -799,7 +786,6 @@ vmlogrdr_register_device(struct vmlogrdr
    > return ret;
    > }
    > dev->driver_data = priv;
    > - priv->device = dev;
    > return 0;
    > }
    >
    > @@ -807,11 +793,8 @@ vmlogrdr_register_device(struct vmlogrdr
    > static int
    > vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv ) {
    > class_device_destroy(vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num));
    > - if (priv->device != NULL) {
    > - sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group);
    > - device_unregister(priv->device);
    > - priv->device=NULL;
    > - }
    > + sysfs_remove_group(&priv->device.kobj, &vmlogrdr_attr_group);
    > + device_unregister(&priv->device);
    > return 0;
    > }
    >
    > -
    > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    > the body of a message to majordomo@vger.kernel.org
    > More majordomo info at http://vger.kernel.org/majordomo-info.html
    > Please read the FAQ at http://www.tux.org/lkml/

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


  • Next message: George Anzinger: "Re: [PATCH] 2.6.14-rc5 fails to build with out CONFIG_FUTEX"

    Relevant Pages

    • [DVB patch 29/54] usb: digitv: support for nxt6000 demod
      ... Add support for the NXT6000-based digitv-box. ... Add .get_tune_settings callback for the NXT6000 to have a min_tune_delay of 500ms. ... static int digitv_probe(struct usb_interface *intf, ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • [patch 14/22] USB: Adapt microtek driver to new scsi features
      ... the scsi layer now uses very short sg lists. ... +static int mts_slave_configure (struct scsi_device *s) ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • util-linux: losetup -a
      ... attached losetup patch adds "-a" option that lists all used loop devices. ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • Re: gjournal and zfs, questions
      ... It's the same as the other one available from the mailing lists ... this list of conditions and the following disclaimer in the ... +static void putcgs; ...
      (freebsd-questions)
    • Oops on APM wakeup on 2.4.22/23-pre, works with 2.6.0-test
      ... use 2.6.0 due to other problems such as unstable PCMCIA ... right now (have to solder null-modem cable first etc), ... the followups to me, I don't read the lists ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)