mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
freezer: Have {,un}lock_system_sleep() save/restore flags
Rafael explained that the reason for having both PF_NOFREEZE and PF_FREEZER_SKIP is that {,un}lock_system_sleep() is callable from kthread context that has previously called set_freezable(). In preparation of merging the flags, have {,un}lock_system_slee() save and restore current->flags. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://lore.kernel.org/r/20220822114648.725003428@infradead.org
This commit is contained in:
parent
0b9d46fc5e
commit
5950e5d574
@ -541,12 +541,14 @@ void acpi_s2idle_setup(void)
|
|||||||
|
|
||||||
int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg)
|
int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg)
|
||||||
{
|
{
|
||||||
|
unsigned int sleep_flags;
|
||||||
|
|
||||||
if (!lps0_device_handle || sleep_no_lps0)
|
if (!lps0_device_handle || sleep_no_lps0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
lock_system_sleep();
|
sleep_flags = lock_system_sleep();
|
||||||
list_add(&arg->list_node, &lps0_s2idle_devops_head);
|
list_add(&arg->list_node, &lps0_s2idle_devops_head);
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -554,12 +556,14 @@ EXPORT_SYMBOL_GPL(acpi_register_lps0_dev);
|
|||||||
|
|
||||||
void acpi_unregister_lps0_dev(struct acpi_s2idle_dev_ops *arg)
|
void acpi_unregister_lps0_dev(struct acpi_s2idle_dev_ops *arg)
|
||||||
{
|
{
|
||||||
|
unsigned int sleep_flags;
|
||||||
|
|
||||||
if (!lps0_device_handle || sleep_no_lps0)
|
if (!lps0_device_handle || sleep_no_lps0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lock_system_sleep();
|
sleep_flags = lock_system_sleep();
|
||||||
list_del(&arg->list_node);
|
list_del(&arg->list_node);
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(acpi_unregister_lps0_dev);
|
EXPORT_SYMBOL_GPL(acpi_unregister_lps0_dev);
|
||||||
|
|
||||||
|
@ -998,8 +998,9 @@ void
|
|||||||
spi_dv_device(struct scsi_device *sdev)
|
spi_dv_device(struct scsi_device *sdev)
|
||||||
{
|
{
|
||||||
struct scsi_target *starget = sdev->sdev_target;
|
struct scsi_target *starget = sdev->sdev_target;
|
||||||
u8 *buffer;
|
|
||||||
const int len = SPI_MAX_ECHO_BUFFER_SIZE*2;
|
const int len = SPI_MAX_ECHO_BUFFER_SIZE*2;
|
||||||
|
unsigned int sleep_flags;
|
||||||
|
u8 *buffer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Because this function and the power management code both call
|
* Because this function and the power management code both call
|
||||||
@ -1007,7 +1008,7 @@ spi_dv_device(struct scsi_device *sdev)
|
|||||||
* while suspend or resume is in progress. Hence the
|
* while suspend or resume is in progress. Hence the
|
||||||
* lock/unlock_system_sleep() calls.
|
* lock/unlock_system_sleep() calls.
|
||||||
*/
|
*/
|
||||||
lock_system_sleep();
|
sleep_flags = lock_system_sleep();
|
||||||
|
|
||||||
if (scsi_autopm_get_device(sdev))
|
if (scsi_autopm_get_device(sdev))
|
||||||
goto unlock_system_sleep;
|
goto unlock_system_sleep;
|
||||||
@ -1058,7 +1059,7 @@ put_autopm:
|
|||||||
scsi_autopm_put_device(sdev);
|
scsi_autopm_put_device(sdev);
|
||||||
|
|
||||||
unlock_system_sleep:
|
unlock_system_sleep:
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(spi_dv_device);
|
EXPORT_SYMBOL(spi_dv_device);
|
||||||
|
|
||||||
|
@ -510,8 +510,8 @@ extern bool pm_save_wakeup_count(unsigned int count);
|
|||||||
extern void pm_wakep_autosleep_enabled(bool set);
|
extern void pm_wakep_autosleep_enabled(bool set);
|
||||||
extern void pm_print_active_wakeup_sources(void);
|
extern void pm_print_active_wakeup_sources(void);
|
||||||
|
|
||||||
extern void lock_system_sleep(void);
|
extern unsigned int lock_system_sleep(void);
|
||||||
extern void unlock_system_sleep(void);
|
extern void unlock_system_sleep(unsigned int);
|
||||||
|
|
||||||
#else /* !CONFIG_PM_SLEEP */
|
#else /* !CONFIG_PM_SLEEP */
|
||||||
|
|
||||||
@ -534,8 +534,8 @@ static inline void pm_system_wakeup(void) {}
|
|||||||
static inline void pm_wakeup_clear(bool reset) {}
|
static inline void pm_wakeup_clear(bool reset) {}
|
||||||
static inline void pm_system_irq_wakeup(unsigned int irq_number) {}
|
static inline void pm_system_irq_wakeup(unsigned int irq_number) {}
|
||||||
|
|
||||||
static inline void lock_system_sleep(void) {}
|
static inline unsigned int lock_system_sleep(void) { return 0; }
|
||||||
static inline void unlock_system_sleep(void) {}
|
static inline void unlock_system_sleep(unsigned int flags) {}
|
||||||
|
|
||||||
#endif /* !CONFIG_PM_SLEEP */
|
#endif /* !CONFIG_PM_SLEEP */
|
||||||
|
|
||||||
|
@ -92,20 +92,24 @@ bool hibernation_available(void)
|
|||||||
*/
|
*/
|
||||||
void hibernation_set_ops(const struct platform_hibernation_ops *ops)
|
void hibernation_set_ops(const struct platform_hibernation_ops *ops)
|
||||||
{
|
{
|
||||||
|
unsigned int sleep_flags;
|
||||||
|
|
||||||
if (ops && !(ops->begin && ops->end && ops->pre_snapshot
|
if (ops && !(ops->begin && ops->end && ops->pre_snapshot
|
||||||
&& ops->prepare && ops->finish && ops->enter && ops->pre_restore
|
&& ops->prepare && ops->finish && ops->enter && ops->pre_restore
|
||||||
&& ops->restore_cleanup && ops->leave)) {
|
&& ops->restore_cleanup && ops->leave)) {
|
||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lock_system_sleep();
|
|
||||||
|
sleep_flags = lock_system_sleep();
|
||||||
|
|
||||||
hibernation_ops = ops;
|
hibernation_ops = ops;
|
||||||
if (ops)
|
if (ops)
|
||||||
hibernation_mode = HIBERNATION_PLATFORM;
|
hibernation_mode = HIBERNATION_PLATFORM;
|
||||||
else if (hibernation_mode == HIBERNATION_PLATFORM)
|
else if (hibernation_mode == HIBERNATION_PLATFORM)
|
||||||
hibernation_mode = HIBERNATION_SHUTDOWN;
|
hibernation_mode = HIBERNATION_SHUTDOWN;
|
||||||
|
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(hibernation_set_ops);
|
EXPORT_SYMBOL_GPL(hibernation_set_ops);
|
||||||
|
|
||||||
@ -713,6 +717,7 @@ static int load_image_and_restore(void)
|
|||||||
int hibernate(void)
|
int hibernate(void)
|
||||||
{
|
{
|
||||||
bool snapshot_test = false;
|
bool snapshot_test = false;
|
||||||
|
unsigned int sleep_flags;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (!hibernation_available()) {
|
if (!hibernation_available()) {
|
||||||
@ -720,7 +725,7 @@ int hibernate(void)
|
|||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_system_sleep();
|
sleep_flags = lock_system_sleep();
|
||||||
/* The snapshot device should not be opened while we're running */
|
/* The snapshot device should not be opened while we're running */
|
||||||
if (!hibernate_acquire()) {
|
if (!hibernate_acquire()) {
|
||||||
error = -EBUSY;
|
error = -EBUSY;
|
||||||
@ -794,7 +799,7 @@ int hibernate(void)
|
|||||||
pm_restore_console();
|
pm_restore_console();
|
||||||
hibernate_release();
|
hibernate_release();
|
||||||
Unlock:
|
Unlock:
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
pr_info("hibernation exit\n");
|
pr_info("hibernation exit\n");
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
@ -809,9 +814,10 @@ int hibernate(void)
|
|||||||
*/
|
*/
|
||||||
int hibernate_quiet_exec(int (*func)(void *data), void *data)
|
int hibernate_quiet_exec(int (*func)(void *data), void *data)
|
||||||
{
|
{
|
||||||
|
unsigned int sleep_flags;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
lock_system_sleep();
|
sleep_flags = lock_system_sleep();
|
||||||
|
|
||||||
if (!hibernate_acquire()) {
|
if (!hibernate_acquire()) {
|
||||||
error = -EBUSY;
|
error = -EBUSY;
|
||||||
@ -891,7 +897,7 @@ restore:
|
|||||||
hibernate_release();
|
hibernate_release();
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -1100,11 +1106,12 @@ static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr,
|
|||||||
static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr,
|
static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr,
|
||||||
const char *buf, size_t n)
|
const char *buf, size_t n)
|
||||||
{
|
{
|
||||||
|
int mode = HIBERNATION_INVALID;
|
||||||
|
unsigned int sleep_flags;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int i;
|
|
||||||
int len;
|
int len;
|
||||||
char *p;
|
char *p;
|
||||||
int mode = HIBERNATION_INVALID;
|
int i;
|
||||||
|
|
||||||
if (!hibernation_available())
|
if (!hibernation_available())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
@ -1112,7 +1119,7 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr,
|
|||||||
p = memchr(buf, '\n', n);
|
p = memchr(buf, '\n', n);
|
||||||
len = p ? p - buf : n;
|
len = p ? p - buf : n;
|
||||||
|
|
||||||
lock_system_sleep();
|
sleep_flags = lock_system_sleep();
|
||||||
for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) {
|
for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) {
|
||||||
if (len == strlen(hibernation_modes[i])
|
if (len == strlen(hibernation_modes[i])
|
||||||
&& !strncmp(buf, hibernation_modes[i], len)) {
|
&& !strncmp(buf, hibernation_modes[i], len)) {
|
||||||
@ -1142,7 +1149,7 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr,
|
|||||||
if (!error)
|
if (!error)
|
||||||
pm_pr_dbg("Hibernation mode set to '%s'\n",
|
pm_pr_dbg("Hibernation mode set to '%s'\n",
|
||||||
hibernation_modes[mode]);
|
hibernation_modes[mode]);
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
return error ? error : n;
|
return error ? error : n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1158,9 +1165,10 @@ static ssize_t resume_show(struct kobject *kobj, struct kobj_attribute *attr,
|
|||||||
static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
|
static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
|
||||||
const char *buf, size_t n)
|
const char *buf, size_t n)
|
||||||
{
|
{
|
||||||
dev_t res;
|
unsigned int sleep_flags;
|
||||||
int len = n;
|
int len = n;
|
||||||
char *name;
|
char *name;
|
||||||
|
dev_t res;
|
||||||
|
|
||||||
if (len && buf[len-1] == '\n')
|
if (len && buf[len-1] == '\n')
|
||||||
len--;
|
len--;
|
||||||
@ -1173,9 +1181,10 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
|
|||||||
if (!res)
|
if (!res)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
lock_system_sleep();
|
sleep_flags = lock_system_sleep();
|
||||||
swsusp_resume_device = res;
|
swsusp_resume_device = res;
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
|
|
||||||
pm_pr_dbg("Configured hibernation resume from disk to %u\n",
|
pm_pr_dbg("Configured hibernation resume from disk to %u\n",
|
||||||
swsusp_resume_device);
|
swsusp_resume_device);
|
||||||
noresume = 0;
|
noresume = 0;
|
||||||
|
@ -21,14 +21,16 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
|
||||||
void lock_system_sleep(void)
|
unsigned int lock_system_sleep(void)
|
||||||
{
|
{
|
||||||
|
unsigned int flags = current->flags;
|
||||||
current->flags |= PF_FREEZER_SKIP;
|
current->flags |= PF_FREEZER_SKIP;
|
||||||
mutex_lock(&system_transition_mutex);
|
mutex_lock(&system_transition_mutex);
|
||||||
|
return flags;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(lock_system_sleep);
|
EXPORT_SYMBOL_GPL(lock_system_sleep);
|
||||||
|
|
||||||
void unlock_system_sleep(void)
|
void unlock_system_sleep(unsigned int flags)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Don't use freezer_count() because we don't want the call to
|
* Don't use freezer_count() because we don't want the call to
|
||||||
@ -46,7 +48,8 @@ void unlock_system_sleep(void)
|
|||||||
* Which means, if we use try_to_freeze() here, it would make them
|
* Which means, if we use try_to_freeze() here, it would make them
|
||||||
* enter the refrigerator, thus causing hibernation to lockup.
|
* enter the refrigerator, thus causing hibernation to lockup.
|
||||||
*/
|
*/
|
||||||
current->flags &= ~PF_FREEZER_SKIP;
|
if (!(flags & PF_FREEZER_SKIP))
|
||||||
|
current->flags &= ~PF_FREEZER_SKIP;
|
||||||
mutex_unlock(&system_transition_mutex);
|
mutex_unlock(&system_transition_mutex);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(unlock_system_sleep);
|
EXPORT_SYMBOL_GPL(unlock_system_sleep);
|
||||||
@ -263,16 +266,17 @@ static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr,
|
|||||||
static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
|
static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
|
||||||
const char *buf, size_t n)
|
const char *buf, size_t n)
|
||||||
{
|
{
|
||||||
|
unsigned int sleep_flags;
|
||||||
const char * const *s;
|
const char * const *s;
|
||||||
|
int error = -EINVAL;
|
||||||
int level;
|
int level;
|
||||||
char *p;
|
char *p;
|
||||||
int len;
|
int len;
|
||||||
int error = -EINVAL;
|
|
||||||
|
|
||||||
p = memchr(buf, '\n', n);
|
p = memchr(buf, '\n', n);
|
||||||
len = p ? p - buf : n;
|
len = p ? p - buf : n;
|
||||||
|
|
||||||
lock_system_sleep();
|
sleep_flags = lock_system_sleep();
|
||||||
|
|
||||||
level = TEST_FIRST;
|
level = TEST_FIRST;
|
||||||
for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++)
|
for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++)
|
||||||
@ -282,7 +286,7 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
|
|
||||||
return error ? error : n;
|
return error ? error : n;
|
||||||
}
|
}
|
||||||
|
@ -75,9 +75,11 @@ EXPORT_SYMBOL_GPL(pm_suspend_default_s2idle);
|
|||||||
|
|
||||||
void s2idle_set_ops(const struct platform_s2idle_ops *ops)
|
void s2idle_set_ops(const struct platform_s2idle_ops *ops)
|
||||||
{
|
{
|
||||||
lock_system_sleep();
|
unsigned int sleep_flags;
|
||||||
|
|
||||||
|
sleep_flags = lock_system_sleep();
|
||||||
s2idle_ops = ops;
|
s2idle_ops = ops;
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void s2idle_begin(void)
|
static void s2idle_begin(void)
|
||||||
@ -200,7 +202,9 @@ __setup("mem_sleep_default=", mem_sleep_default_setup);
|
|||||||
*/
|
*/
|
||||||
void suspend_set_ops(const struct platform_suspend_ops *ops)
|
void suspend_set_ops(const struct platform_suspend_ops *ops)
|
||||||
{
|
{
|
||||||
lock_system_sleep();
|
unsigned int sleep_flags;
|
||||||
|
|
||||||
|
sleep_flags = lock_system_sleep();
|
||||||
|
|
||||||
suspend_ops = ops;
|
suspend_ops = ops;
|
||||||
|
|
||||||
@ -216,7 +220,7 @@ void suspend_set_ops(const struct platform_suspend_ops *ops)
|
|||||||
mem_sleep_current = PM_SUSPEND_MEM;
|
mem_sleep_current = PM_SUSPEND_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(suspend_set_ops);
|
EXPORT_SYMBOL_GPL(suspend_set_ops);
|
||||||
|
|
||||||
|
@ -47,12 +47,13 @@ int is_hibernate_resume_dev(dev_t dev)
|
|||||||
static int snapshot_open(struct inode *inode, struct file *filp)
|
static int snapshot_open(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
struct snapshot_data *data;
|
struct snapshot_data *data;
|
||||||
|
unsigned int sleep_flags;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (!hibernation_available())
|
if (!hibernation_available())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
lock_system_sleep();
|
sleep_flags = lock_system_sleep();
|
||||||
|
|
||||||
if (!hibernate_acquire()) {
|
if (!hibernate_acquire()) {
|
||||||
error = -EBUSY;
|
error = -EBUSY;
|
||||||
@ -98,7 +99,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
|
|||||||
data->dev = 0;
|
data->dev = 0;
|
||||||
|
|
||||||
Unlock:
|
Unlock:
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -106,8 +107,9 @@ static int snapshot_open(struct inode *inode, struct file *filp)
|
|||||||
static int snapshot_release(struct inode *inode, struct file *filp)
|
static int snapshot_release(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
struct snapshot_data *data;
|
struct snapshot_data *data;
|
||||||
|
unsigned int sleep_flags;
|
||||||
|
|
||||||
lock_system_sleep();
|
sleep_flags = lock_system_sleep();
|
||||||
|
|
||||||
swsusp_free();
|
swsusp_free();
|
||||||
data = filp->private_data;
|
data = filp->private_data;
|
||||||
@ -124,7 +126,7 @@ static int snapshot_release(struct inode *inode, struct file *filp)
|
|||||||
PM_POST_HIBERNATION : PM_POST_RESTORE);
|
PM_POST_HIBERNATION : PM_POST_RESTORE);
|
||||||
hibernate_release();
|
hibernate_release();
|
||||||
|
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -132,11 +134,12 @@ static int snapshot_release(struct inode *inode, struct file *filp)
|
|||||||
static ssize_t snapshot_read(struct file *filp, char __user *buf,
|
static ssize_t snapshot_read(struct file *filp, char __user *buf,
|
||||||
size_t count, loff_t *offp)
|
size_t count, loff_t *offp)
|
||||||
{
|
{
|
||||||
struct snapshot_data *data;
|
|
||||||
ssize_t res;
|
|
||||||
loff_t pg_offp = *offp & ~PAGE_MASK;
|
loff_t pg_offp = *offp & ~PAGE_MASK;
|
||||||
|
struct snapshot_data *data;
|
||||||
|
unsigned int sleep_flags;
|
||||||
|
ssize_t res;
|
||||||
|
|
||||||
lock_system_sleep();
|
sleep_flags = lock_system_sleep();
|
||||||
|
|
||||||
data = filp->private_data;
|
data = filp->private_data;
|
||||||
if (!data->ready) {
|
if (!data->ready) {
|
||||||
@ -157,7 +160,7 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf,
|
|||||||
*offp += res;
|
*offp += res;
|
||||||
|
|
||||||
Unlock:
|
Unlock:
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -165,16 +168,17 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf,
|
|||||||
static ssize_t snapshot_write(struct file *filp, const char __user *buf,
|
static ssize_t snapshot_write(struct file *filp, const char __user *buf,
|
||||||
size_t count, loff_t *offp)
|
size_t count, loff_t *offp)
|
||||||
{
|
{
|
||||||
struct snapshot_data *data;
|
|
||||||
ssize_t res;
|
|
||||||
loff_t pg_offp = *offp & ~PAGE_MASK;
|
loff_t pg_offp = *offp & ~PAGE_MASK;
|
||||||
|
struct snapshot_data *data;
|
||||||
|
unsigned long sleep_flags;
|
||||||
|
ssize_t res;
|
||||||
|
|
||||||
if (need_wait) {
|
if (need_wait) {
|
||||||
wait_for_device_probe();
|
wait_for_device_probe();
|
||||||
need_wait = false;
|
need_wait = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_system_sleep();
|
sleep_flags = lock_system_sleep();
|
||||||
|
|
||||||
data = filp->private_data;
|
data = filp->private_data;
|
||||||
|
|
||||||
@ -196,7 +200,7 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
|
|||||||
if (res > 0)
|
if (res > 0)
|
||||||
*offp += res;
|
*offp += res;
|
||||||
unlock:
|
unlock:
|
||||||
unlock_system_sleep();
|
unlock_system_sleep(sleep_flags);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user