diff options
author | Sean Hefty <sean.hefty@intel.com> | 2012-01-10 18:53:41 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2012-01-27 13:07:48 -0500 |
commit | 9ced69ca5296567033804950d8d2161f454c5012 (patch) | |
tree | 6db2856c3ba7e3c018ac039c4c664be0179c1ff3 /drivers/infiniband | |
parent | dcd6c92267155e70a94b3927bce681ce74b80d1f (diff) |
RDMA/ucma: Discard all events for new connections until accepted
After reporting a new connection request to user space, the rdma_ucm
will discard subsequent events until the user has associated a user
space idenfier with the kernel cm_id. This is needed to avoid
reporting a reject/disconnect event to the user for a request that
they may not have processed.
The user space identifier is set once the user tries to accept the
connection request. However, the following race exists in ucma_accept():
ctx->uid = cmd.uid;
<events may be reported now>
ret = rdma_accept(ctx->cm_id, ...);
Once ctx->uid has been set, new events may be reported to the user.
While the above mentioned race is avoided, there is an issue that the
user _may_ receive a reject/disconnect event if rdma_accept() fails,
depending on when the event is processed. To simplify the use of
rdma_accept(), discard all events unless rdma_accept() succeeds.
This problem was discovered based on questions from Roland Dreier
<roland@purestorage.com>.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/ucma.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index b37b0c02a7b9..5034a87cc72d 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
@@ -808,9 +808,12 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf, | |||
808 | return PTR_ERR(ctx); | 808 | return PTR_ERR(ctx); |
809 | 809 | ||
810 | if (cmd.conn_param.valid) { | 810 | if (cmd.conn_param.valid) { |
811 | ctx->uid = cmd.uid; | ||
812 | ucma_copy_conn_param(&conn_param, &cmd.conn_param); | 811 | ucma_copy_conn_param(&conn_param, &cmd.conn_param); |
812 | mutex_lock(&file->mut); | ||
813 | ret = rdma_accept(ctx->cm_id, &conn_param); | 813 | ret = rdma_accept(ctx->cm_id, &conn_param); |
814 | if (!ret) | ||
815 | ctx->uid = cmd.uid; | ||
816 | mutex_unlock(&file->mut); | ||
814 | } else | 817 | } else |
815 | ret = rdma_accept(ctx->cm_id, NULL); | 818 | ret = rdma_accept(ctx->cm_id, NULL); |
816 | 819 | ||