lkml.org 
[lkml]   [2010]   [May]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
SubjectRe: [PATCH 2/8] PM: suspend_block: Add driver to access suspend blockers from user-space
Date
On Saturday 01 May 2010, Arve Hjønnevåg wrote:
> Add a misc device, "suspend_blocker", that allows user-space processes
> to block auto suspend. The device has ioctls to create a suspend_blocker,
> and to block and unblock suspend. To delete the suspend_blocker, close
> the device.
>
> Signed-off-by: Arve Hjønnevåg <arve@android.com>
> ---
> Documentation/ioctl/ioctl-number.txt | 3 +-
> Documentation/power/opportunistic-suspend.txt | 17 ++++
> include/linux/suspend_block_dev.h | 25 +++++
> kernel/power/Kconfig | 9 ++
> kernel/power/Makefile | 1 +
> kernel/power/user_suspend_blocker.c | 128 +++++++++++++++++++++++++
> 6 files changed, 182 insertions(+), 1 deletions(-)
> create mode 100644 include/linux/suspend_block_dev.h
> create mode 100644 kernel/power/user_suspend_blocker.c
>
> diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
> index dd5806f..e2458f7 100644
> --- a/Documentation/ioctl/ioctl-number.txt
> +++ b/Documentation/ioctl/ioctl-number.txt
> @@ -254,7 +254,8 @@ Code Seq#(hex) Include File Comments
> 'q' 80-FF linux/telephony.h Internet PhoneJACK, Internet LineJACK
> linux/ixjuser.h <http://www.quicknet.net>
> 'r' 00-1F linux/msdos_fs.h and fs/fat/dir.c
> -'s' all linux/cdk.h
> +'s' all linux/cdk.h conflict!
> +'s' all linux/suspend_block_dev.h conflict!
> 't' 00-7F linux/if_ppp.h
> 't' 80-8F linux/isdn_ppp.h
> 't' 90 linux/toshiba.h
> diff --git a/Documentation/power/opportunistic-suspend.txt b/Documentation/power/opportunistic-suspend.txt
> index 3d060e8..f2b145e 100644
> --- a/Documentation/power/opportunistic-suspend.txt
> +++ b/Documentation/power/opportunistic-suspend.txt
> @@ -117,3 +117,20 @@ if (list_empty(&state->pending_work))
> else
> suspend_block(&state->suspend_blocker);
>
> +User-space API
> +==============
> +
> +To create a suspend_blocker from user-space, open the suspend_blocker device:
> + fd = open("/dev/suspend_blocker", O_RDWR | O_CLOEXEC);
> +then call:
> + ioctl(fd, SUSPEND_BLOCKER_IOCTL_INIT(strlen(name)), name);
> +
> +To activate a suspend_blocker call:
> + ioctl(fd, SUSPEND_BLOCKER_IOCTL_BLOCK);
> +
> +To unblock call:
> + ioctl(fd, SUSPEND_BLOCKER_IOCTL_UNBLOCK);
> +
> +To destroy the suspend_blocker, close the device:
> + close(fd);
> +
> diff --git a/include/linux/suspend_block_dev.h b/include/linux/suspend_block_dev.h
> new file mode 100644
> index 0000000..24bc5c7
> --- /dev/null
> +++ b/include/linux/suspend_block_dev.h
> @@ -0,0 +1,25 @@
> +/* include/linux/suspend_block_dev.h
> + *
> + * Copyright (C) 2009 Google, Inc.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#ifndef _LINUX_SUSPEND_BLOCK_DEV_H
> +#define _LINUX_SUSPEND_BLOCK_DEV_H
> +
> +#include <linux/ioctl.h>
> +
> +#define SUSPEND_BLOCKER_IOCTL_INIT(len) _IOC(_IOC_WRITE, 's', 0, len)
> +#define SUSPEND_BLOCKER_IOCTL_BLOCK _IO('s', 1)
> +#define SUSPEND_BLOCKER_IOCTL_UNBLOCK _IO('s', 2)
> +
> +#endif
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 55a06a1..fe5a2f2 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -146,6 +146,15 @@ config OPPORTUNISTIC_SUSPEND
> determines the sleep state the system will be put into when there are
> no active suspend blockers.
>
> +config USER_SUSPEND_BLOCKERS
> + bool "Userspace suspend blockers"
> + depends on OPPORTUNISTIC_SUSPEND
> + default y
> + ---help---
> + User-space suspend block api. Creates a misc device with ioctls
> + to create, block and unblock a suspend_blocker. The suspend_blocker
> + will be deleted when the device is closed.
> +
> config HIBERNATION_NVS
> bool
>
> diff --git a/kernel/power/Makefile b/kernel/power/Makefile
> index ee5276d..78f703b 100644
> --- a/kernel/power/Makefile
> +++ b/kernel/power/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_PM_SLEEP) += console.o
> obj-$(CONFIG_FREEZER) += process.o
> obj-$(CONFIG_SUSPEND) += suspend.o
> obj-$(CONFIG_OPPORTUNISTIC_SUSPEND) += suspend_blocker.o
> +obj-$(CONFIG_USER_SUSPEND_BLOCKERS) += user_suspend_blocker.o
> obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o
> obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o
> obj-$(CONFIG_HIBERNATION_NVS) += hibernate_nvs.o
> diff --git a/kernel/power/user_suspend_blocker.c b/kernel/power/user_suspend_blocker.c
> new file mode 100644
> index 0000000..dc1d06f
> --- /dev/null
> +++ b/kernel/power/user_suspend_blocker.c
> @@ -0,0 +1,128 @@
> +/* kernel/power/user_suspend_block.c
> + *
> + * Copyright (C) 2009-2010 Google, Inc.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/fs.h>
> +#include <linux/miscdevice.h>
> +#include <linux/module.h>
> +#include <linux/uaccess.h>
> +#include <linux/slab.h>
> +#include <linux/suspend_blocker.h>
> +#include <linux/suspend_block_dev.h>
> +
> +enum {
> + DEBUG_FAILURE = BIT(0),
> +};
> +static int debug_mask = DEBUG_FAILURE;
> +module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
> +
> +static DEFINE_MUTEX(ioctl_lock);
> +
> +struct user_suspend_blocker {
> + struct suspend_blocker blocker;
> + char name[0];
> +};
> +
> +static int create_user_suspend_blocker(struct file *file, void __user *name,
> + size_t name_len)
> +{
> + struct user_suspend_blocker *bl;
> + if (file->private_data)
> + return -EBUSY;
> + if (name_len > NAME_MAX)
> + return -ENAMETOOLONG;
> + bl = kzalloc(sizeof(*bl) + name_len + 1, GFP_KERNEL);
> + if (!bl)
> + return -ENOMEM;
> + if (copy_from_user(bl->name, name, name_len))
> + goto err_fault;
> + suspend_blocker_init(&bl->blocker, bl->name);
> + file->private_data = bl;

Hmm. It doesn't seem to be possible to create two different suspend blockers
using the same file handle. So, what exactly is a process supposed to do to
use two suspend blockers at the same time?

Rafael
--
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/

\
 
 \ /
  Last update: 2010-05-02 23:25    [W:0.487 / U:64.336 seconds]
©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site