sched/wait: Replace wait_on_atomic_t() with wait_var_event()
Subsystems (14)
Peter Zijlstra
maintainercover sched/wait: Replace wait_on_atomic_t() with wait_var_event()
I never really liked the whole wait_on_atomic_t() because of the hard-coded type and condition. And when Dan proposed to add 50+ lines of duplication to implement wait_on_atomic_one() I figured that was it.
Instead implement wait_var_event(), which at the fundamental level is much the same hashed-waitqueue as wait_on_atomic_t() is, but it doesn't care about the type or condition.
It is further modelled on the existing wait_event() API and is otherwise consistent with that.
The existing:
wait_for_atomic_t(&my_atomic, wait_atomic_t, TASK_UNINTERRUPTIBLE); wake_up_atomic_t(&my_atomic);
can be replaced with:
wait_var_event(&my_atomic, !atomic_read(&my_atomic)); wake_up_var(&my_atomic);
And Dan can do what he needs done using:
wait_var_event(&my_atomic, atomic_read(&my_atomic) == 1);
--- arch/mips/kernel/process.c | 2 + arch/mips/kernel/traps.c | 4 +- drivers/gpu/drm/drm_dp_aux_dev.c | 13 +-- drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c | 14 +-- drivers/media/platform/qcom/venus/hfi.c | 8 +- fs/afs/cell.c | 6 +- fs/afs/rxrpc.c | 6 +- fs/afs/server.c | 6 +- fs/btrfs/extent-tree.c | 14 ++- fs/btrfs/ioctl.c | 2 +- fs/fscache/cookie.c | 7 +- fs/nfs/inode.c | 5 - fs/nfs/pagelist.c | 6 +- fs/nfs/pnfs_nfs.c | 2 +- fs/nfs/write.c | 6 +- fs/ocfs2/filecheck.c | 9 +- include/linux/fscache-cache.h | 2 +- include/linux/wait_bit.h | 95 +++++++++++++----- kernel/sched/wait_bit.c | 110 +++++---------------- 19 files changed, 147 insertions(+), 170 deletions(-)
Peter Zijlstra
maintainerPATCH 1/11 sched/wait: Introduce wait_var_event()
As a replacement for the wait_on_atomic_t() API provide the wait_var_event() API.
The wait_var_event() API is based on the very same hashed-waitqueue idea, but doesn't care about the type (atomic_t) or the specific condition (atomic_read() == 0). IOW. it's much more widely applicable/flexible.
It shares all the benefits/disadvantages of a hashed-waitqueue approach with the existing wait_on_atomic_t/wait_on_bit() APIs.
The API is modeled after the existing wait_event() API, but instead of taking a wait_queue_head, it takes an address. This addresses is hashed to obtain a wait_queue_head from the bit_wait_table.
Similar to the wait_event() API, it takes a condition expression as second argument and will wait until this expression becomes true.
The following are (mostly) identical replacements:
wait_on_atomic_t(&my_atomic, atomic_t_wait, TASK_UNINTERRUPTIBLE); wake_up_atomic_t(&my_atomic); wait_var_event(&my_atomic, !atomic_read(&my_atomic)); wake_up_var(&my_atomic);
The only difference is that wake_up_var() is an unconditional wakeup and doesn't check the previously hard-coded (atomic_read() == 0) condition here. This is of little concequence, since most callers are already conditional on atomic_dec_and_test() and the ones that are not, are trivial to make so.
--- include/linux/wait_bit.h | 70 +++++++++++++++++++++++++++++++++++++++++++++++ kernel/sched/wait_bit.c | 48 ++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+)
include/linux/wait_bit.h +70 -0
@@ -262,4 +262,74 @@ int wait_on_atomic_t(atomic_t *val, waitreturn out_of_line_wait_on_atomic_t (val, action, mode); } +extern void init_wait_var_entry (struct wait_bit_queue_entry *wbq_entry,void *var,int flags); +extern void wake_up_var (void *var); +extern wait_queue_head_t *__var_waitqueue (void *p); + +#define ___wait_var_event (var, condition, state, exclusive, ret, cmd) \ +({ \ + __label__ __out; \ + struct wait_queue_head *__wq_head = __var_waitqueue(var); \ + struct wait_bit_queue_entry __wbq_entry; \ + long __ret = ret;/* explicit shadow */ \ + \ +init_wait_var_entry (&__wbq_entry, var, \ + exclusive ?WQ_FLAG_EXCLUSIVE :0 ); \ +for (;;) { \ +long __int =prepare_to_wait_event (__wq_head, \ + &__wbq_entry.wq_entry, \ + state); \ +if (condition) \ +break ; \ + \ +if (___wait_is_interruptible (state) && __int) { \ + __ret = __int; \ + goto __out; \ + } \ + \ + cmd; \ + } \ +finish_wait (__wq_head, &__wbq_entry.wq_entry); \ +__out: __ret; \ +}) + +#define __wait_var_event (var, condition) \ + ___wait_var_event(var, condition, TASK_UNINTERRUPTIBLE, 0, 0, \ + schedule()) + +#define wait_var_event (var, condition) \ +do { \ + might_sleep(); \ + if (condition) \ + break; \ + __wait_var_event(var, condition); \ +} while (0) + +#define __wait_var_event_killable (var, condition) \ + ___wait_var_event(var, condition, TASK_KILLABLE, 0, 0, \ + schedule()) + +#define wait_var_event_killable (var, condition) \ +({ \ + int __ret = 0; \ + might_sleep(); \ + if (!(condition)) \ + __ret = __wait_var_event_killable(var, condition); \ + __ret; \ +}) + +#define __wait_var_event_timeout (var, condition, timeout) \ + ___wait_var_event(var, ___wait_cond_timeout(condition), \ + TASK_UNINTERRUPTIBLE, 0, timeout, \ + __ret = schedule_timeout(__ret)) + +#define wait_var_event_timeout (var, condition, timeout) \ +({ \ + long __ret = timeout; \ + might_sleep(); \ + if (!___wait_cond_timeout(condition)) \ + __ret = __wait_var_event_timeout(var, condition, timeout); \ + __ret; \ +}) +#endif /* _LINUX_WAIT_BIT_H */
kernel/sched/wait_bit.c +48 -0
54 lines not on this page · raw message
Re: [PATCH 01/11] sched/wait: Introduce wait_var_event()
Quoted 32 lines · Peter Zijlstra
As a replacement for the
wait_on_atomic_t()API provide thewait_var_event()API.The
wait_var_event()API is based on the very same hashed-waitqueue idea, but doesn't care about the type (atomic_t) or the specific condition (atomic_read()== 0). IOW. it's much more widely applicable/flexible.It shares all the benefits/disadvantages of a hashed-waitqueue approach with the existing wait_on_atomic_t/wait_on_bit() APIs.
The API is modeled after the existing
wait_event()API, but instead of taking await_queue_head, it takes an address. This addresses is hashed to obtain await_queue_headfrom thebit_wait_table.Similar to the
wait_event()API, it takes a condition expression as second argument and will wait until this expression becomes true.The following are (mostly) identical replacements:
wait_on_atomic_t(&my_atomic, atomic_t_wait, TASK_UNINTERRUPTIBLE); wake_up_atomic_t(&my_atomic); wait_var_event(&my_atomic, !atomic_read(&my_atomic)); wake_up_var(&my_atomic);The only difference is that
wake_up_var()is an unconditional wakeup and doesn't check the previously hard-coded (atomic_read()== 0) condition here. This is of little concequence, since most callers are already conditional onatomic_dec_and_test()and the ones that are not, are trivial to make so.
Quoted 7 lines
Cc David Howells <[email protected]>Tested-by Dan Williams <[email protected]>Signed-off-by Peter Zijlstra (Intel) <[email protected]>--- include/linux/wait_bit.h | 70 +++++++++++++++++++++++++++++++++++++++++++++++ kernel/sched/wait_bit.c | 48 ++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+)
Hi Peter,
Is this commit ready to hit tip/sched/core? I'm looking for an immutable branch that I can use as a basis for the "dax vs dma vs truncate" fix series.
Thanks in advance.
Peter Zijlstra
maintainerPATCH 2/11 sched/wait,drm: Replace wait_on_atomic_t usage
In reply to Peter ZijlstraConvert the wait_on_atomic_t() usage to the new wait_var_event() API.
Unlike the wake_up_atomic_t(), wake_up_var() will issue the wakeup even if the variable is not 0.
--- drivers/gpu/drm/drm_dp_aux_dev.c | 13 +++++++------ drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c | 14 ++++---------- 2 files changed, 11 insertions(+), 16 deletions(-)
drivers/gpu/drm/drm_dp_aux_dev.c +7 -6
@@ -177,8 +177,9 @@ static ssize_t auxdev_read_iter(struct k res = pos - iocb->ki_pos; iocb->ki_pos = pos; -atomic_dec (&aux_dev->usecount); -wake_up_atomic_t (&aux_dev->usecount); +if (atomic_dec_and_test (&aux_dev->usecount)) +wake_up_var (&aux_dev->usecount); +return res; }
@@ -218,8 +219,9 @@ static ssize_t auxdev_write_iter(struct res = pos - iocb->ki_pos; iocb->ki_pos = pos; -atomic_dec (&aux_dev->usecount); -wake_up_atomic_t (&aux_dev->usecount); +if (atomic_dec_and_test (&aux_dev->usecount)) +wake_up_var (&aux_dev->usecount); +return res; }
@@ -277,8 +279,7 @@ void drm_dp_aux_unregister_devnode(strucmutex_unlock (&aux_idr_mutex);atomic_dec (&aux_dev->usecount); -wait_on_atomic_t (&aux_dev->usecount, atomic_t_wait, -TASK_UNINTERRUPTIBLE ); +wait_var_event (&aux_dev->usecount, !atomic_read (&aux_dev->usecount)); minor = aux_dev->index;if (aux_dev->dev)
drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c +4 -10
@@ -271,18 +271,13 @@ struct igt_wakeup {u32 seqno; }; -static int wait_atomic_timeout (atomic_t *p,unsigned int mode) -{ -return schedule_timeout (10 *HZ ) ?0 : -ETIMEDOUT ; -} -static bool wait_for_ready (struct igt_wakeup *w) {DEFINE_WAIT (ready);set_bit (IDLE , &w->flags);if (atomic_dec_and_test (w->done)) -wake_up_atomic_t (w->done); +wake_up_var (w->done);if (test_bit (STOP , &w->flags)) goto out;
@@ -299,7 +294,7 @@ static bool wait_for_ready(struct igt_wa out:clear_bit (IDLE , &w->flags);if (atomic_dec_and_test (w->set)) -wake_up_atomic_t (w->set); +wake_up_var (w->set);return !test_bit (STOP , &w->flags); }
@@ -342,7 +337,7 @@ static void igt_wake_all_sync(atomic_t *atomic_set (ready,0 );wake_up_all (wq); -wait_on_atomic_t (set, atomic_t_wait,TASK_UNINTERRUPTIBLE ); +wait_var_event (set, !atomic_read (set));atomic_set (ready, count);atomic_set (done, count); }
@@ -350,7 +345,6 @@ static void igt_wake_all_sync(atomic_t *static int igt_wakeup (void *arg) {I915_RND_STATE (prng); -const int state =TASK_UNINTERRUPTIBLE ;struct intel_engine_cs *engine = arg;struct igt_wakeup *waiters;DECLARE_WAIT_QUEUE_HEAD_ONSTACK (wq);
@@ -418,7 +412,7 @@ static int igt_wakeup(void *arg)* that they are ready for the next test. We wait until all * threads are complete and waiting for us (i.e. not a seqno). */ - err =wait_on_atomic_t (&done, wait_atomic_timeout, state); + err =wait_var_event_timeout (&done, !atomic_read (&done),10 *HZ );if (err) {pr_err ("Timed out waiting for %d remaining waiters\n" ,atomic_read (&done));
Re: [PATCH 02/11] sched/wait,drm: Replace wait_on_atomic_t usage
Quoting Peter Zijlstra (2018-03-15 12:19:04)
Quoted 8 lines
Convert the
wait_on_atomic_t()usage to the newwait_var_event()API.Unlike the
wake_up_atomic_t(),wake_up_var()will issue the wakeup even if the variable is not 0.Cc Daniel Vetter <[email protected]>Cc David Airlie <[email protected]>Signed-off-by Peter Zijlstra (Intel) <[email protected]>
-Chris
Peter Zijlstra
maintainerPATCH 3/11 sched/wait,media: Replace wait_on_atomic_t usage
In reply to Peter ZijlstraConvert the wait_on_atomic_t() usage to the new wait_var_event() API.
Unlike the wake_up_atomic_t(), wake_up_var() will issue the wakeup even if the variable is not 0.
--- drivers/media/platform/qcom/venus/hfi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/media/platform/qcom/venus/hfi.c +4 -4
@@ -106,8 +106,8 @@ int hfi_core_deinit(struct venus_core *cif (!empty) {mutex_unlock (&core->lock); -wait_on_atomic_t (&core->insts_count, atomic_t_wait, -TASK_UNINTERRUPTIBLE ); +wait_var_event (&core->insts_count, + !atomic_read (&core->insts_count));mutex_lock (&core->lock); }
@@ -229,8 +229,8 @@ void hfi_session_destroy(struct venus_inmutex_lock (&core->lock);list_del_init (&inst->list); -atomic_dec (&core->insts_count); -wake_up_atomic_t (&core->insts_count); +if (atomic_dec_and_test (&core->insts_count)) +wake_up_var (&core->insts_count);mutex_unlock (&core->lock); }EXPORT_SYMBOL_GPL (hfi_session_destroy);
Peter Zijlstra
maintainerPATCH 4/11 sched/wait,afs: Replace wait_on_atomic_t usage
In reply to Peter ZijlstraConvert the wait_on_atomic_t() usage to the new wait_var_event() API.
--- fs/afs/cell.c | 6 +++--- fs/afs/rxrpc.c | 6 +++--- fs/afs/server.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-)
fs/afs/cell.c +3 -3
@@ -25,7 +25,7 @@ static void afs_manage_cell(struct work_static void afs_dec_cells_outstanding (struct afs_net *net) {if (atomic_dec_and_test (&net->cells_outstanding)) -wake_up_atomic_t (&net->cells_outstanding); +wake_up_var (&net->cells_outstanding); }/*
@@ -764,7 +764,7 @@ void afs_cell_purge(struct afs_net *net)afs_queue_cell_manager (net);_debug ("wait" ); -wait_on_atomic_t (&net->cells_outstanding, atomic_t_wait, -TASK_UNINTERRUPTIBLE ); +wait_var_event (&net->cells_outstanding, + !atomic_read (&net->cells_outstanding));_leave ("" ); }
fs/afs/rxrpc.c +3 -3
@@ -103,8 +103,8 @@ void afs_close_socket(struct afs_net *ne }_debug ("outstanding %u" ,atomic_read (&net->nr_outstanding_calls)); -wait_on_atomic_t (&net->nr_outstanding_calls, atomic_t_wait, -TASK_UNINTERRUPTIBLE ); +wait_var_event (&net->nr_outstanding_calls, + !atomic_read (&net->nr_outstanding_calls));_debug ("no outstanding calls" );kernel_sock_shutdown (net->socket,SHUT_RDWR );
@@ -175,7 +175,7 @@ void afs_put_call(struct afs_call *call)trace_afs_call (call, afs_call_trace_free,0 , o,__builtin_return_address (0 ));if (o ==0 ) -wake_up_atomic_t (&net->nr_outstanding_calls); +wake_up_var (&net->nr_outstanding_calls); } }
fs/afs/server.c +3 -3
@@ -25,7 +25,7 @@ static void afs_inc_servers_outstanding(static void afs_dec_servers_outstanding (struct afs_net *net) {if (atomic_dec_and_test (&net->servers_outstanding)) -wake_up_atomic_t (&net->servers_outstanding); +wake_up_var (&net->servers_outstanding); }/*
@@ -521,8 +521,8 @@ void afs_purge_servers(struct afs_net *nafs_queue_server_manager (net);_debug ("wait" ); -wait_on_atomic_t (&net->servers_outstanding, atomic_t_wait, -TASK_UNINTERRUPTIBLE ); +wait_var_event (&net->servers_outstanding, + !atomic_read (&net->servers_outstanding));_leave ("" ); }
Peter Zijlstra
maintainerPATCH 5/11 sched/wait,btrfs: Replace wait_on_atomic_t usage
In reply to Peter ZijlstraConvert the wait_on_atomic_t() usage to the new wait_var_event() API.
--- fs/btrfs/extent-tree.c | 14 ++++++-------- fs/btrfs/ioctl.c | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-)
fs/btrfs/extent-tree.c +6 -8
@@ -3990,7 +3990,7 @@ void btrfs_dec_nocow_writers(struct btrf bg =btrfs_lookup_block_group (fs_info, bytenr);ASSERT (bg);if (atomic_dec_and_test (&bg->nocow_writers)) -wake_up_atomic_t (&bg->nocow_writers); +wake_up_var (&bg->nocow_writers);/* * Once for our lookup and once for the lookup done by a previous call * to btrfs_inc_nocow_writers()
@@ -4001,8 +4001,7 @@ void btrfs_dec_nocow_writers(struct btrfvoid btrfs_wait_nocow_writers (struct btrfs_block_group_cache *bg) { -wait_on_atomic_t (&bg->nocow_writers, atomic_t_wait, -TASK_UNINTERRUPTIBLE ); +wait_var_event (&bg->nocow_writers, !atomic_read (&bg->nocow_writers)); }static const char *alloc_name (u64 flags)
@@ -6526,7 +6525,7 @@ void btrfs_dec_block_group_reservations( bg =btrfs_lookup_block_group (fs_info, start);ASSERT (bg);if (atomic_dec_and_test (&bg->reservations)) -wake_up_atomic_t (&bg->reservations); +wake_up_var (&bg->reservations);btrfs_put_block_group (bg); }
@@ -6552,8 +6551,7 @@ void btrfs_wait_block_group_reservationsdown_write (&space_info->groups_sem);up_write (&space_info->groups_sem); -wait_on_atomic_t (&bg->reservations, atomic_t_wait, -TASK_UNINTERRUPTIBLE ); +wait_var_event (&bg->reservations, !atomic_read (&bg->reservations)); }/**
@@ -11061,7 +11059,7 @@ void btrfs_wait_for_snapshot_creation(st ret =btrfs_start_write_no_snapshotting (root);if (ret)break ; -wait_on_atomic_t (&root->will_be_snapshotted, atomic_t_wait, -TASK_UNINTERRUPTIBLE ); +wait_var_event (&root->will_be_snapshotted, + !atomic_read (&root->will_be_snapshotted)); } }
fs/btrfs/ioctl.c +1 -1
@@ -723,7 +723,7 @@ static int create_snapshot(struct btrfs_btrfs_subvolume_release_metadata (fs_info, &pending_snapshot->block_rsv); dec_and_free:if (atomic_dec_and_test (&root->will_be_snapshotted)) -wake_up_atomic_t (&root->will_be_snapshotted); +wake_up_var (&root->will_be_snapshotted); free_pending:kfree (pending_snapshot->root_item);btrfs_free_path (pending_snapshot->path);
Re: [PATCH 05/11] sched/wait,btrfs: Replace wait_on_atomic_t usage
Quoted 4 lines · Peter Zijlstra
Convert the
wait_on_atomic_t()usage to the newwait_var_event()API.Cc Chris Mason <[email protected]>Signed-off-by Peter Zijlstra (Intel) <[email protected]>
Peter Zijlstra
maintainerPATCH 6/11 sched/wait,fscache: Replace wait_on_atomic_t usage
In reply to Peter ZijlstraConvert the wait_on_atomic_t() usage to the new wait_var_event() API.
--- fs/fscache/cookie.c | 7 ++++--- include/linux/fscache-cache.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-)
fs/fscache/cookie.c +4 -3
@@ -557,9 +557,10 @@ void __fscache_disable_cookie(struct fsc* n_active reaches 0). This makes sure outstanding reads and writes * have completed. */ -if (!atomic_dec_and_test (&cookie->n_active)) -wait_on_atomic_t (&cookie->n_active, atomic_t_wait, -TASK_UNINTERRUPTIBLE ); +if (!atomic_dec_and_test (&cookie->n_active)) { +wait_var_event (&cookie->n_active, + !atomic_read (&cookie->n_active)); + }/* Make sure any pending writes are cancelled. */ if (cookie->def->type !=FSCACHE_COOKIE_TYPE_INDEX )
include/linux/fscache-cache.h +1 -1
@@ -496,7 +496,7 @@ static inline bool __fscache_unuse_cookistatic inline void __fscache_wake_unused_cookie (struct fscache_cookie *cookie) { -wake_up_atomic_t (&cookie->n_active); +wake_up_var (&cookie->n_active); }/**
Peter Zijlstra
maintainerPATCH 7/11 sched/wait,nfs: Replace wait_on_atomic_t usage
In reply to Peter ZijlstraConvert the wait_on_atomic_t() usage to the new wait_var_event() API.
--- fs/nfs/inode.c | 5 ----- fs/nfs/pagelist.c | 6 +++--- fs/nfs/pnfs_nfs.c | 2 +- fs/nfs/write.c | 6 +++--- 4 files changed, 7 insertions(+), 12 deletions(-)
fs/nfs/inode.c +0 -5
@@ -85,11 +85,6 @@ int nfs_wait_bit_killable(struct wait_bi }EXPORT_SYMBOL_GPL (nfs_wait_bit_killable); -int nfs_wait_atomic_killable (atomic_t *p,unsigned int mode) -{ -return nfs_wait_killable (mode); -} -/** * nfs_compat_user_ino64 - returns the user-visible inode number * @fileid: 64-bit fileid
fs/nfs/pagelist.c +3 -3
@@ -98,8 +98,8 @@ nfs_page_free(struct nfs_page *p)int nfs_iocounter_wait (struct nfs_lock_context *l_ctx) { -return wait_on_atomic_t (&l_ctx->io_count, nfs_wait_atomic_killable, -TASK_KILLABLE ); +return wait_var_event_killable (&l_ctx->io_count, + !atomic_read (&l_ctx->io_count)); }/**
@@ -395,7 +395,7 @@ static void nfs_clear_request(struct nfs }if (l_ctx !=NULL ) {if (atomic_dec_and_test (&l_ctx->io_count)) { -wake_up_atomic_t (&l_ctx->io_count); +wake_up_var (&l_ctx->io_count);if (test_bit (NFS_CONTEXT_UNLOCK , &ctx->flags))rpc_wake_up (&NFS_SERVER (d_inode (ctx->dentry))->uoc_rpcwaitq); }
fs/nfs/pnfs_nfs.c +1 -1
@@ -245,7 +245,7 @@ pnfs_generic_commit_cancel_empty_pagelis {if (list_empty (pages)) {if (atomic_dec_and_test (&cinfo->mds->rpcs_out)) -wake_up_atomic_t (&cinfo->mds->rpcs_out); +wake_up_var (&cinfo->mds->rpcs_out);/* don't call nfs_commitdata_release - it tries to put * the open_context which is not acquired until nfs_init_commit * which has not been called on @data */
fs/nfs/write.c +3 -3
@@ -1620,8 +1620,8 @@ static void nfs_writeback_result(structstatic int wait_on_commit (struct nfs_mds_commit_info *cinfo) { -return wait_on_atomic_t (&cinfo->rpcs_out, - nfs_wait_atomic_killable,TASK_KILLABLE ); +return wait_var_event_killable (&cinfo->rpcs_out, + !atomic_read (&cinfo->rpcs_out)); }static void nfs_commit_begin (struct nfs_mds_commit_info *cinfo)
@@ -1632,7 +1632,7 @@ static void nfs_commit_begin(struct nfs_static void nfs_commit_end (struct nfs_mds_commit_info *cinfo) {if (atomic_dec_and_test (&cinfo->rpcs_out)) -wake_up_atomic_t (&cinfo->rpcs_out); +wake_up_var (&cinfo->rpcs_out); }void nfs_commitdata_release (struct nfs_commit_data *data)
Peter Zijlstra
maintainerPATCH 8/11 sched/wait,ocfs2: Replace wait_on_atomic_t usage
In reply to Peter ZijlstraConvert the wait_on_atomic_t() usage to the new wait_var_event() API.
--- fs/ocfs2/filecheck.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
fs/ocfs2/filecheck.c +5 -4
@@ -134,9 +134,10 @@ ocfs2_filecheck_sysfs_free(struct ocfs2_ {struct ocfs2_filecheck_entry *p; -if (!atomic_dec_and_test (&entry->fs_count)) -wait_on_atomic_t (&entry->fs_count, atomic_t_wait, -TASK_UNINTERRUPTIBLE ); +if (!atomic_dec_and_test (&entry->fs_count)) { +wait_var_event (&entry->fs_count, + !atomic_read (&entry->fs_count)); + }spin_lock (&entry->fs_fcheck->fc_lock);while (!list_empty (&entry->fs_fcheck->fc_head)) {
@@ -183,7 +184,7 @@ static void ocfs2_filecheck_sysfs_put(struct ocfs2_filecheck_sysfs_entry *entry) {if (atomic_dec_and_test (&entry->fs_count)) -wake_up_atomic_t (&entry->fs_count); +wake_up_var (&entry->fs_count); } static struct ocfs2_filecheck_sysfs_entry *
Peter Zijlstra
maintainerPATCH 9/11 sched/wait,mips: Fix and replace wait_on_atomic_t usage
In reply to Peter ZijlstraConvert the wait_on_atomic_t() usage to the new wait_var_event() API.
And while there, add the missing wakeup...
--- arch/mips/kernel/process.c | 2 ++ arch/mips/kernel/traps.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-)
arch/mips/kernel/process.c +2 -0
@@ -781,6 +781,8 @@ int mips_set_process_fp_mode(struct taskatomic_set (&task->mm->context.fp_mode_switching,0 );preempt_enable (); +wake_up_var (&task->mm->context.fp_mode_switching); +return 0 ; }
arch/mips/kernel/traps.c +2 -2
@@ -1248,8 +1248,8 @@ static int enable_restore_fp_context(int* If an FP mode switch is currently underway, wait for it to * complete before proceeding. */ -wait_on_atomic_t (¤t->mm->context.fp_mode_switching, - atomic_t_wait,TASK_KILLABLE ); +wait_var_event (¤t->mm->context.fp_mode_switching, + !atomic_read (¤t->mm->context.fp_mode_switching));if (!used_math ()) {/* First time FP context user. */
Peter Zijlstra
maintainerPATCH 10/11 sched/wait: Remove wait_on_atomic_t()
In reply to Peter ZijlstraThere are no users left, remove it.
--- include/linux/wait_bit.h | 27 ------------ kernel/sched/wait_bit.c | 101 ----------------------------------------------- 2 files changed, 128 deletions(-)
include/linux/wait_bit.h +0 -27
@@ -10,7 +10,6 @@struct wait_bit_key {void *flags;int bit_nr; -#define WAIT_ATOMIC_T_BIT_NR -1unsigned long timeout; };
@@ -22,21 +21,15 @@ struct wait_bit_queue_entry {#define __WAIT_BIT_KEY_INITIALIZER (word, bit) \ { .flags = word, .bit_nr = bit, } -#define __WAIT_ATOMIC_T_KEY_INITIALIZER (p) \ - { .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_atomic_t_action_f (atomic_t *counter,unsigned int mode);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_lock (struct wait_queue_head *wq_head,struct wait_bit_queue_entry *wbq_entry,wait_bit_action_f *action,unsigned int mode);void wake_up_bit (void *word,int bit); -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_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_atomic_t (atomic_t *p,wait_atomic_t_action_f action,unsigned int mode);struct wait_queue_head *bit_waitqueue (void *word,int bit);extern void __init wait_bit_init (void );
@@ -57,7 +50,6 @@ extern int bit_wait(struct wait_bit_keyextern int bit_wait_io (struct wait_bit_key *key,int mode);extern int bit_wait_timeout (struct wait_bit_key *key,int mode);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
@@ -243,25 +235,6 @@ wait_on_bit_lock_action(unsigned long *wreturn out_of_line_wait_on_bit_lock (word, bit, action, mode); } -/** -* wait_on_atomic_t - Wait for an atomic_t to become 0 -* @val: The atomic value being waited on, a kernel virtual address -* @action: the function used to sleep, which may take special actions -* @mode: the task state to sleep in -* -* Wait for an atomic_t to become 0. We abuse the bit-wait waitqueue table for -* the purpose of getting a waitqueue, but we set the key to a bit number -* outside of the target 'word'. -*/ -static inline -int wait_on_atomic_t (atomic_t *val,wait_atomic_t_action_f action,unsigned mode) -{ -might_sleep (); -if (atomic_read (val) ==0 ) -return 0 ; -return out_of_line_wait_on_atomic_t (val, action, mode); -} -extern void init_wait_var_entry (struct wait_bit_queue_entry *wbq_entry,void *var,int flags);extern void wake_up_var (void *var);extern wait_queue_head_t *__var_waitqueue (void *p);
kernel/sched/wait_bit.c +0 -101
107 lines not on this page · raw message
Peter Zijlstra
maintainerPATCH 11/11 sched/wait: Improve __var_waitqueue()
In reply to Peter ZijlstraSince we fixed hash_64 to not suck, there is no need to play games to attempt to improve the hash value on 64bit. Also, since we don't use the bit value for the variables, use hash_ptr() directly.
--- kernel/sched/wait_bit.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
kernel/sched/wait_bit.c +1 -6
@@ -151,12 +151,7 @@ EXPORT_SYMBOL(wake_up_bit);wait_queue_head_t *__var_waitqueue (void *p) { -if (BITS_PER_LONG ==64 ) { -unsigned long q = (unsigned long )p; - -return bit_waitqueue ((void *)(q & ~1 ), q &1 ); - } -return bit_waitqueue (p,0 ); +return bit_wait_table +hash_ptr (p,WAIT_TABLE_BITS ); }EXPORT_SYMBOL (__var_waitqueue);