All of lore.kernel.org
 help / color / mirror / Atom feed
From: johnpol@2ka.mipt.ru (Evgeniy Polyakov)
To: Dmitry Torokhov <dtor_core@ameritech.net>
Cc: sensors@stimpy.netroedge.com, LKML <linux-kernel@vger.kernel.org>,
	Greg KH <gregkh@suse.de>
Subject: [RFC/PATCH 0/22] W1: sysfs, lifetime and other fixes
Date: Thu, 19 May 2005 06:25:55 +0000	[thread overview]
Message-ID: <1114500911.8527.105.camel@uganda> (raw)
In-Reply-To: <200504260216.10560.dtor_core@ameritech.net>

On Tue, 2005-04-26 at 02:16 -0500, Dmitry Torokhov wrote:

> > > > It has explicit barrieres, which guarantees that
> > > > there will not be atomic operation vs. non atomic
> > > > reordering. 
> > > 
> > > And you can't use explicit barriers - why exactly?
> > 
> > I used them - code was following:
> > smp_mb__before_atomic_dec();
> > atomic_dec();
> > smp_mb__after_atomic_dec();
> > 
> > I think simple atomic_dec_and_test() or even atomic_dec_and_lock()
> > is better.
> 
> This is usually indicates that there some kiond of a problem. Consider
> following fragment:
> 
> > +static void cn_queue_wrapper(void *data)
> > +{
> > +       struct cn_callback_entry *cbq = (struct cn_callback_entry *)data;
> > +
> > +       atomic_inc_and_test(&cbq->cb->refcnt);
> > +       cbq->cb->callback(cbq->cb->priv);
> > +       atomic_dec_and_test(&cbq->cb->refcnt);
> > 
> 
> What exactly this refcount protects? Can it be that other code decrements
> refcount and frees the object right when one CPU is entering this function?
> If not that means that cb structure is protected by some other means, so
> why we need to increment refcout here and consider ordering?

It does not needed there. I pointed it to Andrew when we discuss it 
couple of weeks ago, but forget to remove.

> Btw, cb refcount can be complelely removed, something like the patch below
> (won't apply cleanly as I have some other stuff).

I will think of it some more, probably you are right,
it looks like flush_workqueue() is sufficient for that.

> -- 
> Dmitry
> 
>  drivers/connector/cn_queue.c |   85 +++++++++++--------------------------------
>  include/linux/connector.h    |    2 -
>  2 files changed, 23 insertions(+), 64 deletions(-)
> 
> Index: linux-2.6.11/drivers/connector/cn_queue.c
> =================================> --- linux-2.6.11.orig/drivers/connector/cn_queue.c
> +++ linux-2.6.11/drivers/connector/cn_queue.c
> @@ -33,49 +33,12 @@
>  
>  static void cn_queue_wrapper(void *data)
>  {
> -	struct cn_callback_entry *cbq = (struct cn_callback_entry *)data;
> +	struct cn_callback_entry *cbq = data;
>  
> -	atomic_inc_and_test(&cbq->cb->refcnt);
>  	cbq->cb->callback(cbq->cb->priv);
> -	atomic_dec_and_test(&cbq->cb->refcnt);
> -
>  	cbq->destruct_data(cbq->ddata);
>  }
>  
> -static struct cn_callback_entry *cn_queue_alloc_callback_entry(struct cn_callback *cb)
> -{
> -	struct cn_callback_entry *cbq;
> -
> -	cbq = kmalloc(sizeof(*cbq), GFP_KERNEL);
> -	if (!cbq) {
> -		printk(KERN_ERR "Failed to create new callback queue.\n");
> -		return NULL;
> -	}
> -
> -	memset(cbq, 0, sizeof(*cbq));
> -
> -	cbq->cb = cb;
> -
> -	INIT_WORK(&cbq->work, &cn_queue_wrapper, cbq);
> -
> -	return cbq;
> -}
> -
> -static void cn_queue_free_callback(struct cn_callback_entry *cbq)
> -{
> -	cancel_delayed_work(&cbq->work);
> -	flush_workqueue(cbq->pdev->cn_queue);
> -
> -	while (atomic_read(&cbq->cb->refcnt)) {
> -		printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n",
> -		       cbq->pdev->name, atomic_read(&cbq->cb->refcnt));
> -
> -		msleep(1000);
> -	}
> -
> -	kfree(cbq);
> -}
> -
>  int cn_cb_equal(struct cb_id *i1, struct cb_id *i2)
>  {
>  #if 0
> @@ -90,40 +53,37 @@ int cn_cb_equal(struct cb_id *i1, struct
>  int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb)
>  {
>  	struct cn_callback_entry *cbq, *__cbq;
> -	int found = 0;
> +	int retval = 0;
>  
> -	cbq = cn_queue_alloc_callback_entry(cb);
> -	if (!cbq)
> +	cbq = kmalloc(sizeof(*cbq), GFP_KERNEL);
> +	if (!cbq) {
> +		printk(KERN_ERR "Failed to create new callback queue.\n");
>  		return -ENOMEM;
> +	}
>  
>  	atomic_inc(&dev->refcnt);
> +
> +	memset(cbq, 0, sizeof(*cbq));
> +	INIT_WORK(&cbq->work, &cn_queue_wrapper, cbq);
> +	cbq->cb = cb;
>  	cbq->pdev = dev;
> +	cbq->nls = dev->nls;
> +	cbq->seq = 0;
> +	cbq->group = cbq->cb->id.idx;
>  
>  	spin_lock_bh(&dev->queue_lock);
> +
>  	list_for_each_entry(__cbq, &dev->queue_list, callback_entry) {
>  		if (cn_cb_equal(&__cbq->cb->id, &cb->id)) {
> -			found = 1;
> -			break;
> +			retval = -EEXIST;
> +			kfree(cbq);
> +			goto out;
>  		}
>  	}
> -	if (!found) {
> -		atomic_set(&cbq->cb->refcnt, 1);
> -		list_add_tail(&cbq->callback_entry, &dev->queue_list);
> -	}
> +	list_add_tail(&cbq->callback_entry, &dev->queue_list);
> + out:
>  	spin_unlock_bh(&dev->queue_lock);
> -
> -	if (found) {
> -		atomic_dec(&dev->refcnt);
> -		atomic_set(&cbq->cb->refcnt, 0);
> -		cn_queue_free_callback(cbq);
> -		return -EINVAL;
> -	}
> -
> -	cbq->nls = dev->nls;
> -	cbq->seq = 0;
> -	cbq->group = cbq->cb->id.idx;
> -
> -	return 0;
> +	return retval;
>  }
>  
>  void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id)
> @@ -142,8 +102,9 @@ void cn_queue_del_callback(struct cn_que
>  	spin_unlock_bh(&dev->queue_lock);
>  
>  	if (found) {
> -		atomic_dec(&cbq->cb->refcnt);
> -		cn_queue_free_callback(cbq);
> +		cancel_delayed_work(&cbq->work);
> +		flush_workqueue(cbq->pdev->cn_queue);
> +		kfree(cbq);
>  		atomic_dec_and_test(&dev->refcnt);
>  	}
>  }
> Index: linux-2.6.11/include/linux/connector.h
> =================================> --- linux-2.6.11.orig/include/linux/connector.h
> +++ linux-2.6.11/include/linux/connector.h
> @@ -115,8 +115,6 @@ struct cn_callback
>  	struct cb_id		id;
>  	void			(* callback)(void *);
>  	void			*priv;
> -
> -	atomic_t		refcnt;
>  };
>  
>  struct cn_callback_entry
-- 
        Evgeniy Polyakov

Crash is better than data corruption -- Arthur Grabowski
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://lists.lm-sensors.org/pipermail/lm-sensors/attachments/20050426/b22d8e15/attachment.bin

WARNING: multiple messages have this Message-ID (diff)
From: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
To: Dmitry Torokhov <dtor_core@ameritech.net>
Cc: sensors@stimpy.netroedge.com, LKML <linux-kernel@vger.kernel.org>,
	Greg KH <gregkh@suse.de>
Subject: Re: [RFC/PATCH 0/22] W1: sysfs, lifetime and other fixes
Date: Tue, 26 Apr 2005 11:35:11 +0400	[thread overview]
Message-ID: <1114500911.8527.105.camel@uganda> (raw)
In-Reply-To: <200504260216.10560.dtor_core@ameritech.net>

[-- Attachment #1: Type: text/plain, Size: 5722 bytes --]

On Tue, 2005-04-26 at 02:16 -0500, Dmitry Torokhov wrote:

> > > > It has explicit barrieres, which guarantees that
> > > > there will not be atomic operation vs. non atomic
> > > > reordering. 
> > > 
> > > And you can't use explicit barriers - why exactly?
> > 
> > I used them - code was following:
> > smp_mb__before_atomic_dec();
> > atomic_dec();
> > smp_mb__after_atomic_dec();
> > 
> > I think simple atomic_dec_and_test() or even atomic_dec_and_lock()
> > is better.
> 
> This is usually indicates that there some kiond of a problem. Consider
> following fragment:
> 
> > +static void cn_queue_wrapper(void *data)
> > +{
> > +       struct cn_callback_entry *cbq = (struct cn_callback_entry *)data;
> > +
> > +       atomic_inc_and_test(&cbq->cb->refcnt);
> > +       cbq->cb->callback(cbq->cb->priv);
> > +       atomic_dec_and_test(&cbq->cb->refcnt);
> > 
> 
> What exactly this refcount protects? Can it be that other code decrements
> refcount and frees the object right when one CPU is entering this function?
> If not that means that cb structure is protected by some other means, so
> why we need to increment refcout here and consider ordering?

It does not needed there. I pointed it to Andrew when we discuss it 
couple of weeks ago, but forget to remove.

> Btw, cb refcount can be complelely removed, something like the patch below
> (won't apply cleanly as I have some other stuff).

I will think of it some more, probably you are right,
it looks like flush_workqueue() is sufficient for that.

> -- 
> Dmitry
> 
>  drivers/connector/cn_queue.c |   85 +++++++++++--------------------------------
>  include/linux/connector.h    |    2 -
>  2 files changed, 23 insertions(+), 64 deletions(-)
> 
> Index: linux-2.6.11/drivers/connector/cn_queue.c
> ===================================================================
> --- linux-2.6.11.orig/drivers/connector/cn_queue.c
> +++ linux-2.6.11/drivers/connector/cn_queue.c
> @@ -33,49 +33,12 @@
>  
>  static void cn_queue_wrapper(void *data)
>  {
> -	struct cn_callback_entry *cbq = (struct cn_callback_entry *)data;
> +	struct cn_callback_entry *cbq = data;
>  
> -	atomic_inc_and_test(&cbq->cb->refcnt);
>  	cbq->cb->callback(cbq->cb->priv);
> -	atomic_dec_and_test(&cbq->cb->refcnt);
> -
>  	cbq->destruct_data(cbq->ddata);
>  }
>  
> -static struct cn_callback_entry *cn_queue_alloc_callback_entry(struct cn_callback *cb)
> -{
> -	struct cn_callback_entry *cbq;
> -
> -	cbq = kmalloc(sizeof(*cbq), GFP_KERNEL);
> -	if (!cbq) {
> -		printk(KERN_ERR "Failed to create new callback queue.\n");
> -		return NULL;
> -	}
> -
> -	memset(cbq, 0, sizeof(*cbq));
> -
> -	cbq->cb = cb;
> -
> -	INIT_WORK(&cbq->work, &cn_queue_wrapper, cbq);
> -
> -	return cbq;
> -}
> -
> -static void cn_queue_free_callback(struct cn_callback_entry *cbq)
> -{
> -	cancel_delayed_work(&cbq->work);
> -	flush_workqueue(cbq->pdev->cn_queue);
> -
> -	while (atomic_read(&cbq->cb->refcnt)) {
> -		printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n",
> -		       cbq->pdev->name, atomic_read(&cbq->cb->refcnt));
> -
> -		msleep(1000);
> -	}
> -
> -	kfree(cbq);
> -}
> -
>  int cn_cb_equal(struct cb_id *i1, struct cb_id *i2)
>  {
>  #if 0
> @@ -90,40 +53,37 @@ int cn_cb_equal(struct cb_id *i1, struct
>  int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb)
>  {
>  	struct cn_callback_entry *cbq, *__cbq;
> -	int found = 0;
> +	int retval = 0;
>  
> -	cbq = cn_queue_alloc_callback_entry(cb);
> -	if (!cbq)
> +	cbq = kmalloc(sizeof(*cbq), GFP_KERNEL);
> +	if (!cbq) {
> +		printk(KERN_ERR "Failed to create new callback queue.\n");
>  		return -ENOMEM;
> +	}
>  
>  	atomic_inc(&dev->refcnt);
> +
> +	memset(cbq, 0, sizeof(*cbq));
> +	INIT_WORK(&cbq->work, &cn_queue_wrapper, cbq);
> +	cbq->cb = cb;
>  	cbq->pdev = dev;
> +	cbq->nls = dev->nls;
> +	cbq->seq = 0;
> +	cbq->group = cbq->cb->id.idx;
>  
>  	spin_lock_bh(&dev->queue_lock);
> +
>  	list_for_each_entry(__cbq, &dev->queue_list, callback_entry) {
>  		if (cn_cb_equal(&__cbq->cb->id, &cb->id)) {
> -			found = 1;
> -			break;
> +			retval = -EEXIST;
> +			kfree(cbq);
> +			goto out;
>  		}
>  	}
> -	if (!found) {
> -		atomic_set(&cbq->cb->refcnt, 1);
> -		list_add_tail(&cbq->callback_entry, &dev->queue_list);
> -	}
> +	list_add_tail(&cbq->callback_entry, &dev->queue_list);
> + out:
>  	spin_unlock_bh(&dev->queue_lock);
> -
> -	if (found) {
> -		atomic_dec(&dev->refcnt);
> -		atomic_set(&cbq->cb->refcnt, 0);
> -		cn_queue_free_callback(cbq);
> -		return -EINVAL;
> -	}
> -
> -	cbq->nls = dev->nls;
> -	cbq->seq = 0;
> -	cbq->group = cbq->cb->id.idx;
> -
> -	return 0;
> +	return retval;
>  }
>  
>  void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id)
> @@ -142,8 +102,9 @@ void cn_queue_del_callback(struct cn_que
>  	spin_unlock_bh(&dev->queue_lock);
>  
>  	if (found) {
> -		atomic_dec(&cbq->cb->refcnt);
> -		cn_queue_free_callback(cbq);
> +		cancel_delayed_work(&cbq->work);
> +		flush_workqueue(cbq->pdev->cn_queue);
> +		kfree(cbq);
>  		atomic_dec_and_test(&dev->refcnt);
>  	}
>  }
> Index: linux-2.6.11/include/linux/connector.h
> ===================================================================
> --- linux-2.6.11.orig/include/linux/connector.h
> +++ linux-2.6.11/include/linux/connector.h
> @@ -115,8 +115,6 @@ struct cn_callback
>  	struct cb_id		id;
>  	void			(* callback)(void *);
>  	void			*priv;
> -
> -	atomic_t		refcnt;
>  };
>  
>  struct cn_callback_entry
-- 
        Evgeniy Polyakov

Crash is better than data corruption -- Arthur Grabowski

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

  reply	other threads:[~2005-05-19  6:25 UTC|newest]

Thread overview: 88+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-04-21  7:07 [RFC/PATCH 0/22] W1: sysfs, lifetime and other fixes Dmitry Torokhov
2005-05-19  6:25 ` Dmitry Torokhov
2005-04-21  7:08 ` [RFC/PATCH 1/22] W1: whitespace fixes Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:08 ` [RFC/PATCH 2/22] W1: formatting fixes Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:09 ` [RFC/PATCH 3/22] W1: use attribute group for master's attributes Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:10 ` [RFC/PATCH 4/22] W1: use attribute group for slave's attributes Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:11 ` [RFC/PATCH 5/22] W1: list handling cleanup Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:13 ` [RFC/PATCH 6/22] W1: drop owner field from master and slave structures Dmitry Torokhov
2005-05-19  6:25   ` [RFC/PATCH 6/22] W1: drop owner field from master and slave Dmitry Torokhov
2005-04-21  7:13 ` [RFC/PATCH 7/22] W1: bus operations cleanup Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:15 ` [RFC/PATCH 8/22] W1: merge master code into one file Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:16 ` [RFC/PATCH 9/22] W1: drop custom hotplug over netlink notification Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:17 ` [RFC/PATCH 10/22] W1: drop main control thread Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:18 ` [RFC/PATCH 11/22] W1: move w1_search to the rest of IO code Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:19 ` [RFC/PATCH 12/22] W1: drop unneeded master attributes Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:20 ` [RFC/PATCH 13/22] W1: cleanup master attributes handling Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:21 ` [RFC/PATCH 14/22] W1: rename timeout to scan_interval Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:22 ` [RFC/PATCH 15/22] W1: add slave_ttl master attribute Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:23 ` [RFC/PATCH 16/22] W1: cleanup masters refcounting & more Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:23 ` [RFC/PATCH 17/22] W1: cleanup slave " Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:25 ` [RFC/PATCH 18/22] W1: cleanup family implementation Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:26 ` [RFC/PATCH 19/22] W1: convert families to be proper sysfs rivers Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:27 ` [RFC/PATCH 20/22] W1: add w1_device_id/MODULE_DEVICE_TABLE for automatic driver loading Dmitry Torokhov
2005-05-19  6:25   ` [RFC/PATCH 20/22] W1: add w1_device_id/MODULE_DEVICE_TABLE for Dmitry Torokhov
2005-04-21  7:36 ` [RFC/PATCH 21/22] W1: implement standard hotplug handler Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21  7:38 ` [RFC/PATCH 22/22] W1: expose module parameters in sysfs Dmitry Torokhov
2005-05-19  6:25   ` Dmitry Torokhov
2005-04-21 13:18 ` [RFC/PATCH 0/22] W1: sysfs, lifetime and other fixes Evgeniy Polyakov
2005-05-19  6:25   ` Evgeniy Polyakov
2005-04-21 14:31   ` Dmitry Torokhov
2005-05-19  6:25     ` Dmitry Torokhov
2005-04-25  9:08     ` Evgeniy Polyakov
2005-05-19  6:25       ` Evgeniy Polyakov
2005-04-25 16:32       ` Dmitry Torokhov
2005-05-19  6:25         ` Dmitry Torokhov
2005-04-25 19:26         ` Evgeniy Polyakov
2005-05-19  6:25           ` Evgeniy Polyakov
2005-04-25 21:32           ` Dmitry Torokhov
2005-05-19  6:25             ` Dmitry Torokhov
2005-04-26  7:19             ` Evgeniy Polyakov
2005-05-19  6:25               ` Evgeniy Polyakov
2005-04-25 20:15         ` Evgeniy Polyakov
2005-05-19  6:25           ` Evgeniy Polyakov
2005-04-25 20:22           ` Dmitry Torokhov
2005-05-19  6:25             ` Dmitry Torokhov
2005-04-26  6:43             ` Evgeniy Polyakov
2005-05-19  6:25               ` Evgeniy Polyakov
2005-04-26  6:50               ` Dmitry Torokhov
2005-05-19  6:25                 ` Dmitry Torokhov
2005-04-26  7:06                 ` Evgeniy Polyakov
2005-05-19  6:25                   ` Evgeniy Polyakov
2005-04-26  7:16                   ` Dmitry Torokhov
2005-05-19  6:25                     ` Dmitry Torokhov
2005-04-26  7:35                     ` Evgeniy Polyakov [this message]
2005-05-19  6:25                       ` Evgeniy Polyakov
2005-04-26  7:00               ` Greg KH
2005-05-19  6:25                 ` Greg KH
2005-04-26  7:17                 ` Evgeniy Polyakov
2005-05-19  6:25                   ` Evgeniy Polyakov
2005-04-26  6:58         ` Greg KH
2005-05-19  6:25           ` Greg KH
2005-04-21 16:09   ` Dmitry Torokhov
2005-05-19  6:25     ` Dmitry Torokhov
2005-04-25  9:11     ` Evgeniy Polyakov
2005-05-19  6:25       ` Evgeniy Polyakov
2005-04-25 16:36       ` Dmitry Torokhov
2005-05-19  6:25         ` Dmitry Torokhov
2005-04-25 19:32         ` Evgeniy Polyakov
2005-05-19  6:25           ` Evgeniy Polyakov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1114500911.8527.105.camel@uganda \
    --to=johnpol@2ka.mipt.ru \
    --cc=dtor_core@ameritech.net \
    --cc=gregkh@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sensors@stimpy.netroedge.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.