| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2005 Topspin Communications.  All rights reserved. | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  |  * Copyright (c) 2005, 2006, 2007 Cisco Systems.  All rights reserved. | 
					
						
							| 
									
										
										
										
											2005-09-27 15:07:25 -07:00
										 |  |  |  * Copyright (c) 2005 PathScale, Inc.  All rights reserved. | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:57 -08:00
										 |  |  |  * Copyright (c) 2006 Mellanox Technologies.  All rights reserved. | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This software is available to you under a choice of one of two | 
					
						
							|  |  |  |  * licenses.  You may choose to be licensed under the terms of the GNU | 
					
						
							|  |  |  |  * General Public License (GPL) Version 2, available from the file | 
					
						
							|  |  |  |  * COPYING in the main directory of this source tree, or the | 
					
						
							|  |  |  |  * OpenIB.org BSD license below: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     Redistribution and use in source and binary forms, with or | 
					
						
							|  |  |  |  *     without modification, are permitted provided that the following | 
					
						
							|  |  |  |  *     conditions are met: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *      - Redistributions of source code must retain the above | 
					
						
							|  |  |  |  *        copyright notice, this list of conditions and the following | 
					
						
							|  |  |  |  *        disclaimer. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *      - Redistributions in binary form must reproduce the above | 
					
						
							|  |  |  |  *        copyright notice, this list of conditions and the following | 
					
						
							|  |  |  |  *        disclaimer in the documentation and/or other materials | 
					
						
							|  |  |  |  *        provided with the distribution. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
					
						
							|  |  |  |  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 
					
						
							|  |  |  |  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 
					
						
							|  |  |  |  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | 
					
						
							|  |  |  |  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | 
					
						
							|  |  |  |  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | 
					
						
							|  |  |  |  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 
					
						
							|  |  |  |  * SOFTWARE. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | #include <linux/file.h>
 | 
					
						
							| 
									
										
										
										
											2005-10-28 15:38:26 -07:00
										 |  |  | #include <linux/fs.h>
 | 
					
						
							| 
									
										
											  
											
												include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
percpu.h is included by sched.h and module.h and thus ends up being
included when building most .c files.  percpu.h includes slab.h which
in turn includes gfp.h making everything defined by the two files
universally available and complicating inclusion dependencies.
percpu.h -> slab.h dependency is about to be removed.  Prepare for
this change by updating users of gfp and slab facilities include those
headers directly instead of assuming availability.  As this conversion
needs to touch large number of source files, the following script is
used as the basis of conversion.
  http://userweb.kernel.org/~tj/misc/slabh-sweep.py
The script does the followings.
* Scan files for gfp and slab usages and update includes such that
  only the necessary includes are there.  ie. if only gfp is used,
  gfp.h, if slab is used, slab.h.
* When the script inserts a new include, it looks at the include
  blocks and try to put the new include such that its order conforms
  to its surrounding.  It's put in the include block which contains
  core kernel includes, in the same order that the rest are ordered -
  alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
  doesn't seem to be any matching order.
* If the script can't find a place to put a new include (mostly
  because the file doesn't have fitting include block), it prints out
  an error message indicating which .h file needs to be added to the
  file.
The conversion was done in the following steps.
1. The initial automatic conversion of all .c files updated slightly
   over 4000 files, deleting around 700 includes and adding ~480 gfp.h
   and ~3000 slab.h inclusions.  The script emitted errors for ~400
   files.
2. Each error was manually checked.  Some didn't need the inclusion,
   some needed manual addition while adding it to implementation .h or
   embedding .c file was more appropriate for others.  This step added
   inclusions to around 150 files.
3. The script was run again and the output was compared to the edits
   from #2 to make sure no file was left behind.
4. Several build tests were done and a couple of problems were fixed.
   e.g. lib/decompress_*.c used malloc/free() wrappers around slab
   APIs requiring slab.h to be added manually.
5. The script was run on all .h files but without automatically
   editing them as sprinkling gfp.h and slab.h inclusions around .h
   files could easily lead to inclusion dependency hell.  Most gfp.h
   inclusion directives were ignored as stuff from gfp.h was usually
   wildly available and often used in preprocessor macros.  Each
   slab.h inclusion directive was examined and added manually as
   necessary.
6. percpu.h was updated not to include slab.h.
7. Build test were done on the following configurations and failures
   were fixed.  CONFIG_GCOV_KERNEL was turned off for all tests (as my
   distributed build env didn't work with gcov compiles) and a few
   more options had to be turned off depending on archs to make things
   build (like ipr on powerpc/64 which failed due to missing writeq).
   * x86 and x86_64 UP and SMP allmodconfig and a custom test config.
   * powerpc and powerpc64 SMP allmodconfig
   * sparc and sparc64 SMP allmodconfig
   * ia64 SMP allmodconfig
   * s390 SMP allmodconfig
   * alpha SMP allmodconfig
   * um on x86_64 SMP allmodconfig
8. percpu.h modifications were reverted so that it could be applied as
   a separate patch and serve as bisection point.
Given the fact that I had only a couple of failures from tests on step
6, I'm fairly confident about the coverage of this conversion patch.
If there is a breakage, it's likely to be something in one of the arch
headers which should be easily discoverable easily on most builds of
the specific arch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
											
										 
											2010-03-24 17:04:11 +09:00
										 |  |  | #include <linux/slab.h>
 | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | #include <asm/uaccess.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "uverbs.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 15:16:04 -07:00
										 |  |  | static struct lock_class_key pd_lock_key; | 
					
						
							|  |  |  | static struct lock_class_key mr_lock_key; | 
					
						
							|  |  |  | static struct lock_class_key cq_lock_key; | 
					
						
							|  |  |  | static struct lock_class_key qp_lock_key; | 
					
						
							|  |  |  | static struct lock_class_key ah_lock_key; | 
					
						
							|  |  |  | static struct lock_class_key srq_lock_key; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | #define INIT_UDATA(udata, ibuf, obuf, ilen, olen)			\
 | 
					
						
							|  |  |  | 	do {								\ | 
					
						
							|  |  |  | 		(udata)->inbuf  = (void __user *) (ibuf);		\ | 
					
						
							|  |  |  | 		(udata)->outbuf = (void __user *) (obuf);		\ | 
					
						
							|  |  |  | 		(udata)->inlen  = (ilen);				\ | 
					
						
							|  |  |  | 		(udata)->outlen = (olen);				\ | 
					
						
							|  |  |  | 	} while (0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * The ib_uobject locking scheme is as follows: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * - ib_uverbs_idr_lock protects the uverbs idrs themselves, so it | 
					
						
							|  |  |  |  *   needs to be held during all idr operations.  When an object is | 
					
						
							|  |  |  |  *   looked up, a reference must be taken on the object's kref before | 
					
						
							|  |  |  |  *   dropping this lock. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * - Each object also has an rwsem.  This rwsem must be held for | 
					
						
							|  |  |  |  *   reading while an operation that uses the object is performed. | 
					
						
							|  |  |  |  *   For example, while registering an MR, the associated PD's | 
					
						
							|  |  |  |  *   uobject.mutex must be held for reading.  The rwsem must be held | 
					
						
							|  |  |  |  *   for writing while initializing or destroying an object. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * - In addition, each object has a "live" flag.  If this flag is not | 
					
						
							|  |  |  |  *   set, then lookups of the object will fail even if it is found in | 
					
						
							|  |  |  |  *   the idr.  This handles a reader that blocks and does not acquire | 
					
						
							|  |  |  |  *   the rwsem until after the object is destroyed.  The destroy | 
					
						
							|  |  |  |  *   operation will set the live flag to 0 and then drop the rwsem; | 
					
						
							|  |  |  |  *   this will allow the reader to acquire the rwsem, see that the | 
					
						
							|  |  |  |  *   live flag is 0, and then drop the rwsem and its reference to | 
					
						
							|  |  |  |  *   object.  The underlying storage will not be freed until the last | 
					
						
							|  |  |  |  *   reference to the object is dropped. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void init_uobj(struct ib_uobject *uobj, u64 user_handle, | 
					
						
							| 
									
										
										
										
											2006-07-23 15:16:04 -07:00
										 |  |  | 		      struct ib_ucontext *context, struct lock_class_key *key) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	uobj->user_handle = user_handle; | 
					
						
							|  |  |  | 	uobj->context     = context; | 
					
						
							|  |  |  | 	kref_init(&uobj->ref); | 
					
						
							|  |  |  | 	init_rwsem(&uobj->mutex); | 
					
						
							| 
									
										
										
										
											2006-07-23 15:16:04 -07:00
										 |  |  | 	lockdep_set_class(&uobj->mutex, key); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	uobj->live        = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void release_uobj(struct kref *kref) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	kfree(container_of(kref, struct ib_uobject, ref)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void put_uobj(struct ib_uobject *uobj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	kref_put(&uobj->ref, release_uobj); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void put_uobj_read(struct ib_uobject *uobj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	up_read(&uobj->mutex); | 
					
						
							|  |  |  | 	put_uobj(uobj); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void put_uobj_write(struct ib_uobject *uobj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	up_write(&uobj->mutex); | 
					
						
							|  |  |  | 	put_uobj(uobj); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int idr_add_uobj(struct idr *idr, struct ib_uobject *uobj) | 
					
						
							| 
									
										
										
										
											2006-06-17 20:37:40 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | retry: | 
					
						
							|  |  |  | 	if (!idr_pre_get(idr, GFP_KERNEL)) | 
					
						
							|  |  |  | 		return -ENOMEM; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	spin_lock(&ib_uverbs_idr_lock); | 
					
						
							| 
									
										
										
										
											2006-06-17 20:37:40 -07:00
										 |  |  | 	ret = idr_get_new(idr, uobj, &uobj->id); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	spin_unlock(&ib_uverbs_idr_lock); | 
					
						
							| 
									
										
										
										
											2006-06-17 20:37:40 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (ret == -EAGAIN) | 
					
						
							|  |  |  | 		goto retry; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | void idr_remove_uobj(struct idr *idr, struct ib_uobject *uobj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	spin_lock(&ib_uverbs_idr_lock); | 
					
						
							|  |  |  | 	idr_remove(idr, uobj->id); | 
					
						
							|  |  |  | 	spin_unlock(&ib_uverbs_idr_lock); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id, | 
					
						
							|  |  |  | 					 struct ib_ucontext *context) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uobject *uobj; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock(&ib_uverbs_idr_lock); | 
					
						
							|  |  |  | 	uobj = idr_find(idr, id); | 
					
						
							| 
									
										
										
										
											2007-10-19 20:01:43 -07:00
										 |  |  | 	if (uobj) { | 
					
						
							|  |  |  | 		if (uobj->context == context) | 
					
						
							|  |  |  | 			kref_get(&uobj->ref); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			uobj = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	spin_unlock(&ib_uverbs_idr_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return uobj; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ib_uobject *idr_read_uobj(struct idr *idr, int id, | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | 					struct ib_ucontext *context, int nested) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ib_uobject *uobj; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uobj = __idr_get_uobj(idr, id, context); | 
					
						
							|  |  |  | 	if (!uobj) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | 	if (nested) | 
					
						
							|  |  |  | 		down_read_nested(&uobj->mutex, SINGLE_DEPTH_NESTING); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		down_read(&uobj->mutex); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	if (!uobj->live) { | 
					
						
							|  |  |  | 		put_uobj_read(uobj); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return uobj; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ib_uobject *idr_write_uobj(struct idr *idr, int id, | 
					
						
							|  |  |  | 					 struct ib_ucontext *context) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uobject *uobj; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uobj = __idr_get_uobj(idr, id, context); | 
					
						
							|  |  |  | 	if (!uobj) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	down_write(&uobj->mutex); | 
					
						
							|  |  |  | 	if (!uobj->live) { | 
					
						
							|  |  |  | 		put_uobj_write(uobj); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return uobj; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | static void *idr_read_obj(struct idr *idr, int id, struct ib_ucontext *context, | 
					
						
							|  |  |  | 			  int nested) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ib_uobject *uobj; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | 	uobj = idr_read_uobj(idr, id, context, nested); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	return uobj ? uobj->object : NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ib_pd *idr_read_pd(int pd_handle, struct ib_ucontext *context) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | 	return idr_read_obj(&ib_uverbs_pd_idr, pd_handle, context, 0); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void put_pd_read(struct ib_pd *pd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	put_uobj_read(pd->uobject); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | static struct ib_cq *idr_read_cq(int cq_handle, struct ib_ucontext *context, int nested) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | 	return idr_read_obj(&ib_uverbs_cq_idr, cq_handle, context, nested); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void put_cq_read(struct ib_cq *cq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	put_uobj_read(cq->uobject); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ib_ah *idr_read_ah(int ah_handle, struct ib_ucontext *context) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | 	return idr_read_obj(&ib_uverbs_ah_idr, ah_handle, context, 0); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void put_ah_read(struct ib_ah *ah) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	put_uobj_read(ah->uobject); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ib_qp *idr_read_qp(int qp_handle, struct ib_ucontext *context) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | 	return idr_read_obj(&ib_uverbs_qp_idr, qp_handle, context, 0); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void put_qp_read(struct ib_qp *qp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	put_uobj_read(qp->uobject); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ib_srq *idr_read_srq(int srq_handle, struct ib_ucontext *context) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | 	return idr_read_obj(&ib_uverbs_srq_idr, srq_handle, context, 0); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void put_srq_read(struct ib_srq *srq) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	put_uobj_read(srq->uobject); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			      const char __user *buf, | 
					
						
							|  |  |  | 			      int in_len, int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_get_context      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_get_context_resp resp; | 
					
						
							|  |  |  | 	struct ib_udata                   udata; | 
					
						
							|  |  |  | 	struct ib_device                 *ibdev = file->device->ib_dev; | 
					
						
							| 
									
										
										
										
											2005-09-26 13:01:03 -07:00
										 |  |  | 	struct ib_ucontext		 *ucontext; | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 	struct file			 *filp; | 
					
						
							| 
									
										
										
										
											2005-09-26 13:01:03 -07:00
										 |  |  | 	int ret; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (out_len < sizeof resp) | 
					
						
							|  |  |  | 		return -ENOSPC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_lock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-09-26 13:01:03 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (file->ucontext) { | 
					
						
							|  |  |  | 		ret = -EINVAL; | 
					
						
							|  |  |  | 		goto err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	INIT_UDATA(&udata, buf + sizeof cmd, | 
					
						
							|  |  |  | 		   (unsigned long) cmd.response + sizeof resp, | 
					
						
							|  |  |  | 		   in_len - sizeof cmd, out_len - sizeof resp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-26 13:01:03 -07:00
										 |  |  | 	ucontext = ibdev->alloc_ucontext(ibdev, &udata); | 
					
						
							| 
									
										
										
										
											2006-06-17 20:37:40 -07:00
										 |  |  | 	if (IS_ERR(ucontext)) { | 
					
						
							| 
									
										
										
										
											2009-12-09 14:30:44 -08:00
										 |  |  | 		ret = PTR_ERR(ucontext); | 
					
						
							| 
									
										
										
										
											2006-06-17 20:37:40 -07:00
										 |  |  | 		goto err; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-26 13:01:03 -07:00
										 |  |  | 	ucontext->device = ibdev; | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&ucontext->pd_list); | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&ucontext->mr_list); | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&ucontext->mw_list); | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&ucontext->cq_list); | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&ucontext->qp_list); | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&ucontext->srq_list); | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&ucontext->ah_list); | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	ucontext->closing = 0; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 	resp.num_comp_vectors = file->device->num_comp_vectors; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 01:38:00 -05:00
										 |  |  | 	ret = get_unused_fd(); | 
					
						
							|  |  |  | 	if (ret < 0) | 
					
						
							|  |  |  | 		goto err_free; | 
					
						
							|  |  |  | 	resp.async_fd = ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	filp = ib_uverbs_alloc_event_file(file, 1); | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 	if (IS_ERR(filp)) { | 
					
						
							|  |  |  | 		ret = PTR_ERR(filp); | 
					
						
							| 
									
										
										
										
											2010-01-18 01:38:00 -05:00
										 |  |  | 		goto err_fd; | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							| 
									
										
										
										
											2005-09-26 13:01:03 -07:00
										 |  |  | 			 &resp, sizeof resp)) { | 
					
						
							|  |  |  | 		ret = -EFAULT; | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 		goto err_file; | 
					
						
							| 
									
										
										
										
											2005-09-26 13:01:03 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 	file->async_file = filp->private_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	INIT_IB_EVENT_HANDLER(&file->event_handler, file->device->ib_dev, | 
					
						
							|  |  |  | 			      ib_uverbs_event_handler); | 
					
						
							|  |  |  | 	ret = ib_register_event_handler(&file->event_handler); | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							|  |  |  | 		goto err_file; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	kref_get(&file->async_file->ref); | 
					
						
							|  |  |  | 	kref_get(&file->ref); | 
					
						
							| 
									
										
										
										
											2005-10-28 15:38:26 -07:00
										 |  |  | 	file->ucontext = ucontext; | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	fd_install(resp.async_fd, filp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return in_len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | err_file: | 
					
						
							|  |  |  | 	fput(filp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 01:38:00 -05:00
										 |  |  | err_fd: | 
					
						
							|  |  |  | 	put_unused_fd(resp.async_fd); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-26 13:01:03 -07:00
										 |  |  | err_free: | 
					
						
							|  |  |  | 	ibdev->dealloc_ucontext(ucontext); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-26 13:01:03 -07:00
										 |  |  | err: | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-09-26 13:01:03 -07:00
										 |  |  | 	return ret; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			       const char __user *buf, | 
					
						
							|  |  |  | 			       int in_len, int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_query_device      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_query_device_resp resp; | 
					
						
							|  |  |  | 	struct ib_device_attr              attr; | 
					
						
							|  |  |  | 	int                                ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (out_len < sizeof resp) | 
					
						
							|  |  |  | 		return -ENOSPC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = ib_query_device(file->device->ib_dev, &attr); | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memset(&resp, 0, sizeof resp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp.fw_ver 		       = attr.fw_ver; | 
					
						
							| 
									
										
										
										
											2006-01-10 07:39:34 -08:00
										 |  |  | 	resp.node_guid 		       = file->device->ib_dev->node_guid; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	resp.sys_image_guid 	       = attr.sys_image_guid; | 
					
						
							|  |  |  | 	resp.max_mr_size 	       = attr.max_mr_size; | 
					
						
							|  |  |  | 	resp.page_size_cap 	       = attr.page_size_cap; | 
					
						
							|  |  |  | 	resp.vendor_id 		       = attr.vendor_id; | 
					
						
							|  |  |  | 	resp.vendor_part_id 	       = attr.vendor_part_id; | 
					
						
							|  |  |  | 	resp.hw_ver 		       = attr.hw_ver; | 
					
						
							|  |  |  | 	resp.max_qp 		       = attr.max_qp; | 
					
						
							|  |  |  | 	resp.max_qp_wr 		       = attr.max_qp_wr; | 
					
						
							|  |  |  | 	resp.device_cap_flags 	       = attr.device_cap_flags; | 
					
						
							|  |  |  | 	resp.max_sge 		       = attr.max_sge; | 
					
						
							|  |  |  | 	resp.max_sge_rd 	       = attr.max_sge_rd; | 
					
						
							|  |  |  | 	resp.max_cq 		       = attr.max_cq; | 
					
						
							|  |  |  | 	resp.max_cqe 		       = attr.max_cqe; | 
					
						
							|  |  |  | 	resp.max_mr 		       = attr.max_mr; | 
					
						
							|  |  |  | 	resp.max_pd 		       = attr.max_pd; | 
					
						
							|  |  |  | 	resp.max_qp_rd_atom 	       = attr.max_qp_rd_atom; | 
					
						
							|  |  |  | 	resp.max_ee_rd_atom 	       = attr.max_ee_rd_atom; | 
					
						
							|  |  |  | 	resp.max_res_rd_atom 	       = attr.max_res_rd_atom; | 
					
						
							|  |  |  | 	resp.max_qp_init_rd_atom       = attr.max_qp_init_rd_atom; | 
					
						
							|  |  |  | 	resp.max_ee_init_rd_atom       = attr.max_ee_init_rd_atom; | 
					
						
							|  |  |  | 	resp.atomic_cap 	       = attr.atomic_cap; | 
					
						
							|  |  |  | 	resp.max_ee 		       = attr.max_ee; | 
					
						
							|  |  |  | 	resp.max_rdd 		       = attr.max_rdd; | 
					
						
							|  |  |  | 	resp.max_mw 		       = attr.max_mw; | 
					
						
							|  |  |  | 	resp.max_raw_ipv6_qp 	       = attr.max_raw_ipv6_qp; | 
					
						
							|  |  |  | 	resp.max_raw_ethy_qp 	       = attr.max_raw_ethy_qp; | 
					
						
							|  |  |  | 	resp.max_mcast_grp 	       = attr.max_mcast_grp; | 
					
						
							|  |  |  | 	resp.max_mcast_qp_attach       = attr.max_mcast_qp_attach; | 
					
						
							|  |  |  | 	resp.max_total_mcast_qp_attach = attr.max_total_mcast_qp_attach; | 
					
						
							|  |  |  | 	resp.max_ah 		       = attr.max_ah; | 
					
						
							|  |  |  | 	resp.max_fmr 		       = attr.max_fmr; | 
					
						
							|  |  |  | 	resp.max_map_per_fmr 	       = attr.max_map_per_fmr; | 
					
						
							|  |  |  | 	resp.max_srq 		       = attr.max_srq; | 
					
						
							|  |  |  | 	resp.max_srq_wr 	       = attr.max_srq_wr; | 
					
						
							|  |  |  | 	resp.max_srq_sge 	       = attr.max_srq_sge; | 
					
						
							|  |  |  | 	resp.max_pkeys 		       = attr.max_pkeys; | 
					
						
							|  |  |  | 	resp.local_ca_ack_delay        = attr.local_ca_ack_delay; | 
					
						
							|  |  |  | 	resp.phys_port_cnt	       = file->device->ib_dev->phys_port_cnt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return in_len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			     const char __user *buf, | 
					
						
							|  |  |  | 			     int in_len, int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_query_port      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_query_port_resp resp; | 
					
						
							|  |  |  | 	struct ib_port_attr              attr; | 
					
						
							|  |  |  | 	int                              ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (out_len < sizeof resp) | 
					
						
							|  |  |  | 		return -ENOSPC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = ib_query_port(file->device->ib_dev, cmd.port_num, &attr); | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memset(&resp, 0, sizeof resp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp.state 	     = attr.state; | 
					
						
							|  |  |  | 	resp.max_mtu 	     = attr.max_mtu; | 
					
						
							|  |  |  | 	resp.active_mtu      = attr.active_mtu; | 
					
						
							|  |  |  | 	resp.gid_tbl_len     = attr.gid_tbl_len; | 
					
						
							|  |  |  | 	resp.port_cap_flags  = attr.port_cap_flags; | 
					
						
							|  |  |  | 	resp.max_msg_sz      = attr.max_msg_sz; | 
					
						
							|  |  |  | 	resp.bad_pkey_cntr   = attr.bad_pkey_cntr; | 
					
						
							|  |  |  | 	resp.qkey_viol_cntr  = attr.qkey_viol_cntr; | 
					
						
							|  |  |  | 	resp.pkey_tbl_len    = attr.pkey_tbl_len; | 
					
						
							|  |  |  | 	resp.lid 	     = attr.lid; | 
					
						
							|  |  |  | 	resp.sm_lid 	     = attr.sm_lid; | 
					
						
							|  |  |  | 	resp.lmc 	     = attr.lmc; | 
					
						
							|  |  |  | 	resp.max_vl_num      = attr.max_vl_num; | 
					
						
							|  |  |  | 	resp.sm_sl 	     = attr.sm_sl; | 
					
						
							|  |  |  | 	resp.subnet_timeout  = attr.subnet_timeout; | 
					
						
							|  |  |  | 	resp.init_type_reply = attr.init_type_reply; | 
					
						
							|  |  |  | 	resp.active_width    = attr.active_width; | 
					
						
							|  |  |  | 	resp.active_speed    = attr.active_speed; | 
					
						
							|  |  |  | 	resp.phys_state      = attr.phys_state; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return in_len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			   const char __user *buf, | 
					
						
							|  |  |  | 			   int in_len, int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_alloc_pd      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_alloc_pd_resp resp; | 
					
						
							|  |  |  | 	struct ib_udata                udata; | 
					
						
							|  |  |  | 	struct ib_uobject             *uobj; | 
					
						
							|  |  |  | 	struct ib_pd                  *pd; | 
					
						
							|  |  |  | 	int                            ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (out_len < sizeof resp) | 
					
						
							|  |  |  | 		return -ENOSPC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	INIT_UDATA(&udata, buf + sizeof cmd, | 
					
						
							|  |  |  | 		   (unsigned long) cmd.response + sizeof resp, | 
					
						
							|  |  |  | 		   in_len - sizeof cmd, out_len - sizeof resp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uobj = kmalloc(sizeof *uobj, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!uobj) | 
					
						
							|  |  |  | 		return -ENOMEM; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 15:16:04 -07:00
										 |  |  | 	init_uobj(uobj, 0, file->ucontext, &pd_lock_key); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	down_write(&uobj->mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	pd = file->device->ib_dev->alloc_pd(file->device->ib_dev, | 
					
						
							|  |  |  | 					    file->ucontext, &udata); | 
					
						
							|  |  |  | 	if (IS_ERR(pd)) { | 
					
						
							|  |  |  | 		ret = PTR_ERR(pd); | 
					
						
							|  |  |  | 		goto err; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pd->device  = file->device->ib_dev; | 
					
						
							|  |  |  | 	pd->uobject = uobj; | 
					
						
							|  |  |  | 	atomic_set(&pd->usecnt, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	uobj->object = pd; | 
					
						
							|  |  |  | 	ret = idr_add_uobj(&ib_uverbs_pd_idr, uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	if (ret) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err_idr; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	memset(&resp, 0, sizeof resp); | 
					
						
							|  |  |  | 	resp.pd_handle = uobj->id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) { | 
					
						
							|  |  |  | 		ret = -EFAULT; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err_copy; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_lock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-09-27 15:07:25 -07:00
										 |  |  | 	list_add_tail(&uobj->list, &file->ucontext->pd_list); | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	uobj->live = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	up_write(&uobj->mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-27 15:07:25 -07:00
										 |  |  | 	return in_len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | err_copy: | 
					
						
							|  |  |  | 	idr_remove_uobj(&ib_uverbs_pd_idr, uobj); | 
					
						
							| 
									
										
										
										
											2005-09-27 15:07:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | err_idr: | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	ib_dealloc_pd(pd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | err: | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_uobj_write(uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			     const char __user *buf, | 
					
						
							|  |  |  | 			     int in_len, int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_dealloc_pd cmd; | 
					
						
							|  |  |  | 	struct ib_uobject          *uobj; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	int                         ret; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	uobj = idr_write_uobj(&ib_uverbs_pd_idr, cmd.pd_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!uobj) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	ret = ib_dealloc_pd(uobj->object); | 
					
						
							|  |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		uobj->live = 0; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_uobj_write(uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		return ret; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	idr_remove_uobj(&ib_uverbs_pd_idr, uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_lock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	list_del(&uobj->list); | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_uobj(uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	return in_len; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			 const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			 int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_reg_mr      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_reg_mr_resp resp; | 
					
						
							|  |  |  | 	struct ib_udata              udata; | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	struct ib_uobject           *uobj; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	struct ib_pd                *pd; | 
					
						
							|  |  |  | 	struct ib_mr                *mr; | 
					
						
							|  |  |  | 	int                          ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (out_len < sizeof resp) | 
					
						
							|  |  |  | 		return -ENOSPC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	INIT_UDATA(&udata, buf + sizeof cmd, | 
					
						
							|  |  |  | 		   (unsigned long) cmd.response + sizeof resp, | 
					
						
							|  |  |  | 		   in_len - sizeof cmd, out_len - sizeof resp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK)) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-03 09:18:02 -07:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Local write permission is required if remote write or | 
					
						
							|  |  |  | 	 * remote atomic permission is also requested. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (cmd.access_flags & (IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_REMOTE_WRITE) && | 
					
						
							|  |  |  | 	    !(cmd.access_flags & IB_ACCESS_LOCAL_WRITE)) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	uobj = kmalloc(sizeof *uobj, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!uobj) | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 		return -ENOMEM; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	init_uobj(uobj, 0, file->ucontext, &mr_lock_key); | 
					
						
							|  |  |  | 	down_write(&uobj->mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	pd = idr_read_pd(cmd.pd_handle, file->ucontext); | 
					
						
							| 
									
										
										
										
											2007-02-22 13:16:51 -08:00
										 |  |  | 	if (!pd) { | 
					
						
							|  |  |  | 		ret = -EINVAL; | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 		goto err_free; | 
					
						
							| 
									
										
										
										
											2007-02-22 13:16:51 -08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	mr = pd->device->reg_user_mr(pd, cmd.start, cmd.length, cmd.hca_va, | 
					
						
							|  |  |  | 				     cmd.access_flags, &udata); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	if (IS_ERR(mr)) { | 
					
						
							|  |  |  | 		ret = PTR_ERR(mr); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err_put; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mr->device  = pd->device; | 
					
						
							|  |  |  | 	mr->pd      = pd; | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	mr->uobject = uobj; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	atomic_inc(&pd->usecnt); | 
					
						
							|  |  |  | 	atomic_set(&mr->usecnt, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	uobj->object = mr; | 
					
						
							|  |  |  | 	ret = idr_add_uobj(&ib_uverbs_mr_idr, uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	if (ret) | 
					
						
							|  |  |  | 		goto err_unreg; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	memset(&resp, 0, sizeof resp); | 
					
						
							|  |  |  | 	resp.lkey      = mr->lkey; | 
					
						
							|  |  |  | 	resp.rkey      = mr->rkey; | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	resp.mr_handle = uobj->id; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) { | 
					
						
							|  |  |  | 		ret = -EFAULT; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err_copy; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_pd_read(pd); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_lock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	list_add_tail(&uobj->list, &file->ucontext->mr_list); | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-09-27 15:07:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	uobj->live = 1; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	up_write(&uobj->mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return in_len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | err_copy: | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	idr_remove_uobj(&ib_uverbs_mr_idr, uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | err_unreg: | 
					
						
							|  |  |  | 	ib_dereg_mr(mr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | err_put: | 
					
						
							|  |  |  | 	put_pd_read(pd); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | err_free: | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	put_uobj_write(uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			   const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			   int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_dereg_mr cmd; | 
					
						
							|  |  |  | 	struct ib_mr             *mr; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	struct ib_uobject	 *uobj; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	int                       ret = -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	uobj = idr_write_uobj(&ib_uverbs_mr_idr, cmd.mr_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!uobj) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-04 16:15:11 -08:00
										 |  |  | 	mr = uobj->object; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ret = ib_dereg_mr(mr); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		uobj->live = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	put_uobj_write(uobj); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	if (ret) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		return ret; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	idr_remove_uobj(&ib_uverbs_mr_idr, uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_lock(&file->mutex); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	list_del(&uobj->list); | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_uobj(uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	return in_len; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 				      const char __user *buf, int in_len, | 
					
						
							|  |  |  | 				      int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_create_comp_channel	   cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_create_comp_channel_resp  resp; | 
					
						
							|  |  |  | 	struct file				  *filp; | 
					
						
							| 
									
										
										
										
											2010-01-18 01:38:00 -05:00
										 |  |  | 	int ret; | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (out_len < sizeof resp) | 
					
						
							|  |  |  | 		return -ENOSPC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 01:38:00 -05:00
										 |  |  | 	ret = get_unused_fd(); | 
					
						
							|  |  |  | 	if (ret < 0) | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	resp.fd = ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	filp = ib_uverbs_alloc_event_file(file, 0); | 
					
						
							|  |  |  | 	if (IS_ERR(filp)) { | 
					
						
							|  |  |  | 		put_unused_fd(resp.fd); | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 		return PTR_ERR(filp); | 
					
						
							| 
									
										
										
										
											2010-01-18 01:38:00 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) { | 
					
						
							|  |  |  | 		put_unused_fd(resp.fd); | 
					
						
							|  |  |  | 		fput(filp); | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fd_install(resp.fd, filp); | 
					
						
							|  |  |  | 	return in_len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			    const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			    int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_create_cq      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_create_cq_resp resp; | 
					
						
							|  |  |  | 	struct ib_udata                 udata; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	struct ib_ucq_object           *obj; | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 	struct ib_uverbs_event_file    *ev_file = NULL; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	struct ib_cq                   *cq; | 
					
						
							|  |  |  | 	int                             ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (out_len < sizeof resp) | 
					
						
							|  |  |  | 		return -ENOSPC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	INIT_UDATA(&udata, buf + sizeof cmd, | 
					
						
							|  |  |  | 		   (unsigned long) cmd.response + sizeof resp, | 
					
						
							|  |  |  | 		   in_len - sizeof cmd, out_len - sizeof resp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 	if (cmd.comp_vector >= file->device->num_comp_vectors) | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj = kmalloc(sizeof *obj, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!obj) | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 		return -ENOMEM; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 15:16:04 -07:00
										 |  |  | 	init_uobj(&obj->uobject, cmd.user_handle, file->ucontext, &cq_lock_key); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	down_write(&obj->uobject.mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-06 16:43:14 -08:00
										 |  |  | 	if (cmd.comp_channel >= 0) { | 
					
						
							|  |  |  | 		ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel); | 
					
						
							|  |  |  | 		if (!ev_file) { | 
					
						
							|  |  |  | 			ret = -EINVAL; | 
					
						
							|  |  |  | 			goto err; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj->uverbs_file	   = file; | 
					
						
							|  |  |  | 	obj->comp_events_reported  = 0; | 
					
						
							|  |  |  | 	obj->async_events_reported = 0; | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&obj->comp_list); | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&obj->async_list); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	cq = file->device->ib_dev->create_cq(file->device->ib_dev, cmd.cqe, | 
					
						
							| 
									
										
										
										
											2007-05-03 13:48:47 +03:00
										 |  |  | 					     cmd.comp_vector, | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 					     file->ucontext, &udata); | 
					
						
							|  |  |  | 	if (IS_ERR(cq)) { | 
					
						
							|  |  |  | 		ret = PTR_ERR(cq); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err_file; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cq->device        = file->device->ib_dev; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	cq->uobject       = &obj->uobject; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	cq->comp_handler  = ib_uverbs_comp_handler; | 
					
						
							|  |  |  | 	cq->event_handler = ib_uverbs_cq_event_handler; | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 	cq->cq_context    = ev_file; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	atomic_set(&cq->usecnt, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj->uobject.object = cq; | 
					
						
							|  |  |  | 	ret = idr_add_uobj(&ib_uverbs_cq_idr, &obj->uobject); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	if (ret) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err_free; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	memset(&resp, 0, sizeof resp); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	resp.cq_handle = obj->uobject.id; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	resp.cqe       = cq->cqe; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) { | 
					
						
							|  |  |  | 		ret = -EFAULT; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err_copy; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_lock(&file->mutex); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	list_add_tail(&obj->uobject.list, &file->ucontext->cq_list); | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj->uobject.live = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	up_write(&obj->uobject.mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-27 15:07:25 -07:00
										 |  |  | 	return in_len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | err_copy: | 
					
						
							|  |  |  | 	idr_remove_uobj(&ib_uverbs_cq_idr, &obj->uobject); | 
					
						
							| 
									
										
										
										
											2005-09-27 15:07:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | err_free: | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	ib_destroy_cq(cq); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | err_file: | 
					
						
							| 
									
										
										
										
											2006-01-06 16:43:14 -08:00
										 |  |  | 	if (ev_file) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		ib_uverbs_release_ucq(file, ev_file, obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | err: | 
					
						
							|  |  |  | 	put_uobj_write(&obj->uobject); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-30 14:29:21 -08:00
										 |  |  | ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			    const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			    int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_resize_cq	cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_resize_cq_resp	resp; | 
					
						
							|  |  |  | 	struct ib_udata                 udata; | 
					
						
							|  |  |  | 	struct ib_cq			*cq; | 
					
						
							|  |  |  | 	int				ret = -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	INIT_UDATA(&udata, buf + sizeof cmd, | 
					
						
							|  |  |  | 		   (unsigned long) cmd.response + sizeof resp, | 
					
						
							|  |  |  | 		   in_len - sizeof cmd, out_len - sizeof resp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | 	cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	if (!cq) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							| 
									
										
										
										
											2006-01-30 14:29:21 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ret = cq->device->resize_cq(cq, cmd.cqe, &udata); | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							|  |  |  | 		goto out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp.cqe = cq->cqe; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							| 
									
										
										
										
											2006-09-22 15:22:24 -07:00
										 |  |  | 			 &resp, sizeof resp.cqe)) | 
					
						
							| 
									
										
										
										
											2006-01-30 14:29:21 -08:00
										 |  |  | 		ret = -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | out: | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_cq_read(cq); | 
					
						
							| 
									
										
										
										
											2006-01-30 14:29:21 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return ret ? ret : in_len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			  const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			  int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_poll_cq       cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_poll_cq_resp *resp; | 
					
						
							|  |  |  | 	struct ib_cq                  *cq; | 
					
						
							|  |  |  | 	struct ib_wc                  *wc; | 
					
						
							|  |  |  | 	int                            ret = 0; | 
					
						
							|  |  |  | 	int                            i; | 
					
						
							|  |  |  | 	int                            rsize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!wc) | 
					
						
							|  |  |  | 		return -ENOMEM; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc); | 
					
						
							|  |  |  | 	resp = kmalloc(rsize, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!resp) { | 
					
						
							|  |  |  | 		ret = -ENOMEM; | 
					
						
							|  |  |  | 		goto out_wc; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | 	cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0); | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:19 -07:00
										 |  |  | 	if (!cq) { | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 		ret = -EINVAL; | 
					
						
							|  |  |  | 		goto out; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp->count = ib_poll_cq(cq, cmd.ne, wc); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:19 -07:00
										 |  |  | 	put_cq_read(cq); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	for (i = 0; i < resp->count; i++) { | 
					
						
							|  |  |  | 		resp->wc[i].wr_id 	   = wc[i].wr_id; | 
					
						
							|  |  |  | 		resp->wc[i].status 	   = wc[i].status; | 
					
						
							|  |  |  | 		resp->wc[i].opcode 	   = wc[i].opcode; | 
					
						
							|  |  |  | 		resp->wc[i].vendor_err 	   = wc[i].vendor_err; | 
					
						
							|  |  |  | 		resp->wc[i].byte_len 	   = wc[i].byte_len; | 
					
						
							| 
									
										
										
										
											2008-07-14 23:48:45 -07:00
										 |  |  | 		resp->wc[i].ex.imm_data    = (__u32 __force) wc[i].ex.imm_data; | 
					
						
							| 
									
										
										
										
											2006-12-31 21:09:42 +02:00
										 |  |  | 		resp->wc[i].qp_num 	   = wc[i].qp->qp_num; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 		resp->wc[i].src_qp 	   = wc[i].src_qp; | 
					
						
							|  |  |  | 		resp->wc[i].wc_flags 	   = wc[i].wc_flags; | 
					
						
							|  |  |  | 		resp->wc[i].pkey_index 	   = wc[i].pkey_index; | 
					
						
							|  |  |  | 		resp->wc[i].slid 	   = wc[i].slid; | 
					
						
							|  |  |  | 		resp->wc[i].sl 		   = wc[i].sl; | 
					
						
							|  |  |  | 		resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits; | 
					
						
							|  |  |  | 		resp->wc[i].port_num 	   = wc[i].port_num; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize)) | 
					
						
							|  |  |  | 		ret = -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | out: | 
					
						
							|  |  |  | 	kfree(resp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | out_wc: | 
					
						
							|  |  |  | 	kfree(wc); | 
					
						
							|  |  |  | 	return ret ? ret : in_len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 				const char __user *buf, int in_len, | 
					
						
							|  |  |  | 				int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_req_notify_cq cmd; | 
					
						
							|  |  |  | 	struct ib_cq                  *cq; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | 	cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0); | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:19 -07:00
										 |  |  | 	if (!cq) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		return -EINVAL; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	ib_req_notify_cq(cq, cmd.solicited_only ? | 
					
						
							|  |  |  | 			 IB_CQ_SOLICITED : IB_CQ_NEXT_COMP); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:19 -07:00
										 |  |  | 	put_cq_read(cq); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return in_len; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			     const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			     int out_len) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 	struct ib_uverbs_destroy_cq      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_destroy_cq_resp resp; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	struct ib_uobject		*uobj; | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 	struct ib_cq               	*cq; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	struct ib_ucq_object        	*obj; | 
					
						
							| 
									
										
										
										
											2005-09-26 13:53:25 -07:00
										 |  |  | 	struct ib_uverbs_event_file	*ev_file; | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 	int                        	 ret = -EINVAL; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	uobj = idr_write_uobj(&ib_uverbs_cq_idr, cmd.cq_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!uobj) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 	cq      = uobj->object; | 
					
						
							|  |  |  | 	ev_file = cq->cq_context; | 
					
						
							|  |  |  | 	obj     = container_of(cq->uobject, struct ib_ucq_object, uobject); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	ret = ib_destroy_cq(cq); | 
					
						
							|  |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		uobj->live = 0; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_uobj_write(uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		return ret; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	idr_remove_uobj(&ib_uverbs_cq_idr, uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_lock(&file->mutex); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	list_del(&uobj->list); | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	ib_uverbs_release_ucq(file, ev_file, obj); | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	memset(&resp, 0, sizeof resp); | 
					
						
							|  |  |  | 	resp.comp_events_reported  = obj->comp_events_reported; | 
					
						
							|  |  |  | 	resp.async_events_reported = obj->async_events_reported; | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_uobj(uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		return -EFAULT; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	return in_len; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			    const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			    int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_create_qp      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_create_qp_resp resp; | 
					
						
							|  |  |  | 	struct ib_udata                 udata; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	struct ib_uqp_object           *obj; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	struct ib_pd                   *pd; | 
					
						
							|  |  |  | 	struct ib_cq                   *scq, *rcq; | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 	struct ib_srq                  *srq; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	struct ib_qp                   *qp; | 
					
						
							|  |  |  | 	struct ib_qp_init_attr          attr; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (out_len < sizeof resp) | 
					
						
							|  |  |  | 		return -ENOSPC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	INIT_UDATA(&udata, buf + sizeof cmd, | 
					
						
							|  |  |  | 		   (unsigned long) cmd.response + sizeof resp, | 
					
						
							|  |  |  | 		   in_len - sizeof cmd, out_len - sizeof resp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj = kmalloc(sizeof *obj, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!obj) | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 		return -ENOMEM; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 15:16:04 -07:00
										 |  |  | 	init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_key); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	down_write(&obj->uevent.uobject.mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 15:16:04 -07:00
										 |  |  | 	srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	pd  = idr_read_pd(cmd.pd_handle, file->ucontext); | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | 	scq = idr_read_cq(cmd.send_cq_handle, file->ucontext, 0); | 
					
						
							| 
									
										
										
										
											2006-07-23 15:16:04 -07:00
										 |  |  | 	rcq = cmd.recv_cq_handle == cmd.send_cq_handle ? | 
					
						
							| 
									
										
										
										
											2006-09-22 15:17:20 -07:00
										 |  |  | 		scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext, 1); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) { | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 		ret = -EINVAL; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err_put; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	attr.event_handler = ib_uverbs_qp_event_handler; | 
					
						
							|  |  |  | 	attr.qp_context    = file; | 
					
						
							|  |  |  | 	attr.send_cq       = scq; | 
					
						
							|  |  |  | 	attr.recv_cq       = rcq; | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 	attr.srq           = srq; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	attr.sq_sig_type   = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR; | 
					
						
							|  |  |  | 	attr.qp_type       = cmd.qp_type; | 
					
						
							| 
									
										
										
										
											2008-04-16 21:09:27 -07:00
										 |  |  | 	attr.create_flags  = 0; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	attr.cap.max_send_wr     = cmd.max_send_wr; | 
					
						
							|  |  |  | 	attr.cap.max_recv_wr     = cmd.max_recv_wr; | 
					
						
							|  |  |  | 	attr.cap.max_send_sge    = cmd.max_send_sge; | 
					
						
							|  |  |  | 	attr.cap.max_recv_sge    = cmd.max_recv_sge; | 
					
						
							|  |  |  | 	attr.cap.max_inline_data = cmd.max_inline_data; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj->uevent.events_reported     = 0; | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&obj->uevent.event_list); | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&obj->mcast_list); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	qp = pd->device->create_qp(pd, &attr, &udata); | 
					
						
							|  |  |  | 	if (IS_ERR(qp)) { | 
					
						
							|  |  |  | 		ret = PTR_ERR(qp); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err_put; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	qp->device     	  = pd->device; | 
					
						
							|  |  |  | 	qp->pd         	  = pd; | 
					
						
							|  |  |  | 	qp->send_cq    	  = attr.send_cq; | 
					
						
							|  |  |  | 	qp->recv_cq    	  = attr.recv_cq; | 
					
						
							|  |  |  | 	qp->srq	       	  = attr.srq; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	qp->uobject       = &obj->uevent.uobject; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	qp->event_handler = attr.event_handler; | 
					
						
							|  |  |  | 	qp->qp_context    = attr.qp_context; | 
					
						
							|  |  |  | 	qp->qp_type	  = attr.qp_type; | 
					
						
							|  |  |  | 	atomic_inc(&pd->usecnt); | 
					
						
							|  |  |  | 	atomic_inc(&attr.send_cq->usecnt); | 
					
						
							|  |  |  | 	atomic_inc(&attr.recv_cq->usecnt); | 
					
						
							|  |  |  | 	if (attr.srq) | 
					
						
							|  |  |  | 		atomic_inc(&attr.srq->usecnt); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj->uevent.uobject.object = qp; | 
					
						
							|  |  |  | 	ret = idr_add_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	if (ret) | 
					
						
							|  |  |  | 		goto err_destroy; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	memset(&resp, 0, sizeof resp); | 
					
						
							|  |  |  | 	resp.qpn             = qp->qp_num; | 
					
						
							|  |  |  | 	resp.qp_handle       = obj->uevent.uobject.id; | 
					
						
							| 
									
										
										
										
											2005-11-09 11:26:07 -08:00
										 |  |  | 	resp.max_recv_sge    = attr.cap.max_recv_sge; | 
					
						
							|  |  |  | 	resp.max_send_sge    = attr.cap.max_send_sge; | 
					
						
							|  |  |  | 	resp.max_recv_wr     = attr.cap.max_recv_wr; | 
					
						
							|  |  |  | 	resp.max_send_wr     = attr.cap.max_send_wr; | 
					
						
							|  |  |  | 	resp.max_inline_data = attr.cap.max_inline_data; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) { | 
					
						
							|  |  |  | 		ret = -EFAULT; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err_copy; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_pd_read(pd); | 
					
						
							|  |  |  | 	put_cq_read(scq); | 
					
						
							| 
									
										
										
										
											2006-07-23 15:16:04 -07:00
										 |  |  | 	if (rcq != scq) | 
					
						
							|  |  |  | 		put_cq_read(rcq); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	if (srq) | 
					
						
							|  |  |  | 		put_srq_read(srq); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_lock(&file->mutex); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	list_add_tail(&obj->uevent.uobject.list, &file->ucontext->qp_list); | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-09-27 15:07:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj->uevent.uobject.live = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	up_write(&obj->uevent.uobject.mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return in_len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | err_copy: | 
					
						
							|  |  |  | 	idr_remove_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | err_destroy: | 
					
						
							|  |  |  | 	ib_destroy_qp(qp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | err_put: | 
					
						
							|  |  |  | 	if (pd) | 
					
						
							|  |  |  | 		put_pd_read(pd); | 
					
						
							|  |  |  | 	if (scq) | 
					
						
							|  |  |  | 		put_cq_read(scq); | 
					
						
							| 
									
										
										
										
											2006-07-23 15:16:04 -07:00
										 |  |  | 	if (rcq && rcq != scq) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		put_cq_read(rcq); | 
					
						
							|  |  |  | 	if (srq) | 
					
						
							|  |  |  | 		put_srq_read(srq); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	put_uobj_write(&obj->uevent.uobject); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:25 -08:00
										 |  |  | ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			   const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			   int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_query_qp      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_query_qp_resp resp; | 
					
						
							|  |  |  | 	struct ib_qp                   *qp; | 
					
						
							|  |  |  | 	struct ib_qp_attr              *attr; | 
					
						
							|  |  |  | 	struct ib_qp_init_attr         *init_attr; | 
					
						
							|  |  |  | 	int                            ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	attr      = kmalloc(sizeof *attr, GFP_KERNEL); | 
					
						
							|  |  |  | 	init_attr = kmalloc(sizeof *init_attr, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!attr || !init_attr) { | 
					
						
							|  |  |  | 		ret = -ENOMEM; | 
					
						
							|  |  |  | 		goto out; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	qp = idr_read_qp(cmd.qp_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!qp) { | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:25 -08:00
										 |  |  | 		ret = -EINVAL; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto out; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = ib_query_qp(qp, attr, cmd.attr_mask, init_attr); | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:25 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_qp_read(qp); | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:25 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							|  |  |  | 		goto out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memset(&resp, 0, sizeof resp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp.qp_state               = attr->qp_state; | 
					
						
							|  |  |  | 	resp.cur_qp_state           = attr->cur_qp_state; | 
					
						
							|  |  |  | 	resp.path_mtu               = attr->path_mtu; | 
					
						
							|  |  |  | 	resp.path_mig_state         = attr->path_mig_state; | 
					
						
							|  |  |  | 	resp.qkey                   = attr->qkey; | 
					
						
							|  |  |  | 	resp.rq_psn                 = attr->rq_psn; | 
					
						
							|  |  |  | 	resp.sq_psn                 = attr->sq_psn; | 
					
						
							|  |  |  | 	resp.dest_qp_num            = attr->dest_qp_num; | 
					
						
							|  |  |  | 	resp.qp_access_flags        = attr->qp_access_flags; | 
					
						
							|  |  |  | 	resp.pkey_index             = attr->pkey_index; | 
					
						
							|  |  |  | 	resp.alt_pkey_index         = attr->alt_pkey_index; | 
					
						
							| 
									
										
										
										
											2006-10-25 12:54:20 +02:00
										 |  |  | 	resp.sq_draining            = attr->sq_draining; | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:25 -08:00
										 |  |  | 	resp.max_rd_atomic          = attr->max_rd_atomic; | 
					
						
							|  |  |  | 	resp.max_dest_rd_atomic     = attr->max_dest_rd_atomic; | 
					
						
							|  |  |  | 	resp.min_rnr_timer          = attr->min_rnr_timer; | 
					
						
							|  |  |  | 	resp.port_num               = attr->port_num; | 
					
						
							|  |  |  | 	resp.timeout                = attr->timeout; | 
					
						
							|  |  |  | 	resp.retry_cnt              = attr->retry_cnt; | 
					
						
							|  |  |  | 	resp.rnr_retry              = attr->rnr_retry; | 
					
						
							|  |  |  | 	resp.alt_port_num           = attr->alt_port_num; | 
					
						
							|  |  |  | 	resp.alt_timeout            = attr->alt_timeout; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memcpy(resp.dest.dgid, attr->ah_attr.grh.dgid.raw, 16); | 
					
						
							|  |  |  | 	resp.dest.flow_label        = attr->ah_attr.grh.flow_label; | 
					
						
							|  |  |  | 	resp.dest.sgid_index        = attr->ah_attr.grh.sgid_index; | 
					
						
							|  |  |  | 	resp.dest.hop_limit         = attr->ah_attr.grh.hop_limit; | 
					
						
							|  |  |  | 	resp.dest.traffic_class     = attr->ah_attr.grh.traffic_class; | 
					
						
							|  |  |  | 	resp.dest.dlid              = attr->ah_attr.dlid; | 
					
						
							|  |  |  | 	resp.dest.sl                = attr->ah_attr.sl; | 
					
						
							|  |  |  | 	resp.dest.src_path_bits     = attr->ah_attr.src_path_bits; | 
					
						
							|  |  |  | 	resp.dest.static_rate       = attr->ah_attr.static_rate; | 
					
						
							|  |  |  | 	resp.dest.is_global         = !!(attr->ah_attr.ah_flags & IB_AH_GRH); | 
					
						
							|  |  |  | 	resp.dest.port_num          = attr->ah_attr.port_num; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memcpy(resp.alt_dest.dgid, attr->alt_ah_attr.grh.dgid.raw, 16); | 
					
						
							|  |  |  | 	resp.alt_dest.flow_label    = attr->alt_ah_attr.grh.flow_label; | 
					
						
							|  |  |  | 	resp.alt_dest.sgid_index    = attr->alt_ah_attr.grh.sgid_index; | 
					
						
							|  |  |  | 	resp.alt_dest.hop_limit     = attr->alt_ah_attr.grh.hop_limit; | 
					
						
							|  |  |  | 	resp.alt_dest.traffic_class = attr->alt_ah_attr.grh.traffic_class; | 
					
						
							|  |  |  | 	resp.alt_dest.dlid          = attr->alt_ah_attr.dlid; | 
					
						
							|  |  |  | 	resp.alt_dest.sl            = attr->alt_ah_attr.sl; | 
					
						
							|  |  |  | 	resp.alt_dest.src_path_bits = attr->alt_ah_attr.src_path_bits; | 
					
						
							|  |  |  | 	resp.alt_dest.static_rate   = attr->alt_ah_attr.static_rate; | 
					
						
							|  |  |  | 	resp.alt_dest.is_global     = !!(attr->alt_ah_attr.ah_flags & IB_AH_GRH); | 
					
						
							|  |  |  | 	resp.alt_dest.port_num      = attr->alt_ah_attr.port_num; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp.max_send_wr            = init_attr->cap.max_send_wr; | 
					
						
							|  |  |  | 	resp.max_recv_wr            = init_attr->cap.max_recv_wr; | 
					
						
							|  |  |  | 	resp.max_send_sge           = init_attr->cap.max_send_sge; | 
					
						
							|  |  |  | 	resp.max_recv_sge           = init_attr->cap.max_recv_sge; | 
					
						
							|  |  |  | 	resp.max_inline_data        = init_attr->cap.max_inline_data; | 
					
						
							| 
									
										
										
										
											2006-03-02 11:25:27 -08:00
										 |  |  | 	resp.sq_sig_all             = init_attr->sq_sig_type == IB_SIGNAL_ALL_WR; | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:25 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) | 
					
						
							|  |  |  | 		ret = -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | out: | 
					
						
							|  |  |  | 	kfree(attr); | 
					
						
							|  |  |  | 	kfree(init_attr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret ? ret : in_len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			    const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			    int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_modify_qp cmd; | 
					
						
							| 
									
										
										
										
											2006-08-11 14:58:09 -07:00
										 |  |  | 	struct ib_udata            udata; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	struct ib_qp              *qp; | 
					
						
							|  |  |  | 	struct ib_qp_attr         *attr; | 
					
						
							|  |  |  | 	int                        ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-11 14:58:09 -07:00
										 |  |  | 	INIT_UDATA(&udata, buf + sizeof cmd, NULL, in_len - sizeof cmd, | 
					
						
							|  |  |  | 		   out_len); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	attr = kmalloc(sizeof *attr, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!attr) | 
					
						
							|  |  |  | 		return -ENOMEM; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	qp = idr_read_qp(cmd.qp_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!qp) { | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 		ret = -EINVAL; | 
					
						
							|  |  |  | 		goto out; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	attr->qp_state 		  = cmd.qp_state; | 
					
						
							|  |  |  | 	attr->cur_qp_state 	  = cmd.cur_qp_state; | 
					
						
							|  |  |  | 	attr->path_mtu 		  = cmd.path_mtu; | 
					
						
							|  |  |  | 	attr->path_mig_state 	  = cmd.path_mig_state; | 
					
						
							|  |  |  | 	attr->qkey 		  = cmd.qkey; | 
					
						
							|  |  |  | 	attr->rq_psn 		  = cmd.rq_psn; | 
					
						
							|  |  |  | 	attr->sq_psn 		  = cmd.sq_psn; | 
					
						
							|  |  |  | 	attr->dest_qp_num 	  = cmd.dest_qp_num; | 
					
						
							|  |  |  | 	attr->qp_access_flags 	  = cmd.qp_access_flags; | 
					
						
							|  |  |  | 	attr->pkey_index 	  = cmd.pkey_index; | 
					
						
							| 
									
										
										
										
											2006-03-20 10:08:24 -08:00
										 |  |  | 	attr->alt_pkey_index 	  = cmd.alt_pkey_index; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	attr->en_sqd_async_notify = cmd.en_sqd_async_notify; | 
					
						
							|  |  |  | 	attr->max_rd_atomic 	  = cmd.max_rd_atomic; | 
					
						
							|  |  |  | 	attr->max_dest_rd_atomic  = cmd.max_dest_rd_atomic; | 
					
						
							|  |  |  | 	attr->min_rnr_timer 	  = cmd.min_rnr_timer; | 
					
						
							|  |  |  | 	attr->port_num 		  = cmd.port_num; | 
					
						
							|  |  |  | 	attr->timeout 		  = cmd.timeout; | 
					
						
							|  |  |  | 	attr->retry_cnt 	  = cmd.retry_cnt; | 
					
						
							|  |  |  | 	attr->rnr_retry 	  = cmd.rnr_retry; | 
					
						
							|  |  |  | 	attr->alt_port_num 	  = cmd.alt_port_num; | 
					
						
							|  |  |  | 	attr->alt_timeout 	  = cmd.alt_timeout; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memcpy(attr->ah_attr.grh.dgid.raw, cmd.dest.dgid, 16); | 
					
						
							|  |  |  | 	attr->ah_attr.grh.flow_label        = cmd.dest.flow_label; | 
					
						
							|  |  |  | 	attr->ah_attr.grh.sgid_index        = cmd.dest.sgid_index; | 
					
						
							|  |  |  | 	attr->ah_attr.grh.hop_limit         = cmd.dest.hop_limit; | 
					
						
							|  |  |  | 	attr->ah_attr.grh.traffic_class     = cmd.dest.traffic_class; | 
					
						
							|  |  |  | 	attr->ah_attr.dlid 	    	    = cmd.dest.dlid; | 
					
						
							|  |  |  | 	attr->ah_attr.sl   	    	    = cmd.dest.sl; | 
					
						
							|  |  |  | 	attr->ah_attr.src_path_bits 	    = cmd.dest.src_path_bits; | 
					
						
							|  |  |  | 	attr->ah_attr.static_rate   	    = cmd.dest.static_rate; | 
					
						
							|  |  |  | 	attr->ah_attr.ah_flags 	    	    = cmd.dest.is_global ? IB_AH_GRH : 0; | 
					
						
							|  |  |  | 	attr->ah_attr.port_num 	    	    = cmd.dest.port_num; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memcpy(attr->alt_ah_attr.grh.dgid.raw, cmd.alt_dest.dgid, 16); | 
					
						
							|  |  |  | 	attr->alt_ah_attr.grh.flow_label    = cmd.alt_dest.flow_label; | 
					
						
							|  |  |  | 	attr->alt_ah_attr.grh.sgid_index    = cmd.alt_dest.sgid_index; | 
					
						
							|  |  |  | 	attr->alt_ah_attr.grh.hop_limit     = cmd.alt_dest.hop_limit; | 
					
						
							|  |  |  | 	attr->alt_ah_attr.grh.traffic_class = cmd.alt_dest.traffic_class; | 
					
						
							|  |  |  | 	attr->alt_ah_attr.dlid 	    	    = cmd.alt_dest.dlid; | 
					
						
							|  |  |  | 	attr->alt_ah_attr.sl   	    	    = cmd.alt_dest.sl; | 
					
						
							|  |  |  | 	attr->alt_ah_attr.src_path_bits     = cmd.alt_dest.src_path_bits; | 
					
						
							|  |  |  | 	attr->alt_ah_attr.static_rate       = cmd.alt_dest.static_rate; | 
					
						
							|  |  |  | 	attr->alt_ah_attr.ah_flags 	    = cmd.alt_dest.is_global ? IB_AH_GRH : 0; | 
					
						
							|  |  |  | 	attr->alt_ah_attr.port_num 	    = cmd.alt_dest.port_num; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-11 14:58:09 -07:00
										 |  |  | 	ret = qp->device->modify_qp(qp, attr, cmd.attr_mask, &udata); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	put_qp_read(qp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	if (ret) | 
					
						
							|  |  |  | 		goto out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = in_len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | out: | 
					
						
							|  |  |  | 	kfree(attr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			     const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			     int out_len) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 	struct ib_uverbs_destroy_qp      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_destroy_qp_resp resp; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	struct ib_uobject		*uobj; | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 	struct ib_qp               	*qp; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	struct ib_uqp_object        	*obj; | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 	int                        	 ret = -EINVAL; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 	memset(&resp, 0, sizeof resp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	uobj = idr_write_uobj(&ib_uverbs_qp_idr, cmd.qp_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!uobj) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 	qp  = uobj->object; | 
					
						
							|  |  |  | 	obj = container_of(uobj, struct ib_uqp_object, uevent.uobject); | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	if (!list_empty(&obj->mcast_list)) { | 
					
						
							|  |  |  | 		put_uobj_write(uobj); | 
					
						
							|  |  |  | 		return -EBUSY; | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ret = ib_destroy_qp(qp); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		uobj->live = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	put_uobj_write(uobj); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	if (ret) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		return ret; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	idr_remove_uobj(&ib_uverbs_qp_idr, uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_lock(&file->mutex); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	list_del(&uobj->list); | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	ib_uverbs_release_uevent(file, &obj->uevent); | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	resp.events_reported = obj->uevent.events_reported; | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_uobj(uobj); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		return -EFAULT; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	return in_len; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, | 
					
						
							| 
									
										
										
										
											2006-02-13 16:30:49 -08:00
										 |  |  | 			    const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			    int out_len) | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_post_send      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_post_send_resp resp; | 
					
						
							|  |  |  | 	struct ib_uverbs_send_wr       *user_wr; | 
					
						
							|  |  |  | 	struct ib_send_wr              *wr = NULL, *last, *next, *bad_wr; | 
					
						
							|  |  |  | 	struct ib_qp                   *qp; | 
					
						
							|  |  |  | 	int                             i, sg_ind; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	int				is_ud; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	ssize_t                         ret = -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (in_len < sizeof cmd + cmd.wqe_size * cmd.wr_count + | 
					
						
							|  |  |  | 	    cmd.sge_count * sizeof (struct ib_uverbs_sge)) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (cmd.wqe_size < sizeof (struct ib_uverbs_send_wr)) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	user_wr = kmalloc(cmd.wqe_size, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!user_wr) | 
					
						
							|  |  |  | 		return -ENOMEM; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	qp = idr_read_qp(cmd.qp_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!qp) | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 		goto out; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	is_ud = qp->qp_type == IB_QPT_UD; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	sg_ind = 0; | 
					
						
							|  |  |  | 	last = NULL; | 
					
						
							|  |  |  | 	for (i = 0; i < cmd.wr_count; ++i) { | 
					
						
							|  |  |  | 		if (copy_from_user(user_wr, | 
					
						
							|  |  |  | 				   buf + sizeof cmd + i * cmd.wqe_size, | 
					
						
							|  |  |  | 				   cmd.wqe_size)) { | 
					
						
							|  |  |  | 			ret = -EFAULT; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 			goto out_put; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (user_wr->num_sge + sg_ind > cmd.sge_count) { | 
					
						
							|  |  |  | 			ret = -EINVAL; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 			goto out_put; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) + | 
					
						
							|  |  |  | 			       user_wr->num_sge * sizeof (struct ib_sge), | 
					
						
							|  |  |  | 			       GFP_KERNEL); | 
					
						
							|  |  |  | 		if (!next) { | 
					
						
							|  |  |  | 			ret = -ENOMEM; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 			goto out_put; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!last) | 
					
						
							|  |  |  | 			wr = next; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			last->next = next; | 
					
						
							|  |  |  | 		last = next; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		next->next       = NULL; | 
					
						
							|  |  |  | 		next->wr_id      = user_wr->wr_id; | 
					
						
							|  |  |  | 		next->num_sge    = user_wr->num_sge; | 
					
						
							|  |  |  | 		next->opcode     = user_wr->opcode; | 
					
						
							|  |  |  | 		next->send_flags = user_wr->send_flags; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		if (is_ud) { | 
					
						
							|  |  |  | 			next->wr.ud.ah = idr_read_ah(user_wr->wr.ud.ah, | 
					
						
							|  |  |  | 						     file->ucontext); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 			if (!next->wr.ud.ah) { | 
					
						
							|  |  |  | 				ret = -EINVAL; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 				goto out_put; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			next->wr.ud.remote_qpn  = user_wr->wr.ud.remote_qpn; | 
					
						
							|  |  |  | 			next->wr.ud.remote_qkey = user_wr->wr.ud.remote_qkey; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			switch (next->opcode) { | 
					
						
							|  |  |  | 			case IB_WR_RDMA_WRITE_WITH_IMM: | 
					
						
							| 
									
										
										
										
											2008-04-16 21:09:32 -07:00
										 |  |  | 				next->ex.imm_data = | 
					
						
							|  |  |  | 					(__be32 __force) user_wr->ex.imm_data; | 
					
						
							|  |  |  | 			case IB_WR_RDMA_WRITE: | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 			case IB_WR_RDMA_READ: | 
					
						
							|  |  |  | 				next->wr.rdma.remote_addr = | 
					
						
							|  |  |  | 					user_wr->wr.rdma.remote_addr; | 
					
						
							|  |  |  | 				next->wr.rdma.rkey        = | 
					
						
							|  |  |  | 					user_wr->wr.rdma.rkey; | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2008-04-16 21:09:32 -07:00
										 |  |  | 			case IB_WR_SEND_WITH_IMM: | 
					
						
							|  |  |  | 				next->ex.imm_data = | 
					
						
							|  |  |  | 					(__be32 __force) user_wr->ex.imm_data; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case IB_WR_SEND_WITH_INV: | 
					
						
							|  |  |  | 				next->ex.invalidate_rkey = | 
					
						
							|  |  |  | 					user_wr->ex.invalidate_rkey; | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 			case IB_WR_ATOMIC_CMP_AND_SWP: | 
					
						
							|  |  |  | 			case IB_WR_ATOMIC_FETCH_AND_ADD: | 
					
						
							|  |  |  | 				next->wr.atomic.remote_addr = | 
					
						
							|  |  |  | 					user_wr->wr.atomic.remote_addr; | 
					
						
							|  |  |  | 				next->wr.atomic.compare_add = | 
					
						
							|  |  |  | 					user_wr->wr.atomic.compare_add; | 
					
						
							|  |  |  | 				next->wr.atomic.swap = user_wr->wr.atomic.swap; | 
					
						
							|  |  |  | 				next->wr.atomic.rkey = user_wr->wr.atomic.rkey; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (next->num_sge) { | 
					
						
							|  |  |  | 			next->sg_list = (void *) next + | 
					
						
							|  |  |  | 				ALIGN(sizeof *next, sizeof (struct ib_sge)); | 
					
						
							|  |  |  | 			if (copy_from_user(next->sg_list, | 
					
						
							|  |  |  | 					   buf + sizeof cmd + | 
					
						
							|  |  |  | 					   cmd.wr_count * cmd.wqe_size + | 
					
						
							|  |  |  | 					   sg_ind * sizeof (struct ib_sge), | 
					
						
							|  |  |  | 					   next->num_sge * sizeof (struct ib_sge))) { | 
					
						
							|  |  |  | 				ret = -EFAULT; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 				goto out_put; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			sg_ind += next->num_sge; | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 			next->sg_list = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp.bad_wr = 0; | 
					
						
							|  |  |  | 	ret = qp->device->post_send(qp, wr, &bad_wr); | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							|  |  |  | 		for (next = wr; next; next = next->next) { | 
					
						
							|  |  |  | 			++resp.bad_wr; | 
					
						
							|  |  |  | 			if (next == bad_wr) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) | 
					
						
							|  |  |  | 		ret = -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | out_put: | 
					
						
							|  |  |  | 	put_qp_read(qp); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while (wr) { | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		if (is_ud && wr->wr.ud.ah) | 
					
						
							|  |  |  | 			put_ah_read(wr->wr.ud.ah); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 		next = wr->next; | 
					
						
							|  |  |  | 		kfree(wr); | 
					
						
							|  |  |  | 		wr = next; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-22 07:47:27 -07:00
										 |  |  | out: | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	kfree(user_wr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret ? ret : in_len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ib_recv_wr *ib_uverbs_unmarshall_recv(const char __user *buf, | 
					
						
							|  |  |  | 						    int in_len, | 
					
						
							|  |  |  | 						    u32 wr_count, | 
					
						
							|  |  |  | 						    u32 sge_count, | 
					
						
							|  |  |  | 						    u32 wqe_size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_recv_wr *user_wr; | 
					
						
							|  |  |  | 	struct ib_recv_wr        *wr = NULL, *last, *next; | 
					
						
							|  |  |  | 	int                       sg_ind; | 
					
						
							|  |  |  | 	int                       i; | 
					
						
							|  |  |  | 	int                       ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (in_len < wqe_size * wr_count + | 
					
						
							|  |  |  | 	    sge_count * sizeof (struct ib_uverbs_sge)) | 
					
						
							|  |  |  | 		return ERR_PTR(-EINVAL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (wqe_size < sizeof (struct ib_uverbs_recv_wr)) | 
					
						
							|  |  |  | 		return ERR_PTR(-EINVAL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	user_wr = kmalloc(wqe_size, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!user_wr) | 
					
						
							|  |  |  | 		return ERR_PTR(-ENOMEM); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sg_ind = 0; | 
					
						
							|  |  |  | 	last = NULL; | 
					
						
							|  |  |  | 	for (i = 0; i < wr_count; ++i) { | 
					
						
							|  |  |  | 		if (copy_from_user(user_wr, buf + i * wqe_size, | 
					
						
							|  |  |  | 				   wqe_size)) { | 
					
						
							|  |  |  | 			ret = -EFAULT; | 
					
						
							|  |  |  | 			goto err; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (user_wr->num_sge + sg_ind > sge_count) { | 
					
						
							|  |  |  | 			ret = -EINVAL; | 
					
						
							|  |  |  | 			goto err; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) + | 
					
						
							|  |  |  | 			       user_wr->num_sge * sizeof (struct ib_sge), | 
					
						
							|  |  |  | 			       GFP_KERNEL); | 
					
						
							|  |  |  | 		if (!next) { | 
					
						
							|  |  |  | 			ret = -ENOMEM; | 
					
						
							|  |  |  | 			goto err; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!last) | 
					
						
							|  |  |  | 			wr = next; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			last->next = next; | 
					
						
							|  |  |  | 		last = next; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		next->next       = NULL; | 
					
						
							|  |  |  | 		next->wr_id      = user_wr->wr_id; | 
					
						
							|  |  |  | 		next->num_sge    = user_wr->num_sge; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (next->num_sge) { | 
					
						
							|  |  |  | 			next->sg_list = (void *) next + | 
					
						
							|  |  |  | 				ALIGN(sizeof *next, sizeof (struct ib_sge)); | 
					
						
							|  |  |  | 			if (copy_from_user(next->sg_list, | 
					
						
							|  |  |  | 					   buf + wr_count * wqe_size + | 
					
						
							|  |  |  | 					   sg_ind * sizeof (struct ib_sge), | 
					
						
							|  |  |  | 					   next->num_sge * sizeof (struct ib_sge))) { | 
					
						
							|  |  |  | 				ret = -EFAULT; | 
					
						
							|  |  |  | 				goto err; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			sg_ind += next->num_sge; | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 			next->sg_list = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	kfree(user_wr); | 
					
						
							|  |  |  | 	return wr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | err: | 
					
						
							|  |  |  | 	kfree(user_wr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (wr) { | 
					
						
							|  |  |  | 		next = wr->next; | 
					
						
							|  |  |  | 		kfree(wr); | 
					
						
							|  |  |  | 		wr = next; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ERR_PTR(ret); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file, | 
					
						
							| 
									
										
										
										
											2006-02-13 16:30:49 -08:00
										 |  |  | 			    const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			    int out_len) | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_post_recv      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_post_recv_resp resp; | 
					
						
							|  |  |  | 	struct ib_recv_wr              *wr, *next, *bad_wr; | 
					
						
							|  |  |  | 	struct ib_qp                   *qp; | 
					
						
							|  |  |  | 	ssize_t                         ret = -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd, | 
					
						
							|  |  |  | 				       in_len - sizeof cmd, cmd.wr_count, | 
					
						
							|  |  |  | 				       cmd.sge_count, cmd.wqe_size); | 
					
						
							|  |  |  | 	if (IS_ERR(wr)) | 
					
						
							|  |  |  | 		return PTR_ERR(wr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	qp = idr_read_qp(cmd.qp_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!qp) | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 		goto out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp.bad_wr = 0; | 
					
						
							|  |  |  | 	ret = qp->device->post_recv(qp, wr, &bad_wr); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	put_qp_read(qp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	if (ret) | 
					
						
							|  |  |  | 		for (next = wr; next; next = next->next) { | 
					
						
							|  |  |  | 			++resp.bad_wr; | 
					
						
							|  |  |  | 			if (next == bad_wr) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) | 
					
						
							|  |  |  | 		ret = -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | out: | 
					
						
							|  |  |  | 	while (wr) { | 
					
						
							|  |  |  | 		next = wr->next; | 
					
						
							|  |  |  | 		kfree(wr); | 
					
						
							|  |  |  | 		wr = next; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret ? ret : in_len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file, | 
					
						
							| 
									
										
										
										
											2006-02-13 16:30:49 -08:00
										 |  |  | 				const char __user *buf, int in_len, | 
					
						
							|  |  |  | 				int out_len) | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_post_srq_recv      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_post_srq_recv_resp resp; | 
					
						
							|  |  |  | 	struct ib_recv_wr                  *wr, *next, *bad_wr; | 
					
						
							|  |  |  | 	struct ib_srq                      *srq; | 
					
						
							|  |  |  | 	ssize_t                             ret = -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd, | 
					
						
							|  |  |  | 				       in_len - sizeof cmd, cmd.wr_count, | 
					
						
							|  |  |  | 				       cmd.sge_count, cmd.wqe_size); | 
					
						
							|  |  |  | 	if (IS_ERR(wr)) | 
					
						
							|  |  |  | 		return PTR_ERR(wr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	srq = idr_read_srq(cmd.srq_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!srq) | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 		goto out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp.bad_wr = 0; | 
					
						
							|  |  |  | 	ret = srq->device->post_srq_recv(srq, wr, &bad_wr); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	put_srq_read(srq); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	if (ret) | 
					
						
							|  |  |  | 		for (next = wr; next; next = next->next) { | 
					
						
							|  |  |  | 			++resp.bad_wr; | 
					
						
							|  |  |  | 			if (next == bad_wr) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) | 
					
						
							|  |  |  | 		ret = -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | out: | 
					
						
							|  |  |  | 	while (wr) { | 
					
						
							|  |  |  | 		next = wr->next; | 
					
						
							|  |  |  | 		kfree(wr); | 
					
						
							|  |  |  | 		wr = next; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret ? ret : in_len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			    const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			    int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_create_ah	 cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_create_ah_resp	 resp; | 
					
						
							|  |  |  | 	struct ib_uobject		*uobj; | 
					
						
							|  |  |  | 	struct ib_pd			*pd; | 
					
						
							|  |  |  | 	struct ib_ah			*ah; | 
					
						
							|  |  |  | 	struct ib_ah_attr		attr; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (out_len < sizeof resp) | 
					
						
							|  |  |  | 		return -ENOSPC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uobj = kmalloc(sizeof *uobj, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!uobj) | 
					
						
							|  |  |  | 		return -ENOMEM; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 15:16:04 -07:00
										 |  |  | 	init_uobj(uobj, cmd.user_handle, file->ucontext, &ah_lock_key); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	down_write(&uobj->mutex); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	pd = idr_read_pd(cmd.pd_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!pd) { | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 		ret = -EINVAL; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	attr.dlid 	       = cmd.attr.dlid; | 
					
						
							|  |  |  | 	attr.sl 	       = cmd.attr.sl; | 
					
						
							|  |  |  | 	attr.src_path_bits     = cmd.attr.src_path_bits; | 
					
						
							|  |  |  | 	attr.static_rate       = cmd.attr.static_rate; | 
					
						
							| 
									
										
										
										
											2006-01-06 16:24:45 -08:00
										 |  |  | 	attr.ah_flags          = cmd.attr.is_global ? IB_AH_GRH : 0; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	attr.port_num 	       = cmd.attr.port_num; | 
					
						
							|  |  |  | 	attr.grh.flow_label    = cmd.attr.grh.flow_label; | 
					
						
							|  |  |  | 	attr.grh.sgid_index    = cmd.attr.grh.sgid_index; | 
					
						
							|  |  |  | 	attr.grh.hop_limit     = cmd.attr.grh.hop_limit; | 
					
						
							|  |  |  | 	attr.grh.traffic_class = cmd.attr.grh.traffic_class; | 
					
						
							|  |  |  | 	memcpy(attr.grh.dgid.raw, cmd.attr.grh.dgid, 16); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ah = ib_create_ah(pd, &attr); | 
					
						
							|  |  |  | 	if (IS_ERR(ah)) { | 
					
						
							|  |  |  | 		ret = PTR_ERR(ah); | 
					
						
							| 
									
										
										
										
											2006-07-17 18:20:51 +03:00
										 |  |  | 		goto err_put; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	ah->uobject  = uobj; | 
					
						
							|  |  |  | 	uobj->object = ah; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	ret = idr_add_uobj(&ib_uverbs_ah_idr, uobj); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	if (ret) | 
					
						
							|  |  |  | 		goto err_destroy; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp.ah_handle = uobj->id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) { | 
					
						
							|  |  |  | 		ret = -EFAULT; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err_copy; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_pd_read(pd); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_lock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	list_add_tail(&uobj->list, &file->ucontext->ah_list); | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	uobj->live = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	up_write(&uobj->mutex); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return in_len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | err_copy: | 
					
						
							|  |  |  | 	idr_remove_uobj(&ib_uverbs_ah_idr, uobj); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | err_destroy: | 
					
						
							|  |  |  | 	ib_destroy_ah(ah); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-17 18:20:51 +03:00
										 |  |  | err_put: | 
					
						
							|  |  |  | 	put_pd_read(pd); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | err: | 
					
						
							|  |  |  | 	put_uobj_write(uobj); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			     const char __user *buf, int in_len, int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_destroy_ah cmd; | 
					
						
							|  |  |  | 	struct ib_ah		   *ah; | 
					
						
							|  |  |  | 	struct ib_uobject	   *uobj; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	int			    ret; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	uobj = idr_write_uobj(&ib_uverbs_ah_idr, cmd.ah_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!uobj) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 	ah = uobj->object; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	ret = ib_destroy_ah(ah); | 
					
						
							|  |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		uobj->live = 0; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_uobj_write(uobj); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		return ret; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	idr_remove_uobj(&ib_uverbs_ah_idr, uobj); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_lock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 	list_del(&uobj->list); | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_uobj(uobj); | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	return in_len; | 
					
						
							| 
									
										
										
										
											2005-10-14 15:26:04 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			       const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			       int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_attach_mcast cmd; | 
					
						
							|  |  |  | 	struct ib_qp                 *qp; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	struct ib_uqp_object         *obj; | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 	struct ib_uverbs_mcast_entry *mcast; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	int                           ret; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	qp = idr_read_qp(cmd.qp_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!qp) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject); | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	list_for_each_entry(mcast, &obj->mcast_list, list) | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 		if (cmd.mlid == mcast->lid && | 
					
						
							|  |  |  | 		    !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) { | 
					
						
							|  |  |  | 			ret = 0; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 			goto out_put; | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mcast = kmalloc(sizeof *mcast, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!mcast) { | 
					
						
							|  |  |  | 		ret = -ENOMEM; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto out_put; | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mcast->lid = cmd.mlid; | 
					
						
							|  |  |  | 	memcpy(mcast->gid.raw, cmd.gid, sizeof mcast->gid.raw); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 	ret = ib_attach_mcast(qp, &mcast->gid, cmd.mlid); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		list_add_tail(&mcast->list, &obj->mcast_list); | 
					
						
							|  |  |  | 	else | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 		kfree(mcast); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | out_put: | 
					
						
							|  |  |  | 	put_qp_read(qp); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return ret ? ret : in_len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			       const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			       int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_detach_mcast cmd; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	struct ib_uqp_object         *obj; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	struct ib_qp                 *qp; | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 	struct ib_uverbs_mcast_entry *mcast; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 	int                           ret = -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	qp = idr_read_qp(cmd.qp_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!qp) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 	ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid); | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto out_put; | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject); | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	list_for_each_entry(mcast, &obj->mcast_list, list) | 
					
						
							| 
									
										
										
										
											2005-11-29 16:57:01 -08:00
										 |  |  | 		if (cmd.mlid == mcast->lid && | 
					
						
							|  |  |  | 		    !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) { | 
					
						
							|  |  |  | 			list_del(&mcast->list); | 
					
						
							|  |  |  | 			kfree(mcast); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | out_put: | 
					
						
							|  |  |  | 	put_qp_read(qp); | 
					
						
							| 
									
										
										
										
											2005-07-07 17:57:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return ret ? ret : in_len; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			     const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			     int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_create_srq      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_create_srq_resp resp; | 
					
						
							|  |  |  | 	struct ib_udata                  udata; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	struct ib_uevent_object         *obj; | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 	struct ib_pd                    *pd; | 
					
						
							|  |  |  | 	struct ib_srq                   *srq; | 
					
						
							|  |  |  | 	struct ib_srq_init_attr          attr; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (out_len < sizeof resp) | 
					
						
							|  |  |  | 		return -ENOSPC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	INIT_UDATA(&udata, buf + sizeof cmd, | 
					
						
							|  |  |  | 		   (unsigned long) cmd.response + sizeof resp, | 
					
						
							|  |  |  | 		   in_len - sizeof cmd, out_len - sizeof resp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj = kmalloc(sizeof *obj, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!obj) | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 		return -ENOMEM; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-23 15:16:04 -07:00
										 |  |  | 	init_uobj(&obj->uobject, cmd.user_handle, file->ucontext, &srq_lock_key); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	down_write(&obj->uobject.mutex); | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	pd  = idr_read_pd(cmd.pd_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!pd) { | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 		ret = -EINVAL; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err; | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	attr.event_handler  = ib_uverbs_srq_event_handler; | 
					
						
							|  |  |  | 	attr.srq_context    = file; | 
					
						
							|  |  |  | 	attr.attr.max_wr    = cmd.max_wr; | 
					
						
							|  |  |  | 	attr.attr.max_sge   = cmd.max_sge; | 
					
						
							|  |  |  | 	attr.attr.srq_limit = cmd.srq_limit; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj->events_reported     = 0; | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&obj->event_list); | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	srq = pd->device->create_srq(pd, &attr, &udata); | 
					
						
							|  |  |  | 	if (IS_ERR(srq)) { | 
					
						
							|  |  |  | 		ret = PTR_ERR(srq); | 
					
						
							| 
									
										
										
										
											2006-07-17 18:20:51 +03:00
										 |  |  | 		goto err_put; | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	srq->device    	   = pd->device; | 
					
						
							|  |  |  | 	srq->pd        	   = pd; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	srq->uobject       = &obj->uobject; | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 	srq->event_handler = attr.event_handler; | 
					
						
							|  |  |  | 	srq->srq_context   = attr.srq_context; | 
					
						
							|  |  |  | 	atomic_inc(&pd->usecnt); | 
					
						
							|  |  |  | 	atomic_set(&srq->usecnt, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj->uobject.object = srq; | 
					
						
							|  |  |  | 	ret = idr_add_uobj(&ib_uverbs_srq_idr, &obj->uobject); | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 	if (ret) | 
					
						
							|  |  |  | 		goto err_destroy; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	memset(&resp, 0, sizeof resp); | 
					
						
							|  |  |  | 	resp.srq_handle = obj->uobject.id; | 
					
						
							| 
									
										
										
										
											2006-02-23 12:36:18 -08:00
										 |  |  | 	resp.max_wr     = attr.attr.max_wr; | 
					
						
							|  |  |  | 	resp.max_sge    = attr.attr.max_sge; | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) { | 
					
						
							|  |  |  | 		ret = -EFAULT; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		goto err_copy; | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_pd_read(pd); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_lock(&file->mutex); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	list_add_tail(&obj->uobject.list, &file->ucontext->srq_list); | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-09-27 15:07:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	obj->uobject.live = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	up_write(&obj->uobject.mutex); | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return in_len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | err_copy: | 
					
						
							|  |  |  | 	idr_remove_uobj(&ib_uverbs_srq_idr, &obj->uobject); | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | err_destroy: | 
					
						
							|  |  |  | 	ib_destroy_srq(srq); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-17 18:20:51 +03:00
										 |  |  | err_put: | 
					
						
							|  |  |  | 	put_pd_read(pd); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | err: | 
					
						
							|  |  |  | 	put_uobj_write(&obj->uobject); | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			     const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			     int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_modify_srq cmd; | 
					
						
							| 
									
										
										
										
											2006-08-11 14:58:09 -07:00
										 |  |  | 	struct ib_udata             udata; | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 	struct ib_srq              *srq; | 
					
						
							|  |  |  | 	struct ib_srq_attr          attr; | 
					
						
							|  |  |  | 	int                         ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-11 14:58:09 -07:00
										 |  |  | 	INIT_UDATA(&udata, buf + sizeof cmd, NULL, in_len - sizeof cmd, | 
					
						
							|  |  |  | 		   out_len); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	srq = idr_read_srq(cmd.srq_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!srq) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	attr.max_wr    = cmd.max_wr; | 
					
						
							|  |  |  | 	attr.srq_limit = cmd.srq_limit; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-11 14:58:09 -07:00
										 |  |  | 	ret = srq->device->modify_srq(srq, &attr, cmd.attr_mask, &udata); | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_srq_read(srq); | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return ret ? ret : in_len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:57 -08:00
										 |  |  | ssize_t ib_uverbs_query_srq(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			    const char __user *buf, | 
					
						
							|  |  |  | 			    int in_len, int out_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ib_uverbs_query_srq      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_query_srq_resp resp; | 
					
						
							|  |  |  | 	struct ib_srq_attr              attr; | 
					
						
							|  |  |  | 	struct ib_srq                   *srq; | 
					
						
							|  |  |  | 	int                             ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (out_len < sizeof resp) | 
					
						
							|  |  |  | 		return -ENOSPC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	srq = idr_read_srq(cmd.srq_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!srq) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:57 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	ret = ib_query_srq(srq, &attr); | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:57 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_srq_read(srq); | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:57 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		return ret; | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:57 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	memset(&resp, 0, sizeof resp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp.max_wr    = attr.max_wr; | 
					
						
							|  |  |  | 	resp.max_sge   = attr.max_sge; | 
					
						
							|  |  |  | 	resp.srq_limit = attr.srq_limit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		return -EFAULT; | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:57 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	return in_len; | 
					
						
							| 
									
										
										
										
											2006-02-13 16:31:57 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, | 
					
						
							|  |  |  | 			      const char __user *buf, int in_len, | 
					
						
							|  |  |  | 			      int out_len) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 	struct ib_uverbs_destroy_srq      cmd; | 
					
						
							|  |  |  | 	struct ib_uverbs_destroy_srq_resp resp; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	struct ib_uobject		 *uobj; | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 	struct ib_srq               	 *srq; | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	struct ib_uevent_object        	 *obj; | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 	int                         	  ret = -EINVAL; | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_from_user(&cmd, buf, sizeof cmd)) | 
					
						
							|  |  |  | 		return -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	uobj = idr_write_uobj(&ib_uverbs_srq_idr, cmd.srq_handle, file->ucontext); | 
					
						
							|  |  |  | 	if (!uobj) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 	srq = uobj->object; | 
					
						
							|  |  |  | 	obj = container_of(uobj, struct ib_uevent_object, uobject); | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	ret = ib_destroy_srq(srq); | 
					
						
							|  |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		uobj->live = 0; | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_uobj_write(uobj); | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (ret) | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 		return ret; | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	idr_remove_uobj(&ib_uverbs_srq_idr, uobj); | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_lock(&file->mutex); | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	list_del(&uobj->list); | 
					
						
							| 
									
										
										
										
											2006-01-13 14:51:39 -08:00
										 |  |  | 	mutex_unlock(&file->mutex); | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	ib_uverbs_release_uevent(file, obj); | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	memset(&resp, 0, sizeof resp); | 
					
						
							|  |  |  | 	resp.events_reported = obj->events_reported; | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel
are serialized by ib_uverbs_idr_mutex.  This can be a scalability
issue for some workloads, especially for devices driven by the ipath
driver, which needs to call into the kernel even for datapath
operations.
Fix this by adding reference counts to the userspace objects, and then
converting ib_uverbs_idr_mutex into a spinlock that only protects the
idrs long enough to take a reference on the object being looked up.
Because remove operations may fail, we have to do a slightly funky
two-step deletion, which is described in the comments at the top of
uverbs_cmd.c.
This also still leaves ib_uverbs_idr_lock as a single lock that is
possibly subject to contention.  However, the lock hold time will only
be a single idr operation, so multiple threads should still be able to
make progress, even if ib_uverbs_idr_lock is being ping-ponged.
Surprisingly, these changes even shrink the object code:
add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
											
										 
											2006-06-17 20:44:49 -07:00
										 |  |  | 	put_uobj(uobj); | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-09 15:55:08 -07:00
										 |  |  | 	if (copy_to_user((void __user *) (unsigned long) cmd.response, | 
					
						
							|  |  |  | 			 &resp, sizeof resp)) | 
					
						
							|  |  |  | 		ret = -EFAULT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-18 12:24:13 -07:00
										 |  |  | 	return ret ? ret : in_len; | 
					
						
							|  |  |  | } |