From: dtor_core@ameritech.net (Dmitry Torokhov)
To: sensors@Stimpy.netroedge.com
Cc: LKML <linux-kernel@vger.kernel.org>, Greg KH <gregkh@suse.de>,
Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Subject: [RFC/PATCH 10/22] W1: drop main control thread
Date: Thu, 19 May 2005 06:25:53 +0000 [thread overview]
Message-ID: <200504210217.05859.dtor_core@ameritech.net> (raw)
In-Reply-To: <200504210207.02421.dtor_core@ameritech.net>
W1: Drop control thread from w1 core, whatever it does can
also be done in the context of w1_remove_master_device.
Also, pin the module when registering new master device
to make sure that w1 core is not unloaded until last
device is gone. This simplifies logic a lot.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
w1.c | 157 +++++++++++++++----------------------------------------------------
w1.h | 1
2 files changed, 36 insertions(+), 122 deletions(-)
Index: dtor/drivers/w1/w1.c
=================================--- dtor.orig/drivers/w1/w1.c
+++ dtor/drivers/w1/w1.c
@@ -50,14 +50,8 @@ module_param_named(timeout, w1_timeout,
module_param_named(max_slave_count, w1_max_slave_count, int, 0);
module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
-static DEFINE_SPINLOCK(w1_mlock);
-static LIST_HEAD(w1_masters);
static u32 w1_ids = 1;
-static pid_t control_thread;
-static int control_needs_exit;
-static DECLARE_COMPLETION(w1_control_complete);
-
static int w1_master_match(struct device *dev, struct device_driver *drv)
{
return 1;
@@ -582,66 +576,6 @@ void w1_search(struct w1_master *dev)
}
-static int w1_control(void *data)
-{
- struct w1_slave *slave, *nexts;
- struct w1_master *master, *nextm;
- int err, have_to_wait = 0;
-
- daemonize("w1_control");
- allow_signal(SIGTERM);
-
- while (!control_needs_exit || have_to_wait) {
- have_to_wait = 0;
-
- try_to_freeze(PF_FREEZE);
- msleep_interruptible(w1_timeout * 1000);
-
- if (signal_pending(current))
- flush_signals(current);
-
- list_for_each_entry_safe(master, nextm, &w1_masters, node) {
-
- if (!control_needs_exit && !master->need_exit)
- continue;
- /*
- * Little race: we can create thread but not set the flag.
- * Get a chance for external process to set flag up.
- */
- if (!master->initialized) {
- have_to_wait = 1;
- continue;
- }
-
- spin_lock(&w1_mlock);
- list_del(&master->node);
- spin_unlock(&w1_mlock);
-
- if (control_needs_exit) {
- master->need_exit = 1;
-
- err = kill_proc(master->kpid, SIGTERM, 1);
- if (err)
- dev_err(&master->dev,
- "Failed to send signal to w1 kernel thread %d.\n",
- master->kpid);
- }
-
- wait_for_completion(&master->dev_exited);
-
- list_for_each_entry_safe(slave, nexts, &master->slist, node) {
- list_del(&slave->node);
- w1_slave_detach(slave);
- kfree(slave);
- }
- w1_destroy_master_attributes(master);
- atomic_dec(&master->refcnt);
- }
- }
-
- complete_and_exit(&w1_control_complete, 0);
-}
-
static int w1_process(void *data)
{
struct w1_master *dev = (struct w1_master *) data;
@@ -731,12 +665,22 @@ struct w1_master *w1_allocate_master_dev
return dev;
}
-static void w1_free_dev(struct w1_master *dev)
+static void w1_free_master_dev(struct w1_master *dev)
{
device_unregister(&dev->dev);
kfree(dev);
}
+static void w1_stop_master_device(struct w1_master *dev)
+{
+ dev->need_exit = 1;
+ if (kill_proc(dev->kpid, SIGTERM, 1))
+ dev_err(&dev->dev,
+ "Failed to send signal to w1 kernel thread %d.\n",
+ dev->kpid);
+ wait_for_completion(&dev->dev_exited);
+}
+
int w1_add_master_device(struct w1_master *dev)
{
int error;
@@ -762,36 +706,32 @@ int w1_add_master_device(struct w1_maste
dev->initialized = 1;
- spin_lock(&w1_mlock);
- list_add(&dev->node, &w1_masters);
- spin_unlock(&w1_mlock);
+ __module_get(THIS_MODULE);
return 0;
err_out_kill_thread:
- dev->need_exit = 1;
- if (kill_proc(dev->kpid, SIGTERM, 1))
- dev_err(&dev->dev,
- "Failed to send signal to w1 kernel thread %d.\n",
- dev->kpid);
- wait_for_completion(&dev->dev_exited);
+ w1_stop_master_device(dev);
err_out_free_dev:
- w1_free_dev(dev);
+ w1_free_master_dev(dev);
return error;
}
void w1_remove_master_device(struct w1_master *dev)
{
- int err;
+ struct w1_slave *slave, *next;
- dev->need_exit = 1;
- err = kill_proc(dev->kpid, SIGTERM, 1);
- if (err)
- dev_err(&dev->dev,
- "%s: Failed to send signal to w1 kernel thread %d.\n",
- __func__, dev->kpid);
+ w1_stop_master_device(dev);
+
+ list_for_each_entry_safe(slave, next, &dev->slist, node) {
+ list_del(&slave->node);
+ w1_slave_detach(slave);
+ kfree(slave);
+ }
+
+ w1_destroy_master_attributes(dev);
while (atomic_read(&dev->refcnt)) {
printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n",
@@ -801,61 +741,36 @@ void w1_remove_master_device(struct w1_m
flush_signals(current);
}
- w1_free_dev(dev);
+ w1_free_master_dev(dev);
+ module_put(THIS_MODULE);
}
int w1_init(void)
{
- int retval;
+ int error;
printk(KERN_INFO "Driver for 1-wire Dallas network protocol.\n");
- retval = bus_register(&w1_bus_type);
- if (retval) {
- printk(KERN_ERR "Failed to register bus. err=%d.\n", retval);
- goto err_out_exit_init;
+ error = bus_register(&w1_bus_type);
+ if (error) {
+ printk(KERN_ERR "Failed to register bus. err=%d.\n", error);
+ return error;
}
- retval = driver_register(&w1_driver);
- if (retval) {
+ error = driver_register(&w1_driver);
+ if (error) {
printk(KERN_ERR
- "Failed to register master driver. err=%d.\n",
- retval);
- goto err_out_bus_unregister;
- }
-
- control_thread = kernel_thread(&w1_control, NULL, 0);
- if (control_thread < 0) {
- printk(KERN_ERR "Failed to create control thread. err=%d\n",
- control_thread);
- retval = control_thread;
- goto err_out_driver_unregister;
+ "Failed to register master driver. err=%d.\n", error);
+ bus_unregister(&w1_bus_type);
+ return error;
}
return 0;
-
-err_out_driver_unregister:
- driver_unregister(&w1_driver);
-
-err_out_bus_unregister:
- bus_unregister(&w1_bus_type);
-
-err_out_exit_init:
- return retval;
}
void w1_fini(void)
{
- struct w1_master *master, *next;
-
- list_for_each_entry_safe(master, next, &w1_masters, node)
- w1_remove_master_device(master);
-
- control_needs_exit = 1;
-
- wait_for_completion(&w1_control_complete);
-
driver_unregister(&w1_driver);
bus_unregister(&w1_bus_type);
}
Index: dtor/drivers/w1/w1.h
=================================--- dtor.orig/drivers/w1/w1.h
+++ dtor/drivers/w1/w1.h
@@ -103,7 +103,6 @@ struct w1_bus_ops
struct w1_master
{
- struct list_head node;
unsigned char name[W1_MAXNAMELEN];
struct list_head slist;
int max_slave_count, slave_count;
WARNING: multiple messages have this Message-ID (diff)
From: Dmitry Torokhov <dtor_core@ameritech.net>
To: sensors@Stimpy.netroedge.com
Cc: LKML <linux-kernel@vger.kernel.org>, Greg KH <gregkh@suse.de>,
Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Subject: [RFC/PATCH 10/22] W1: drop main control thread
Date: Thu, 21 Apr 2005 02:17:04 -0500 [thread overview]
Message-ID: <200504210217.05859.dtor_core@ameritech.net> (raw)
In-Reply-To: <200504210207.02421.dtor_core@ameritech.net>
W1: Drop control thread from w1 core, whatever it does can
also be done in the context of w1_remove_master_device.
Also, pin the module when registering new master device
to make sure that w1 core is not unloaded until last
device is gone. This simplifies logic a lot.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
w1.c | 157 +++++++++++++++----------------------------------------------------
w1.h | 1
2 files changed, 36 insertions(+), 122 deletions(-)
Index: dtor/drivers/w1/w1.c
===================================================================
--- dtor.orig/drivers/w1/w1.c
+++ dtor/drivers/w1/w1.c
@@ -50,14 +50,8 @@ module_param_named(timeout, w1_timeout,
module_param_named(max_slave_count, w1_max_slave_count, int, 0);
module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
-static DEFINE_SPINLOCK(w1_mlock);
-static LIST_HEAD(w1_masters);
static u32 w1_ids = 1;
-static pid_t control_thread;
-static int control_needs_exit;
-static DECLARE_COMPLETION(w1_control_complete);
-
static int w1_master_match(struct device *dev, struct device_driver *drv)
{
return 1;
@@ -582,66 +576,6 @@ void w1_search(struct w1_master *dev)
}
-static int w1_control(void *data)
-{
- struct w1_slave *slave, *nexts;
- struct w1_master *master, *nextm;
- int err, have_to_wait = 0;
-
- daemonize("w1_control");
- allow_signal(SIGTERM);
-
- while (!control_needs_exit || have_to_wait) {
- have_to_wait = 0;
-
- try_to_freeze(PF_FREEZE);
- msleep_interruptible(w1_timeout * 1000);
-
- if (signal_pending(current))
- flush_signals(current);
-
- list_for_each_entry_safe(master, nextm, &w1_masters, node) {
-
- if (!control_needs_exit && !master->need_exit)
- continue;
- /*
- * Little race: we can create thread but not set the flag.
- * Get a chance for external process to set flag up.
- */
- if (!master->initialized) {
- have_to_wait = 1;
- continue;
- }
-
- spin_lock(&w1_mlock);
- list_del(&master->node);
- spin_unlock(&w1_mlock);
-
- if (control_needs_exit) {
- master->need_exit = 1;
-
- err = kill_proc(master->kpid, SIGTERM, 1);
- if (err)
- dev_err(&master->dev,
- "Failed to send signal to w1 kernel thread %d.\n",
- master->kpid);
- }
-
- wait_for_completion(&master->dev_exited);
-
- list_for_each_entry_safe(slave, nexts, &master->slist, node) {
- list_del(&slave->node);
- w1_slave_detach(slave);
- kfree(slave);
- }
- w1_destroy_master_attributes(master);
- atomic_dec(&master->refcnt);
- }
- }
-
- complete_and_exit(&w1_control_complete, 0);
-}
-
static int w1_process(void *data)
{
struct w1_master *dev = (struct w1_master *) data;
@@ -731,12 +665,22 @@ struct w1_master *w1_allocate_master_dev
return dev;
}
-static void w1_free_dev(struct w1_master *dev)
+static void w1_free_master_dev(struct w1_master *dev)
{
device_unregister(&dev->dev);
kfree(dev);
}
+static void w1_stop_master_device(struct w1_master *dev)
+{
+ dev->need_exit = 1;
+ if (kill_proc(dev->kpid, SIGTERM, 1))
+ dev_err(&dev->dev,
+ "Failed to send signal to w1 kernel thread %d.\n",
+ dev->kpid);
+ wait_for_completion(&dev->dev_exited);
+}
+
int w1_add_master_device(struct w1_master *dev)
{
int error;
@@ -762,36 +706,32 @@ int w1_add_master_device(struct w1_maste
dev->initialized = 1;
- spin_lock(&w1_mlock);
- list_add(&dev->node, &w1_masters);
- spin_unlock(&w1_mlock);
+ __module_get(THIS_MODULE);
return 0;
err_out_kill_thread:
- dev->need_exit = 1;
- if (kill_proc(dev->kpid, SIGTERM, 1))
- dev_err(&dev->dev,
- "Failed to send signal to w1 kernel thread %d.\n",
- dev->kpid);
- wait_for_completion(&dev->dev_exited);
+ w1_stop_master_device(dev);
err_out_free_dev:
- w1_free_dev(dev);
+ w1_free_master_dev(dev);
return error;
}
void w1_remove_master_device(struct w1_master *dev)
{
- int err;
+ struct w1_slave *slave, *next;
- dev->need_exit = 1;
- err = kill_proc(dev->kpid, SIGTERM, 1);
- if (err)
- dev_err(&dev->dev,
- "%s: Failed to send signal to w1 kernel thread %d.\n",
- __func__, dev->kpid);
+ w1_stop_master_device(dev);
+
+ list_for_each_entry_safe(slave, next, &dev->slist, node) {
+ list_del(&slave->node);
+ w1_slave_detach(slave);
+ kfree(slave);
+ }
+
+ w1_destroy_master_attributes(dev);
while (atomic_read(&dev->refcnt)) {
printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n",
@@ -801,61 +741,36 @@ void w1_remove_master_device(struct w1_m
flush_signals(current);
}
- w1_free_dev(dev);
+ w1_free_master_dev(dev);
+ module_put(THIS_MODULE);
}
int w1_init(void)
{
- int retval;
+ int error;
printk(KERN_INFO "Driver for 1-wire Dallas network protocol.\n");
- retval = bus_register(&w1_bus_type);
- if (retval) {
- printk(KERN_ERR "Failed to register bus. err=%d.\n", retval);
- goto err_out_exit_init;
+ error = bus_register(&w1_bus_type);
+ if (error) {
+ printk(KERN_ERR "Failed to register bus. err=%d.\n", error);
+ return error;
}
- retval = driver_register(&w1_driver);
- if (retval) {
+ error = driver_register(&w1_driver);
+ if (error) {
printk(KERN_ERR
- "Failed to register master driver. err=%d.\n",
- retval);
- goto err_out_bus_unregister;
- }
-
- control_thread = kernel_thread(&w1_control, NULL, 0);
- if (control_thread < 0) {
- printk(KERN_ERR "Failed to create control thread. err=%d\n",
- control_thread);
- retval = control_thread;
- goto err_out_driver_unregister;
+ "Failed to register master driver. err=%d.\n", error);
+ bus_unregister(&w1_bus_type);
+ return error;
}
return 0;
-
-err_out_driver_unregister:
- driver_unregister(&w1_driver);
-
-err_out_bus_unregister:
- bus_unregister(&w1_bus_type);
-
-err_out_exit_init:
- return retval;
}
void w1_fini(void)
{
- struct w1_master *master, *next;
-
- list_for_each_entry_safe(master, next, &w1_masters, node)
- w1_remove_master_device(master);
-
- control_needs_exit = 1;
-
- wait_for_completion(&w1_control_complete);
-
driver_unregister(&w1_driver);
bus_unregister(&w1_bus_type);
}
Index: dtor/drivers/w1/w1.h
===================================================================
--- dtor.orig/drivers/w1/w1.h
+++ dtor/drivers/w1/w1.h
@@ -103,7 +103,6 @@ struct w1_bus_ops
struct w1_master
{
- struct list_head node;
unsigned char name[W1_MAXNAMELEN];
struct list_head slist;
int max_slave_count, slave_count;
next prev parent 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 ` Dmitry Torokhov [this message]
2005-05-19 6:25 ` [RFC/PATCH 10/22] W1: drop main control thread 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
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=200504210217.05859.dtor_core@ameritech.net \
--to=dtor_core@ameritech.net \
--cc=gregkh@suse.de \
--cc=johnpol@2ka.mipt.ru \
--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.