diff options
| author | Tejun Heo <tj@kernel.org> | 2013-04-01 17:08:13 -0700 | 
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2013-04-01 18:45:36 -0700 | 
| commit | 229641a6f1f09e27a1f12fba38980f33f4c92975 (patch) | |
| tree | 234a6f8aea0910de3242af0bbe6d7494fcf81847 /include/linux/idr.h | |
| parent | d55262c4d164759a8debe772da6c9b16059dec47 (diff) | |
| parent | 07961ac7c0ee8b546658717034fe692fd12eefa9 (diff) | |
| download | olio-linux-3.10-229641a6f1f09e27a1f12fba38980f33f4c92975.tar.xz olio-linux-3.10-229641a6f1f09e27a1f12fba38980f33f4c92975.zip  | |
Merge tag 'v3.9-rc5' into wq/for-3.10
Writeback conversion to workqueue will be based on top of wq/for-3.10
branch to take advantage of custom attrs and NUMA support for unbound
workqueues.  Mainline currently contains two commits which result in
non-trivial merge conflicts with wq/for-3.10 and because
block/for-3.10/core is based on v3.9-rc3 which contains one of the
conflicting commits, we need a pre-merge-window merge anyway.  Let's
pull v3.9-rc5 into wq/for-3.10 so that the block tree doesn't suffer
from workqueue merge conflicts.
The two conflicts and their resolutions:
* e68035fb65 ("workqueue: convert to idr_alloc()") in mainline changes
  worker_pool_assign_id() to use idr_alloc() instead of the old idr
  interface.  worker_pool_assign_id() goes through multiple locking
  changes in wq/for-3.10 causing the following conflict.
  static int worker_pool_assign_id(struct worker_pool *pool)
  {
	  int ret;
  <<<<<<< HEAD
	  lockdep_assert_held(&wq_pool_mutex);
	  do {
		  if (!idr_pre_get(&worker_pool_idr, GFP_KERNEL))
			  return -ENOMEM;
		  ret = idr_get_new(&worker_pool_idr, pool, &pool->id);
	  } while (ret == -EAGAIN);
  =======
	  mutex_lock(&worker_pool_idr_mutex);
	  ret = idr_alloc(&worker_pool_idr, pool, 0, 0, GFP_KERNEL);
	  if (ret >= 0)
		  pool->id = ret;
	  mutex_unlock(&worker_pool_idr_mutex);
  >>>>>>> c67bf5361e7e66a0ff1f4caf95f89347d55dfb89
	  return ret < 0 ? ret : 0;
  }
  We want locking from the former and idr_alloc() usage from the
  latter, which can be combined to the following.
  static int worker_pool_assign_id(struct worker_pool *pool)
  {
	  int ret;
	  lockdep_assert_held(&wq_pool_mutex);
	  ret = idr_alloc(&worker_pool_idr, pool, 0, 0, GFP_KERNEL);
	  if (ret >= 0) {
		  pool->id = ret;
		  return 0;
	  }
	  return ret;
   }
* eb2834285c ("workqueue: fix possible pool stall bug in
  wq_unbind_fn()") updated wq_unbind_fn() such that it has single
  larger for_each_std_worker_pool() loop instead of two separate loops
  with a schedule() call inbetween.  wq/for-3.10 renamed
  pool->assoc_mutex to pool->manager_mutex causing the following
  conflict (earlier function body and comments omitted for brevity).
  static void wq_unbind_fn(struct work_struct *work)
  {
  ...
		  spin_unlock_irq(&pool->lock);
  <<<<<<< HEAD
		  mutex_unlock(&pool->manager_mutex);
	  }
  =======
		  mutex_unlock(&pool->assoc_mutex);
  >>>>>>> c67bf5361e7e66a0ff1f4caf95f89347d55dfb89
		  schedule();
  <<<<<<< HEAD
	  for_each_cpu_worker_pool(pool, cpu)
  =======
  >>>>>>> c67bf5361e7e66a0ff1f4caf95f89347d55dfb89
		  atomic_set(&pool->nr_running, 0);
		  spin_lock_irq(&pool->lock);
		  wake_up_worker(pool);
		  spin_unlock_irq(&pool->lock);
	  }
  }
  The resolution is mostly trivial.  We want the control flow of the
  latter with the rename of the former.
  static void wq_unbind_fn(struct work_struct *work)
  {
  ...
		  spin_unlock_irq(&pool->lock);
		  mutex_unlock(&pool->manager_mutex);
		  schedule();
		  atomic_set(&pool->nr_running, 0);
		  spin_lock_irq(&pool->lock);
		  wake_up_worker(pool);
		  spin_unlock_irq(&pool->lock);
	  }
  }
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'include/linux/idr.h')
| -rw-r--r-- | include/linux/idr.h | 68 | 
1 files changed, 51 insertions, 17 deletions
diff --git a/include/linux/idr.h b/include/linux/idr.h index a6f38b5c34e..2640c7e99e5 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -73,8 +73,6 @@ struct idr {   */  void *idr_find_slowpath(struct idr *idp, int id); -int idr_pre_get(struct idr *idp, gfp_t gfp_mask); -int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);  void idr_preload(gfp_t gfp_mask);  int idr_alloc(struct idr *idp, void *ptr, int start, int end, gfp_t gfp_mask);  int idr_for_each(struct idr *idp, @@ -99,7 +97,7 @@ static inline void idr_preload_end(void)  /**   * idr_find - return pointer for given id - * @idp: idr handle + * @idr: idr handle   * @id: lookup key   *   * Return the pointer given the id it has been registered with.  A %NULL @@ -120,19 +118,6 @@ static inline void *idr_find(struct idr *idr, int id)  }  /** - * idr_get_new - allocate new idr entry - * @idp: idr handle - * @ptr: pointer you want associated with the id - * @id: pointer to the allocated handle - * - * Simple wrapper around idr_get_new_above() w/ @starting_id of zero. - */ -static inline int idr_get_new(struct idr *idp, void *ptr, int *id) -{ -	return idr_get_new_above(idp, ptr, 0, id); -} - -/**   * idr_for_each_entry - iterate over an idr's elements of a given type   * @idp:     idr handle   * @entry:   the type * to use as cursor @@ -143,7 +128,56 @@ static inline int idr_get_new(struct idr *idp, void *ptr, int *id)  	     entry != NULL;                                             \  	     ++id, entry = (typeof(entry))idr_get_next((idp), &(id))) -void __idr_remove_all(struct idr *idp);	/* don't use */ +/* + * Don't use the following functions.  These exist only to suppress + * deprecated warnings on EXPORT_SYMBOL()s. + */ +int __idr_pre_get(struct idr *idp, gfp_t gfp_mask); +int __idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id); +void __idr_remove_all(struct idr *idp); + +/** + * idr_pre_get - reserve resources for idr allocation + * @idp:	idr handle + * @gfp_mask:	memory allocation flags + * + * Part of old alloc interface.  This is going away.  Use + * idr_preload[_end]() and idr_alloc() instead. + */ +static inline int __deprecated idr_pre_get(struct idr *idp, gfp_t gfp_mask) +{ +	return __idr_pre_get(idp, gfp_mask); +} + +/** + * idr_get_new_above - allocate new idr entry above or equal to a start id + * @idp: idr handle + * @ptr: pointer you want associated with the id + * @starting_id: id to start search at + * @id: pointer to the allocated handle + * + * Part of old alloc interface.  This is going away.  Use + * idr_preload[_end]() and idr_alloc() instead. + */ +static inline int __deprecated idr_get_new_above(struct idr *idp, void *ptr, +						 int starting_id, int *id) +{ +	return __idr_get_new_above(idp, ptr, starting_id, id); +} + +/** + * idr_get_new - allocate new idr entry + * @idp: idr handle + * @ptr: pointer you want associated with the id + * @id: pointer to the allocated handle + * + * Part of old alloc interface.  This is going away.  Use + * idr_preload[_end]() and idr_alloc() instead. + */ +static inline int __deprecated idr_get_new(struct idr *idp, void *ptr, int *id) +{ +	return __idr_get_new_above(idp, ptr, 0, id); +}  /**   * idr_remove_all - remove all ids from the given idr tree  |