All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: linux-kernel@vger.kernel.org
Cc: Tejun Heo <tj@kernel.org>, Anton Vorontsov <cbou@mail.ru>,
	David Woodhouse <dwmw2@infradead.org>,
	Donggeun Kim <dg77.kim@samsung.com>,
	MyungJoo Ham <myungjoo.ham@samsung.com>
Subject: [PATCH 01/25] charger_manager: don't use [delayed_]work_pending()
Date: Fri, 21 Dec 2012 17:56:51 -0800	[thread overview]
Message-ID: <1356141435-17340-2-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1356141435-17340-1-git-send-email-tj@kernel.org>

There's no need to test whether a (delayed) work item in pending
before queueing, flushing or cancelling it.  Most uses are unnecessary
and quite a few of them are buggy.

Remove unnecessary pending tests and rewrite _setup_polling() so that
it uses mod_delayed_work() if the next polling interval is sooner than
currently scheduled.  queue_delayed_work() is used otherwise.

Only compile tested.  I noticed that two work items - setup_polling
and cm_monitor_work - schedule each other.  It's a very unusual
construct and I'm fairly sure it's racy.  You can't break such
circular dependency by calling cancel on each.  I strongly recommend
revising the mechanism.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Anton Vorontsov <cbou@mail.ru>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Donggeun Kim <dg77.kim@samsung.com>
Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
---
Please let me know how this patch should be routed.  I can take it
through the workqueue tree if necessary.

Thanks.

 drivers/power/charger-manager.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
index adb3a4b..9fd9776 100644
--- a/drivers/power/charger-manager.c
+++ b/drivers/power/charger-manager.c
@@ -675,15 +675,21 @@ static void _setup_polling(struct work_struct *work)
 	WARN(cm_wq == NULL, "charger-manager: workqueue not initialized"
 			    ". try it later. %s\n", __func__);
 
+	/*
+	 * Use mod_delayed_work() iff the next polling interval should
+	 * occur before the currently scheduled one.  If @cm_monitor_work
+	 * isn't active, the end result is the same, so no need to worry
+	 * about stale @next_polling.
+	 */
 	_next_polling = jiffies + polling_jiffy;
 
-	if (!delayed_work_pending(&cm_monitor_work) ||
-	    (delayed_work_pending(&cm_monitor_work) &&
-	     time_after(next_polling, _next_polling))) {
-		next_polling = jiffies + polling_jiffy;
+	if (time_before(_next_polling, next_polling)) {
 		mod_delayed_work(cm_wq, &cm_monitor_work, polling_jiffy);
+		next_polling = _next_polling;
+	} else {
+		if (queue_delayed_work(cm_wq, &cm_monitor_work, polling_jiffy))
+			next_polling = _next_polling;
 	}
-
 out:
 	mutex_unlock(&cm_list_mtx);
 }
@@ -757,8 +763,7 @@ static void misc_event_handler(struct charger_manager *cm,
 	if (cm_suspended)
 		device_set_wakeup_capable(cm->dev, true);
 
-	if (!delayed_work_pending(&cm_monitor_work) &&
-	    is_polling_required(cm) && cm->desc->polling_interval_ms)
+	if (is_polling_required(cm) && cm->desc->polling_interval_ms)
 		schedule_work(&setup_polling);
 	uevent_notify(cm, default_event_names[type]);
 }
@@ -1176,8 +1181,7 @@ static int charger_extcon_notifier(struct notifier_block *self,
 	 * when charger cable is attached.
 	 */
 	if (cable->attached && is_polling_required(cable->cm)) {
-		if (work_pending(&setup_polling))
-			cancel_work_sync(&setup_polling);
+		cancel_work_sync(&setup_polling);
 		schedule_work(&setup_polling);
 	}
 
@@ -1667,10 +1671,8 @@ static int charger_manager_remove(struct platform_device *pdev)
 	list_del(&cm->entry);
 	mutex_unlock(&cm_list_mtx);
 
-	if (work_pending(&setup_polling))
-		cancel_work_sync(&setup_polling);
-	if (delayed_work_pending(&cm_monitor_work))
-		cancel_delayed_work_sync(&cm_monitor_work);
+	cancel_work_sync(&setup_polling);
+	cancel_delayed_work_sync(&cm_monitor_work);
 
 	for (i = 0 ; i < desc->num_charger_regulators ; i++) {
 		struct charger_regulator *charger
@@ -1739,8 +1741,7 @@ static int cm_suspend_prepare(struct device *dev)
 		cm_suspended = true;
 	}
 
-	if (delayed_work_pending(&cm->fullbatt_vchk_work))
-		cancel_delayed_work(&cm->fullbatt_vchk_work);
+	cancel_delayed_work(&cm->fullbatt_vchk_work);
 	cm->status_save_ext_pwr_inserted = is_ext_pwr_online(cm);
 	cm->status_save_batt = is_batt_present(cm);
 
-- 
1.8.0.2


  reply	other threads:[~2012-12-22  1:57 UTC|newest]

Thread overview: 84+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-22  1:56 [PATCHSET] workqueue: don't use [delayed_]work_pending() Tejun Heo
2012-12-22  1:56 ` Tejun Heo [this message]
2013-01-05 22:11   ` [PATCH 01/25] charger_manager: " Anton Vorontsov
2012-12-22  1:56 ` [PATCH 02/25] ab8500_charger: " Tejun Heo
     [not found]   ` <CACRpkdYE3F22rnW+ZRhOWT4VGRhG2CSnb7Rj3gdCosTK8wLQmA@mail.gmail.com>
     [not found]     ` <50EAA53F.1000304@stericsson.com>
2013-01-07 10:48       ` Arun MURTHY
2013-01-08 14:30   ` Linus Walleij
2012-12-22  1:56 ` [PATCH 03/25] sja1000: " Tejun Heo
2012-12-22  8:01   ` David Miller
2012-12-28 21:40     ` Tejun Heo
2012-12-22  1:56 ` [PATCH 04/25] ipw2x00: simplify scan_event handling Tejun Heo
2013-01-27 21:02   ` Stanislav Yakovlev
2013-02-09 19:31     ` Tejun Heo
2012-12-22  1:56 ` [PATCH 05/25] devfreq: don't use [delayed_]work_pending() Tejun Heo
2012-12-22  1:56 ` [PATCH 06/25] libertas: " Tejun Heo
2012-12-22  1:56 ` [PATCH 07/25] mwifiex: " Tejun Heo
2012-12-22 22:29   ` Bing Zhao
2012-12-28 21:41     ` Tejun Heo
2012-12-22  1:56 ` [PATCH 08/25] thinkpad_acpi: " Tejun Heo
     [not found]   ` <1356141435-17340-9-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2012-12-22 23:55     ` Henrique de Moraes Holschuh
2012-12-22 23:55       ` Henrique de Moraes Holschuh
2012-12-28 21:41       ` Tejun Heo
2012-12-22  1:56 ` [PATCH 09/25] wl1251: " Tejun Heo
2012-12-22 14:14   ` Luciano Coelho
2012-12-28 21:42     ` Tejun Heo
2012-12-22  1:57 ` [PATCH 10/25] kprobes: fix wait_for_kprobe_optimizer() Tejun Heo
2012-12-25  3:51   ` Masami Hiramatsu
2013-01-28 19:49     ` Tejun Heo
2013-01-29 11:53       ` Masami Hiramatsu
2013-02-09 19:33         ` Tejun Heo
2012-12-22  1:57 ` [PATCH 11/25] pm: don't use [delayed_]work_pending() Tejun Heo
2012-12-22 11:53   ` Rafael J. Wysocki
2012-12-25 16:44     ` Tejun Heo
2012-12-22  1:57 ` [PATCH 12/25] bluetooth/l2cap: " Tejun Heo
2013-01-03 22:27   ` Gustavo Padovan
2012-12-22  1:57 ` [PATCH 13/25] sound/wm8350: " Tejun Heo
2012-12-24 16:11   ` Mark Brown
2012-12-22  1:57 ` [PATCH 14/25] rfkill: " Tejun Heo
2012-12-22 20:22   ` Johannes Berg
2012-12-28 21:42     ` Tejun Heo
2012-12-22  1:57 ` [PATCH 15/25] x86/mce: " Tejun Heo
2012-12-25 11:07   ` Borislav Petkov
2012-12-28 21:44     ` [PATCH v2 " Tejun Heo
2012-12-22  1:57 ` [PATCH 16/25] PM / Domains: " Tejun Heo
2012-12-22 11:57   ` Rafael J. Wysocki
2012-12-25 17:03     ` Tejun Heo
2012-12-25 20:33       ` Rafael J. Wysocki
2012-12-26  1:23         ` Tejun Heo
2012-12-22  1:57 ` [PATCH 17/25] wm97xx: " Tejun Heo
2012-12-23  9:54   ` Dmitry Torokhov
2012-12-24 16:18     ` Mark Brown
2013-03-09 23:53       ` Dmitry Torokhov
2013-03-12 18:49         ` Mark Brown
2012-12-24 18:25     ` Tejun Heo
2012-12-22  1:57 ` [PATCH 18/25] TMIO MMC: " Tejun Heo
2012-12-24 22:31   ` Guennadi Liakhovetski
2012-12-22  1:57 ` [PATCH 19/25] net/caif: " Tejun Heo
2012-12-22  1:57 ` [PATCH 20/25] wimax/i2400m: fix i2400m->wake_tx_skb handling Tejun Heo
2012-12-22 15:28   ` Perez-Gonzalez, Inaky
2013-01-04 21:19   ` Dan Williams
2013-02-09 19:35     ` Tejun Heo
2012-12-22  1:57 ` [PATCH 21/25] tty/max3100: don't use [delayed_]work_pending() Tejun Heo
2012-12-22  4:21   ` Greg Kroah-Hartman
2012-12-28 21:44     ` Tejun Heo
2012-12-22  1:57 ` [PATCH 22/25] usb/at91_udc: " Tejun Heo
2013-01-07 16:25   ` Nicolas Ferre
2012-12-22  1:57 ` [PATCH 23/25] video/exynos: " Tejun Heo
2012-12-22  3:05   ` Kukjin Kim
2012-12-26  4:04     ` Jingoo Han
2012-12-28 21:44       ` 'Tejun Heo'
2012-12-22  1:57 ` [PATCH 24/25] debugobjects: " Tejun Heo
2012-12-22  1:57 ` [PATCH 25/25] ipc: " Tejun Heo
2012-12-22  2:15   ` Andrew Morton
2012-12-22  2:22     ` Tejun Heo
2012-12-22 11:09       ` Borislav Petkov
2012-12-24 18:33         ` Tejun Heo
2012-12-24 18:45           ` Tejun Heo
2012-12-24 19:41             ` Borislav Petkov
2012-12-25  3:29               ` Tejun Heo
2012-12-25 10:46                 ` Borislav Petkov
2012-12-25 16:35                   ` Tejun Heo
2012-12-24 18:55           ` Borislav Petkov
2012-12-24 19:07             ` Tejun Heo
2012-12-24 19:32               ` Borislav Petkov
2012-12-25  3:18                 ` Tejun Heo

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=1356141435-17340-2-git-send-email-tj@kernel.org \
    --to=tj@kernel.org \
    --cc=cbou@mail.ru \
    --cc=dg77.kim@samsung.com \
    --cc=dwmw2@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=myungjoo.ham@samsung.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.