Commit 5e4def20 authored by David Howells's avatar David Howells

Pass mode to wait_on_atomic_t() action funcs and provide default actions

Make wait_on_atomic_t() pass the TASK_* mode onto its action function as an
extra argument and make it 'unsigned int throughout.

Also, consolidate a bunch of identical action functions into a default
function that can do the appropriate thing for the mode.

Also, change the argument name in the bit_wait*() function declarations to
reflect the fact that it's the mode and not the bit number.

[Peter Z gives this a grudging ACK, but thinks that the whole atomic_t wait
should be done differently, though he's not immediately sure as to how]
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Acked-by: default avatarPeter Zijlstra <peterz@infradead.org>
cc: Ingo Molnar <mingo@kernel.org>
parent 81445e63
...@@ -1233,18 +1233,6 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action, ...@@ -1233,18 +1233,6 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
return NOTIFY_OK; return NOTIFY_OK;
} }
static int wait_on_fp_mode_switch(atomic_t *p)
{
/*
* The FP mode for this task is currently being switched. That may
* involve modifications to the format of this tasks FP context which
* make it unsafe to proceed with execution for the moment. Instead,
* schedule some other task.
*/
schedule();
return 0;
}
static int enable_restore_fp_context(int msa) static int enable_restore_fp_context(int msa)
{ {
int err, was_fpu_owner, prior_msa; int err, was_fpu_owner, prior_msa;
...@@ -1254,7 +1242,7 @@ static int enable_restore_fp_context(int msa) ...@@ -1254,7 +1242,7 @@ static int enable_restore_fp_context(int msa)
* complete before proceeding. * complete before proceeding.
*/ */
wait_on_atomic_t(&current->mm->context.fp_mode_switching, wait_on_atomic_t(&current->mm->context.fp_mode_switching,
wait_on_fp_mode_switch, TASK_KILLABLE); atomic_t_wait, TASK_KILLABLE);
if (!used_math()) { if (!used_math()) {
/* First time FP context user. */ /* First time FP context user. */
......
...@@ -263,12 +263,6 @@ static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_aux(struct drm_dp_aux *aux) ...@@ -263,12 +263,6 @@ static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_aux(struct drm_dp_aux *aux)
return aux_dev; return aux_dev;
} }
static int auxdev_wait_atomic_t(atomic_t *p)
{
schedule();
return 0;
}
void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux) void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
{ {
struct drm_dp_aux_dev *aux_dev; struct drm_dp_aux_dev *aux_dev;
...@@ -283,7 +277,7 @@ void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux) ...@@ -283,7 +277,7 @@ void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
mutex_unlock(&aux_idr_mutex); mutex_unlock(&aux_idr_mutex);
atomic_dec(&aux_dev->usecount); atomic_dec(&aux_dev->usecount);
wait_on_atomic_t(&aux_dev->usecount, auxdev_wait_atomic_t, wait_on_atomic_t(&aux_dev->usecount, atomic_t_wait,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
minor = aux_dev->index; minor = aux_dev->index;
......
...@@ -271,13 +271,7 @@ struct igt_wakeup { ...@@ -271,13 +271,7 @@ struct igt_wakeup {
u32 seqno; u32 seqno;
}; };
static int wait_atomic(atomic_t *p) static int wait_atomic_timeout(atomic_t *p, unsigned int mode)
{
schedule();
return 0;
}
static int wait_atomic_timeout(atomic_t *p)
{ {
return schedule_timeout(10 * HZ) ? 0 : -ETIMEDOUT; return schedule_timeout(10 * HZ) ? 0 : -ETIMEDOUT;
} }
...@@ -348,7 +342,7 @@ static void igt_wake_all_sync(atomic_t *ready, ...@@ -348,7 +342,7 @@ static void igt_wake_all_sync(atomic_t *ready,
atomic_set(ready, 0); atomic_set(ready, 0);
wake_up_all(wq); wake_up_all(wq);
wait_on_atomic_t(set, wait_atomic, TASK_UNINTERRUPTIBLE); wait_on_atomic_t(set, atomic_t_wait, TASK_UNINTERRUPTIBLE);
atomic_set(ready, count); atomic_set(ready, count);
atomic_set(done, count); atomic_set(done, count);
} }
......
...@@ -88,12 +88,6 @@ int hfi_core_init(struct venus_core *core) ...@@ -88,12 +88,6 @@ int hfi_core_init(struct venus_core *core)
return ret; return ret;
} }
static int core_deinit_wait_atomic_t(atomic_t *p)
{
schedule();
return 0;
}
int hfi_core_deinit(struct venus_core *core, bool blocking) int hfi_core_deinit(struct venus_core *core, bool blocking)
{ {
int ret = 0, empty; int ret = 0, empty;
...@@ -112,7 +106,7 @@ int hfi_core_deinit(struct venus_core *core, bool blocking) ...@@ -112,7 +106,7 @@ int hfi_core_deinit(struct venus_core *core, bool blocking)
if (!empty) { if (!empty) {
mutex_unlock(&core->lock); mutex_unlock(&core->lock);
wait_on_atomic_t(&core->insts_count, core_deinit_wait_atomic_t, wait_on_atomic_t(&core->insts_count, atomic_t_wait,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
mutex_lock(&core->lock); mutex_lock(&core->lock);
} }
......
...@@ -41,12 +41,6 @@ static void afs_charge_preallocation(struct work_struct *); ...@@ -41,12 +41,6 @@ static void afs_charge_preallocation(struct work_struct *);
static DECLARE_WORK(afs_charge_preallocation_work, afs_charge_preallocation); static DECLARE_WORK(afs_charge_preallocation_work, afs_charge_preallocation);
static int afs_wait_atomic_t(atomic_t *p)
{
schedule();
return 0;
}
/* /*
* open an RxRPC socket and bind it to be a server for callback notifications * open an RxRPC socket and bind it to be a server for callback notifications
* - the socket is left in blocking mode and non-blocking ops use MSG_DONTWAIT * - the socket is left in blocking mode and non-blocking ops use MSG_DONTWAIT
...@@ -121,7 +115,7 @@ void afs_close_socket(void) ...@@ -121,7 +115,7 @@ void afs_close_socket(void)
} }
_debug("outstanding %u", atomic_read(&afs_outstanding_calls)); _debug("outstanding %u", atomic_read(&afs_outstanding_calls));
wait_on_atomic_t(&afs_outstanding_calls, afs_wait_atomic_t, wait_on_atomic_t(&afs_outstanding_calls, atomic_t_wait,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
_debug("no outstanding calls"); _debug("no outstanding calls");
......
...@@ -4016,16 +4016,9 @@ void btrfs_dec_nocow_writers(struct btrfs_fs_info *fs_info, u64 bytenr) ...@@ -4016,16 +4016,9 @@ void btrfs_dec_nocow_writers(struct btrfs_fs_info *fs_info, u64 bytenr)
btrfs_put_block_group(bg); btrfs_put_block_group(bg);
} }
static int btrfs_wait_nocow_writers_atomic_t(atomic_t *a)
{
schedule();
return 0;
}
void btrfs_wait_nocow_writers(struct btrfs_block_group_cache *bg) void btrfs_wait_nocow_writers(struct btrfs_block_group_cache *bg)
{ {
wait_on_atomic_t(&bg->nocow_writers, wait_on_atomic_t(&bg->nocow_writers, atomic_t_wait,
btrfs_wait_nocow_writers_atomic_t,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
} }
...@@ -6595,12 +6588,6 @@ void btrfs_dec_block_group_reservations(struct btrfs_fs_info *fs_info, ...@@ -6595,12 +6588,6 @@ void btrfs_dec_block_group_reservations(struct btrfs_fs_info *fs_info,
btrfs_put_block_group(bg); btrfs_put_block_group(bg);
} }
static int btrfs_wait_bg_reservations_atomic_t(atomic_t *a)
{
schedule();
return 0;
}
void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg) void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg)
{ {
struct btrfs_space_info *space_info = bg->space_info; struct btrfs_space_info *space_info = bg->space_info;
...@@ -6623,8 +6610,7 @@ void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg) ...@@ -6623,8 +6610,7 @@ void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg)
down_write(&space_info->groups_sem); down_write(&space_info->groups_sem);
up_write(&space_info->groups_sem); up_write(&space_info->groups_sem);
wait_on_atomic_t(&bg->reservations, wait_on_atomic_t(&bg->reservations, atomic_t_wait,
btrfs_wait_bg_reservations_atomic_t,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
} }
...@@ -11106,12 +11092,6 @@ int btrfs_start_write_no_snapshotting(struct btrfs_root *root) ...@@ -11106,12 +11092,6 @@ int btrfs_start_write_no_snapshotting(struct btrfs_root *root)
return 1; return 1;
} }
static int wait_snapshotting_atomic_t(atomic_t *a)
{
schedule();
return 0;
}
void btrfs_wait_for_snapshot_creation(struct btrfs_root *root) void btrfs_wait_for_snapshot_creation(struct btrfs_root *root)
{ {
while (true) { while (true) {
...@@ -11120,8 +11100,7 @@ void btrfs_wait_for_snapshot_creation(struct btrfs_root *root) ...@@ -11120,8 +11100,7 @@ void btrfs_wait_for_snapshot_creation(struct btrfs_root *root)
ret = btrfs_start_write_no_snapshotting(root); ret = btrfs_start_write_no_snapshotting(root);
if (ret) if (ret)
break; break;
wait_on_atomic_t(&root->will_be_snapshotted, wait_on_atomic_t(&root->will_be_snapshotted, atomic_t_wait,
wait_snapshotting_atomic_t,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
} }
} }
...@@ -558,7 +558,7 @@ void __fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate) ...@@ -558,7 +558,7 @@ void __fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate)
* have completed. * have completed.
*/ */
if (!atomic_dec_and_test(&cookie->n_active)) if (!atomic_dec_and_test(&cookie->n_active))
wait_on_atomic_t(&cookie->n_active, fscache_wait_atomic_t, wait_on_atomic_t(&cookie->n_active, atomic_t_wait,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
/* Make sure any pending writes are cancelled. */ /* Make sure any pending writes are cancelled. */
......
...@@ -97,8 +97,6 @@ static inline bool fscache_object_congested(void) ...@@ -97,8 +97,6 @@ static inline bool fscache_object_congested(void)
return workqueue_congested(WORK_CPU_UNBOUND, fscache_object_wq); return workqueue_congested(WORK_CPU_UNBOUND, fscache_object_wq);
} }
extern int fscache_wait_atomic_t(atomic_t *);
/* /*
* object.c * object.c
*/ */
......
...@@ -195,12 +195,3 @@ static void __exit fscache_exit(void) ...@@ -195,12 +195,3 @@ static void __exit fscache_exit(void)
} }
module_exit(fscache_exit); module_exit(fscache_exit);
/*
* wait_on_atomic_t() sleep function for uninterruptible waiting
*/
int fscache_wait_atomic_t(atomic_t *p)
{
schedule();
return 0;
}
...@@ -85,9 +85,9 @@ int nfs_wait_bit_killable(struct wait_bit_key *key, int mode) ...@@ -85,9 +85,9 @@ int nfs_wait_bit_killable(struct wait_bit_key *key, int mode)
} }
EXPORT_SYMBOL_GPL(nfs_wait_bit_killable); EXPORT_SYMBOL_GPL(nfs_wait_bit_killable);
int nfs_wait_atomic_killable(atomic_t *p) int nfs_wait_atomic_killable(atomic_t *p, unsigned int mode)
{ {
return nfs_wait_killable(TASK_KILLABLE); return nfs_wait_killable(mode);
} }
/** /**
......
...@@ -388,7 +388,7 @@ extern void nfs_evict_inode(struct inode *); ...@@ -388,7 +388,7 @@ extern void nfs_evict_inode(struct inode *);
void nfs_zap_acl_cache(struct inode *inode); void nfs_zap_acl_cache(struct inode *inode);
extern bool nfs_check_cache_invalid(struct inode *, unsigned long); extern bool nfs_check_cache_invalid(struct inode *, unsigned long);
extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode); extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);
extern int nfs_wait_atomic_killable(atomic_t *p); extern int nfs_wait_atomic_killable(atomic_t *p, unsigned int mode);
/* super.c */ /* super.c */
extern const struct super_operations nfs_sops; extern const struct super_operations nfs_sops;
......
...@@ -129,19 +129,13 @@ static struct kobj_attribute ocfs2_attr_filecheck_set = ...@@ -129,19 +129,13 @@ static struct kobj_attribute ocfs2_attr_filecheck_set =
ocfs2_filecheck_show, ocfs2_filecheck_show,
ocfs2_filecheck_store); ocfs2_filecheck_store);
static int ocfs2_filecheck_sysfs_wait(atomic_t *p)
{
schedule();
return 0;
}
static void static void
ocfs2_filecheck_sysfs_free(struct ocfs2_filecheck_sysfs_entry *entry) ocfs2_filecheck_sysfs_free(struct ocfs2_filecheck_sysfs_entry *entry)
{ {
struct ocfs2_filecheck_entry *p; struct ocfs2_filecheck_entry *p;
if (!atomic_dec_and_test(&entry->fs_count)) if (!atomic_dec_and_test(&entry->fs_count))
wait_on_atomic_t(&entry->fs_count, ocfs2_filecheck_sysfs_wait, wait_on_atomic_t(&entry->fs_count, atomic_t_wait,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
spin_lock(&entry->fs_fcheck->fc_lock); spin_lock(&entry->fs_fcheck->fc_lock);
......
...@@ -26,6 +26,8 @@ struct wait_bit_queue_entry { ...@@ -26,6 +26,8 @@ struct wait_bit_queue_entry {
{ .flags = p, .bit_nr = WAIT_ATOMIC_T_BIT_NR, } { .flags = p, .bit_nr = WAIT_ATOMIC_T_BIT_NR, }
typedef int wait_bit_action_f(struct wait_bit_key *key, int mode); typedef int wait_bit_action_f(struct wait_bit_key *key, int mode);
typedef int wait_atomic_t_action_f(atomic_t *counter, unsigned int mode);
void __wake_up_bit(struct wait_queue_head *wq_head, void *word, int bit); void __wake_up_bit(struct wait_queue_head *wq_head, void *word, int bit);
int __wait_on_bit(struct wait_queue_head *wq_head, struct wait_bit_queue_entry *wbq_entry, wait_bit_action_f *action, unsigned int mode); int __wait_on_bit(struct wait_queue_head *wq_head, struct wait_bit_queue_entry *wbq_entry, wait_bit_action_f *action, unsigned int mode);
int __wait_on_bit_lock(struct wait_queue_head *wq_head, struct wait_bit_queue_entry *wbq_entry, wait_bit_action_f *action, unsigned int mode); int __wait_on_bit_lock(struct wait_queue_head *wq_head, struct wait_bit_queue_entry *wbq_entry, wait_bit_action_f *action, unsigned int mode);
...@@ -34,7 +36,7 @@ void wake_up_atomic_t(atomic_t *p); ...@@ -34,7 +36,7 @@ void wake_up_atomic_t(atomic_t *p);
int out_of_line_wait_on_bit(void *word, int, wait_bit_action_f *action, unsigned int mode); int out_of_line_wait_on_bit(void *word, int, wait_bit_action_f *action, unsigned int mode);
int out_of_line_wait_on_bit_timeout(void *word, int, wait_bit_action_f *action, unsigned int mode, unsigned long timeout); int out_of_line_wait_on_bit_timeout(void *word, int, wait_bit_action_f *action, unsigned int mode, unsigned long timeout);
int out_of_line_wait_on_bit_lock(void *word, int, wait_bit_action_f *action, unsigned int mode); int out_of_line_wait_on_bit_lock(void *word, int, wait_bit_action_f *action, unsigned int mode);
int out_of_line_wait_on_atomic_t(atomic_t *p, int (*)(atomic_t *), unsigned int mode); int out_of_line_wait_on_atomic_t(atomic_t *p, wait_atomic_t_action_f action, unsigned int mode);
struct wait_queue_head *bit_waitqueue(void *word, int bit); struct wait_queue_head *bit_waitqueue(void *word, int bit);
extern void __init wait_bit_init(void); extern void __init wait_bit_init(void);
...@@ -51,10 +53,11 @@ int wake_bit_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync ...@@ -51,10 +53,11 @@ int wake_bit_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync
}, \ }, \
} }
extern int bit_wait(struct wait_bit_key *key, int bit); extern int bit_wait(struct wait_bit_key *key, int mode);
extern int bit_wait_io(struct wait_bit_key *key, int bit); extern int bit_wait_io(struct wait_bit_key *key, int mode);
extern int bit_wait_timeout(struct wait_bit_key *key, int bit); extern int bit_wait_timeout(struct wait_bit_key *key, int mode);
extern int bit_wait_io_timeout(struct wait_bit_key *key, int bit); extern int bit_wait_io_timeout(struct wait_bit_key *key, int mode);
extern int atomic_t_wait(atomic_t *counter, unsigned int mode);
/** /**
* wait_on_bit - wait for a bit to be cleared * wait_on_bit - wait for a bit to be cleared
...@@ -251,7 +254,7 @@ wait_on_bit_lock_action(unsigned long *word, int bit, wait_bit_action_f *action, ...@@ -251,7 +254,7 @@ wait_on_bit_lock_action(unsigned long *word, int bit, wait_bit_action_f *action,
* outside of the target 'word'. * outside of the target 'word'.
*/ */
static inline static inline
int wait_on_atomic_t(atomic_t *val, int (*action)(atomic_t *), unsigned mode) int wait_on_atomic_t(atomic_t *val, wait_atomic_t_action_f action, unsigned mode)
{ {
might_sleep(); might_sleep();
if (atomic_read(val) == 0) if (atomic_read(val) == 0)
......
...@@ -183,7 +183,7 @@ static int wake_atomic_t_function(struct wait_queue_entry *wq_entry, unsigned mo ...@@ -183,7 +183,7 @@ static int wake_atomic_t_function(struct wait_queue_entry *wq_entry, unsigned mo
*/ */
static __sched static __sched
int __wait_on_atomic_t(struct wait_queue_head *wq_head, struct wait_bit_queue_entry *wbq_entry, int __wait_on_atomic_t(struct wait_queue_head *wq_head, struct wait_bit_queue_entry *wbq_entry,
int (*action)(atomic_t *), unsigned mode) wait_atomic_t_action_f action, unsigned int mode)
{ {
atomic_t *val; atomic_t *val;
int ret = 0; int ret = 0;
...@@ -193,7 +193,7 @@ int __wait_on_atomic_t(struct wait_queue_head *wq_head, struct wait_bit_queue_en ...@@ -193,7 +193,7 @@ int __wait_on_atomic_t(struct wait_queue_head *wq_head, struct wait_bit_queue_en
val = wbq_entry->key.flags; val = wbq_entry->key.flags;
if (atomic_read(val) == 0) if (atomic_read(val) == 0)
break; break;
ret = (*action)(val); ret = (*action)(val, mode);
} while (!ret && atomic_read(val) != 0); } while (!ret && atomic_read(val) != 0);
finish_wait(wq_head, &wbq_entry->wq_entry); finish_wait(wq_head, &wbq_entry->wq_entry);
return ret; return ret;
...@@ -210,8 +210,9 @@ int __wait_on_atomic_t(struct wait_queue_head *wq_head, struct wait_bit_queue_en ...@@ -210,8 +210,9 @@ int __wait_on_atomic_t(struct wait_queue_head *wq_head, struct wait_bit_queue_en
}, \ }, \
} }
__sched int out_of_line_wait_on_atomic_t(atomic_t *p, int (*action)(atomic_t *), __sched int out_of_line_wait_on_atomic_t(atomic_t *p,
unsigned mode) wait_atomic_t_action_f action,
unsigned int mode)
{ {
struct wait_queue_head *wq_head = atomic_t_waitqueue(p); struct wait_queue_head *wq_head = atomic_t_waitqueue(p);
DEFINE_WAIT_ATOMIC_T(wq_entry, p); DEFINE_WAIT_ATOMIC_T(wq_entry, p);
...@@ -220,6 +221,15 @@ __sched int out_of_line_wait_on_atomic_t(atomic_t *p, int (*action)(atomic_t *), ...@@ -220,6 +221,15 @@ __sched int out_of_line_wait_on_atomic_t(atomic_t *p, int (*action)(atomic_t *),
} }
EXPORT_SYMBOL(out_of_line_wait_on_atomic_t); EXPORT_SYMBOL(out_of_line_wait_on_atomic_t);
__sched int atomic_t_wait(atomic_t *counter, unsigned int mode)
{
schedule();
if (signal_pending_state(mode, current))
return -EINTR;
return 0;
}
EXPORT_SYMBOL(atomic_t_wait);
/** /**
* wake_up_atomic_t - Wake up a waiter on a atomic_t * wake_up_atomic_t - Wake up a waiter on a atomic_t
* @p: The atomic_t being waited on, a kernel virtual address * @p: The atomic_t being waited on, a kernel virtual address
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment