Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 674a396c authored by Evgeniy Polyakov's avatar Evgeniy Polyakov Committed by Greg Kroah-Hartman
Browse files

[PATCH] w1: use kthread api.



This patch removes old-style kernel thread initialization
and changes w1 to use kthread api.
It is based on Christoph Hellwig <hch@lst.de> work.

Signed-off-by: default avatarEvgeniy Polyakov <johnpol@2ka.mipt.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent f73b5e79
Loading
Loading
Loading
Loading
+16 −40
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/kthread.h>

#include <asm/atomic.h>

@@ -57,9 +58,7 @@ module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
DEFINE_SPINLOCK(w1_mlock);
LIST_HEAD(w1_masters);

static pid_t control_thread;
static int control_needs_exit;
static DECLARE_COMPLETION(w1_control_complete);
static struct task_struct *w1_control_thread;

static int w1_master_match(struct device *dev, struct device_driver *drv)
{
@@ -717,22 +716,16 @@ static int w1_control(void *data)
{
	struct w1_slave *sl, *sln;
	struct w1_master *dev, *n;
	int err, have_to_wait = 0;
	int have_to_wait = 0;

	daemonize("w1_control");
	allow_signal(SIGTERM);

	while (!control_needs_exit || have_to_wait) {
	while (!kthread_should_stop() || have_to_wait) {
		have_to_wait = 0;

		try_to_freeze();
		msleep_interruptible(w1_control_timeout * 1000);

		if (signal_pending(current))
			flush_signals(current);

		list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) {
			if (!control_needs_exit && !dev->flags)
			if (!kthread_should_stop() && !dev->flags)
				continue;
			/*
			 * Little race: we can create thread but not set the flag.
@@ -743,21 +736,12 @@ static int w1_control(void *data)
				continue;
			}

			if (control_needs_exit) {
			if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
				set_bit(W1_MASTER_NEED_EXIT, &dev->flags);

				err = kill_proc(dev->kpid, SIGTERM, 1);
				if (err)
					dev_err(&dev->dev,
						 "Failed to send signal to w1 kernel thread %d.\n",
						 dev->kpid);
			}

			if (test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
				wait_for_completion(&dev->dev_exited);
				spin_lock_bh(&w1_mlock);
				spin_lock(&w1_mlock);
				list_del(&dev->w1_master_entry);
				spin_unlock_bh(&w1_mlock);
				spin_unlock(&w1_mlock);

				down(&dev->mutex);
				list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
@@ -789,7 +773,7 @@ static int w1_control(void *data)
		}
	}

	complete_and_exit(&w1_control_complete, 0);
	return 0;
}

int w1_process(void *data)
@@ -797,17 +781,11 @@ int w1_process(void *data)
	struct w1_master *dev = (struct w1_master *) data;
	struct w1_slave *sl, *sln;

	daemonize("%s", dev->name);
	allow_signal(SIGTERM);

	while (!test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
	while (!kthread_should_stop() && !test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
		try_to_freeze();
		msleep_interruptible(w1_timeout * 1000);

		if (signal_pending(current))
			flush_signals(current);

		if (test_bit(W1_MASTER_NEED_EXIT, &dev->flags))
		if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags))
			break;

		if (!dev->initialized)
@@ -840,7 +818,6 @@ int w1_process(void *data)
	}

	atomic_dec(&dev->refcnt);
	complete_and_exit(&dev->dev_exited, 0);

	return 0;
}
@@ -873,11 +850,11 @@ static int w1_init(void)
		goto err_out_master_unregister;
	}

	control_thread = kernel_thread(&w1_control, NULL, 0);
	if (control_thread < 0) {
	w1_control_thread = kthread_run(w1_control, NULL, "w1_control");
	if (IS_ERR(w1_control_thread)) {
		retval = PTR_ERR(w1_control_thread);
		printk(KERN_ERR "Failed to create control thread. err=%d\n",
			control_thread);
		retval = control_thread;
			retval);
		goto err_out_slave_unregister;
	}

@@ -903,8 +880,7 @@ static void w1_fini(void)
	list_for_each_entry(dev, &w1_masters, w1_master_entry)
		__w1_remove_master_device(dev);

	control_needs_exit = 1;
	wait_for_completion(&w1_control_complete);
	kthread_stop(w1_control_thread);

	driver_unregister(&w1_slave_driver);
	driver_unregister(&w1_master_driver);
+1 −2
Original line number Diff line number Diff line
@@ -172,12 +172,11 @@ struct w1_master

	long			flags;

	pid_t			kpid;
	struct task_struct	*thread;
	struct semaphore	mutex;

	struct device_driver	*driver;
	struct device		dev;
	struct completion	dev_exited;

	struct w1_bus_master	*bus_master;

+11 −23
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/kthread.h>

#include "w1.h"
#include "w1_log.h"
@@ -56,7 +57,6 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
	dev->max_slave_count	= slave_count;
	dev->slave_count	= 0;
	dev->attempts		= 0;
	dev->kpid		= -1;
	dev->initialized	= 0;
	dev->id			= id;
	dev->slave_ttl		= slave_ttl;
@@ -67,8 +67,6 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
	INIT_LIST_HEAD(&dev->slist);
	init_MUTEX(&dev->mutex);

	init_completion(&dev->dev_exited);

	memcpy(&dev->dev, device, sizeof(struct device));
	snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id),
		  "w1_bus_master%u", dev->id);
@@ -116,12 +114,12 @@ int w1_add_master_device(struct w1_bus_master *master)
	if (!dev)
		return -ENOMEM;

	dev->kpid = kernel_thread(&w1_process, dev, 0);
	if (dev->kpid < 0) {
	dev->thread = kthread_run(&w1_process, dev, "%s", dev->name);
	if (IS_ERR(dev->thread)) {
		retval = PTR_ERR(dev->thread);
		dev_err(&dev->dev,
			 "Failed to create new kernel thread. err=%d\n",
			 dev->kpid);
		retval = dev->kpid;
			 retval);
		goto err_out_free_dev;
	}

@@ -138,20 +136,14 @@ int w1_add_master_device(struct w1_bus_master *master)
	spin_unlock(&w1_mlock);

	msg.id.mst.id = dev->id;
	msg.id.mst.pid = dev->kpid;
	msg.id.mst.pid = dev->thread->pid;
	msg.type = W1_MASTER_ADD;
	w1_netlink_send(dev, &msg);

	return 0;

err_out_kill_thread:
	set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
	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);

	kthread_stop(dev->thread);
err_out_free_dev:
	w1_free_dev(dev);

@@ -160,18 +152,14 @@ int w1_add_master_device(struct w1_bus_master *master)

void __w1_remove_master_device(struct w1_master *dev)
{
	int err;
	struct w1_netlink_msg msg;
	pid_t pid = dev->thread->pid;

	set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
	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);
	kthread_stop(dev->thread);

	while (atomic_read(&dev->refcnt)) {
		dev_dbg(&dev->dev, "Waiting for %s to become free: refcnt=%d.\n",
		dev_info(&dev->dev, "Waiting for %s to become free: refcnt=%d.\n",
				dev->name, atomic_read(&dev->refcnt));

		if (msleep_interruptible(1000))
@@ -179,7 +167,7 @@ void __w1_remove_master_device(struct w1_master *dev)
	}

	msg.id.mst.id = dev->id;
	msg.id.mst.pid = dev->kpid;
	msg.id.mst.pid = pid;
	msg.type = W1_MASTER_REMOVE;
	w1_netlink_send(dev, &msg);