You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband: IB/core: Set static rate in ib_init_ah_from_path() IB/ipath: Make ipath_map_sg() static IB/core: Fix sparse warnings about shadowed declarations RDMA/cma: Add multicast communication support IB/sa: Track multicast join/leave requests IPoIB: CM error handling thinko fix RDMA/cxgb3: Remove Open Grid Computing copyrights in iw_cxgb3 driver RDMA/cxgb3: Fail posts synchronously when in TERMINATE state RDMA/iwcm: iw_cm_id destruction race fixes IB/ehca: Change query_port() to return LINK_UP instead UNKNOWN IB/ehca: Allow en/disabling scaling code via module parameter IB/ehca: Fix race condition/locking issues in scaling code IB/ehca: Rework irq handler IPoIB: Only allow root to change between datagram and connected mode IB/mthca: Fix allocation of ICM chunks in coherent memory IB/mthca: Allow the QP state transition RESET->RESET
This commit is contained in:
@@ -12,7 +12,7 @@ ib_core-y := packer.o ud_header.o verbs.o sysfs.o \
|
||||
|
||||
ib_mad-y := mad.o smi.o agent.o mad_rmpp.o
|
||||
|
||||
ib_sa-y := sa_query.o
|
||||
ib_sa-y := sa_query.o multicast.o
|
||||
|
||||
ib_cm-y := cm.o
|
||||
|
||||
|
||||
+315
-44
File diff suppressed because it is too large
Load Diff
@@ -301,7 +301,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
|
||||
|
||||
{
|
||||
struct ib_pool_fmr *fmr;
|
||||
struct ib_fmr_attr attr = {
|
||||
struct ib_fmr_attr fmr_attr = {
|
||||
.max_pages = params->max_pages_per_fmr,
|
||||
.max_maps = pool->max_remaps,
|
||||
.page_shift = params->page_shift
|
||||
@@ -321,7 +321,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
|
||||
fmr->ref_count = 0;
|
||||
INIT_HLIST_NODE(&fmr->cache_node);
|
||||
|
||||
fmr->fmr = ib_alloc_fmr(pd, params->access, &attr);
|
||||
fmr->fmr = ib_alloc_fmr(pd, params->access, &fmr_attr);
|
||||
if (IS_ERR(fmr->fmr)) {
|
||||
printk(KERN_WARNING "fmr_create failed for FMR %d", i);
|
||||
kfree(fmr);
|
||||
|
||||
@@ -146,6 +146,12 @@ static int copy_private_data(struct iw_cm_event *event)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_cm_id(struct iwcm_id_private *cm_id_priv)
|
||||
{
|
||||
dealloc_work_entries(cm_id_priv);
|
||||
kfree(cm_id_priv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Release a reference on cm_id. If the last reference is being
|
||||
* released, enable the waiting thread (in iw_destroy_cm_id) to
|
||||
@@ -153,21 +159,14 @@ static int copy_private_data(struct iw_cm_event *event)
|
||||
*/
|
||||
static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
|
||||
if (atomic_dec_and_test(&cm_id_priv->refcount)) {
|
||||
BUG_ON(!list_empty(&cm_id_priv->work_list));
|
||||
if (waitqueue_active(&cm_id_priv->destroy_comp.wait)) {
|
||||
BUG_ON(cm_id_priv->state != IW_CM_STATE_DESTROYING);
|
||||
BUG_ON(test_bit(IWCM_F_CALLBACK_DESTROY,
|
||||
&cm_id_priv->flags));
|
||||
ret = 1;
|
||||
}
|
||||
complete(&cm_id_priv->destroy_comp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void add_ref(struct iw_cm_id *cm_id)
|
||||
@@ -181,7 +180,11 @@ static void rem_ref(struct iw_cm_id *cm_id)
|
||||
{
|
||||
struct iwcm_id_private *cm_id_priv;
|
||||
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
|
||||
iwcm_deref_id(cm_id_priv);
|
||||
if (iwcm_deref_id(cm_id_priv) &&
|
||||
test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) {
|
||||
BUG_ON(!list_empty(&cm_id_priv->work_list));
|
||||
free_cm_id(cm_id_priv);
|
||||
}
|
||||
}
|
||||
|
||||
static int cm_event_handler(struct iw_cm_id *cm_id, struct iw_cm_event *event);
|
||||
@@ -355,7 +358,9 @@ static void destroy_cm_id(struct iw_cm_id *cm_id)
|
||||
case IW_CM_STATE_CONN_RECV:
|
||||
/*
|
||||
* App called destroy before/without calling accept after
|
||||
* receiving connection request event notification.
|
||||
* receiving connection request event notification or
|
||||
* returned non zero from the event callback function.
|
||||
* In either case, must tell the provider to reject.
|
||||
*/
|
||||
cm_id_priv->state = IW_CM_STATE_DESTROYING;
|
||||
break;
|
||||
@@ -391,9 +396,7 @@ void iw_destroy_cm_id(struct iw_cm_id *cm_id)
|
||||
|
||||
wait_for_completion(&cm_id_priv->destroy_comp);
|
||||
|
||||
dealloc_work_entries(cm_id_priv);
|
||||
|
||||
kfree(cm_id_priv);
|
||||
free_cm_id(cm_id_priv);
|
||||
}
|
||||
EXPORT_SYMBOL(iw_destroy_cm_id);
|
||||
|
||||
@@ -647,10 +650,11 @@ static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv,
|
||||
/* Call the client CM handler */
|
||||
ret = cm_id->cm_handler(cm_id, iw_event);
|
||||
if (ret) {
|
||||
iw_cm_reject(cm_id, NULL, 0);
|
||||
set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
|
||||
destroy_cm_id(cm_id);
|
||||
if (atomic_read(&cm_id_priv->refcount)==0)
|
||||
kfree(cm_id);
|
||||
free_cm_id(cm_id_priv);
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -854,13 +858,12 @@ static void cm_work_handler(struct work_struct *_work)
|
||||
destroy_cm_id(&cm_id_priv->id);
|
||||
}
|
||||
BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
|
||||
if (iwcm_deref_id(cm_id_priv))
|
||||
return;
|
||||
|
||||
if (atomic_read(&cm_id_priv->refcount)==0 &&
|
||||
test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) {
|
||||
dealloc_work_entries(cm_id_priv);
|
||||
kfree(cm_id_priv);
|
||||
if (iwcm_deref_id(cm_id_priv)) {
|
||||
if (test_bit(IWCM_F_CALLBACK_DESTROY,
|
||||
&cm_id_priv->flags)) {
|
||||
BUG_ON(!list_empty(&cm_id_priv->work_list));
|
||||
free_cm_id(cm_id_priv);
|
||||
}
|
||||
return;
|
||||
}
|
||||
spin_lock_irqsave(&cm_id_priv->lock, flags);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Topspin Communications. All rights reserved.
|
||||
* Copyright (c) 2005 Voltaire, Inc. All rights reserved.
|
||||
* Copyright (c) 2006 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef SA_H
|
||||
#define SA_H
|
||||
|
||||
#include <rdma/ib_sa.h>
|
||||
|
||||
static inline void ib_sa_client_get(struct ib_sa_client *client)
|
||||
{
|
||||
atomic_inc(&client->users);
|
||||
}
|
||||
|
||||
static inline void ib_sa_client_put(struct ib_sa_client *client)
|
||||
{
|
||||
if (atomic_dec_and_test(&client->users))
|
||||
complete(&client->comp);
|
||||
}
|
||||
|
||||
int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
|
||||
struct ib_device *device, u8 port_num,
|
||||
u8 method,
|
||||
struct ib_sa_mcmember_rec *rec,
|
||||
ib_sa_comp_mask comp_mask,
|
||||
int timeout_ms, gfp_t gfp_mask,
|
||||
void (*callback)(int status,
|
||||
struct ib_sa_mcmember_rec *resp,
|
||||
void *context),
|
||||
void *context,
|
||||
struct ib_sa_query **sa_query);
|
||||
|
||||
int mcast_init(void);
|
||||
void mcast_cleanup(void);
|
||||
|
||||
#endif /* SA_H */
|
||||
@@ -47,8 +47,8 @@
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include <rdma/ib_pack.h>
|
||||
#include <rdma/ib_sa.h>
|
||||
#include <rdma/ib_cache.h>
|
||||
#include "sa.h"
|
||||
|
||||
MODULE_AUTHOR("Roland Dreier");
|
||||
MODULE_DESCRIPTION("InfiniBand subnet administration query support");
|
||||
@@ -425,17 +425,6 @@ void ib_sa_register_client(struct ib_sa_client *client)
|
||||
}
|
||||
EXPORT_SYMBOL(ib_sa_register_client);
|
||||
|
||||
static inline void ib_sa_client_get(struct ib_sa_client *client)
|
||||
{
|
||||
atomic_inc(&client->users);
|
||||
}
|
||||
|
||||
static inline void ib_sa_client_put(struct ib_sa_client *client)
|
||||
{
|
||||
if (atomic_dec_and_test(&client->users))
|
||||
complete(&client->comp);
|
||||
}
|
||||
|
||||
void ib_sa_unregister_client(struct ib_sa_client *client)
|
||||
{
|
||||
ib_sa_client_put(client);
|
||||
@@ -482,6 +471,7 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
|
||||
ah_attr->sl = rec->sl;
|
||||
ah_attr->src_path_bits = be16_to_cpu(rec->slid) & 0x7f;
|
||||
ah_attr->port_num = port_num;
|
||||
ah_attr->static_rate = rec->rate;
|
||||
|
||||
if (rec->hop_limit > 1) {
|
||||
ah_attr->ah_flags = IB_AH_GRH;
|
||||
@@ -901,7 +891,6 @@ err1:
|
||||
kfree(query);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ib_sa_mcmember_rec_query);
|
||||
|
||||
static void send_handler(struct ib_mad_agent *agent,
|
||||
struct ib_mad_send_wc *mad_send_wc)
|
||||
@@ -1053,14 +1042,27 @@ static int __init ib_sa_init(void)
|
||||
get_random_bytes(&tid, sizeof tid);
|
||||
|
||||
ret = ib_register_client(&sa_client);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
printk(KERN_ERR "Couldn't register ib_sa client\n");
|
||||
goto err1;
|
||||
}
|
||||
|
||||
ret = mcast_init();
|
||||
if (ret) {
|
||||
printk(KERN_ERR "Couldn't initialize multicast handling\n");
|
||||
goto err2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err2:
|
||||
ib_unregister_client(&sa_client);
|
||||
err1:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit ib_sa_cleanup(void)
|
||||
{
|
||||
mcast_cleanup();
|
||||
ib_unregister_client(&sa_client);
|
||||
idr_destroy(&query_idr);
|
||||
}
|
||||
|
||||
@@ -714,8 +714,6 @@ int ib_device_register_sysfs(struct ib_device *device)
|
||||
if (ret)
|
||||
goto err_put;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= device->phys_port_cnt; ++i) {
|
||||
ret = add_port(device, i);
|
||||
if (ret)
|
||||
|
||||
@@ -70,10 +70,24 @@ struct ucma_context {
|
||||
u64 uid;
|
||||
|
||||
struct list_head list;
|
||||
struct list_head mc_list;
|
||||
};
|
||||
|
||||
struct ucma_multicast {
|
||||
struct ucma_context *ctx;
|
||||
int id;
|
||||
int events_reported;
|
||||
|
||||
u64 uid;
|
||||
struct list_head list;
|
||||
struct sockaddr addr;
|
||||
u8 pad[sizeof(struct sockaddr_in6) -
|
||||
sizeof(struct sockaddr)];
|
||||
};
|
||||
|
||||
struct ucma_event {
|
||||
struct ucma_context *ctx;
|
||||
struct ucma_multicast *mc;
|
||||
struct list_head list;
|
||||
struct rdma_cm_id *cm_id;
|
||||
struct rdma_ucm_event_resp resp;
|
||||
@@ -81,6 +95,7 @@ struct ucma_event {
|
||||
|
||||
static DEFINE_MUTEX(mut);
|
||||
static DEFINE_IDR(ctx_idr);
|
||||
static DEFINE_IDR(multicast_idr);
|
||||
|
||||
static inline struct ucma_context *_ucma_find_context(int id,
|
||||
struct ucma_file *file)
|
||||
@@ -124,6 +139,7 @@ static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file)
|
||||
|
||||
atomic_set(&ctx->ref, 1);
|
||||
init_completion(&ctx->comp);
|
||||
INIT_LIST_HEAD(&ctx->mc_list);
|
||||
ctx->file = file;
|
||||
|
||||
do {
|
||||
@@ -147,6 +163,37 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct ucma_multicast* ucma_alloc_multicast(struct ucma_context *ctx)
|
||||
{
|
||||
struct ucma_multicast *mc;
|
||||
int ret;
|
||||
|
||||
mc = kzalloc(sizeof(*mc), GFP_KERNEL);
|
||||
if (!mc)
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
ret = idr_pre_get(&multicast_idr, GFP_KERNEL);
|
||||
if (!ret)
|
||||
goto error;
|
||||
|
||||
mutex_lock(&mut);
|
||||
ret = idr_get_new(&multicast_idr, mc, &mc->id);
|
||||
mutex_unlock(&mut);
|
||||
} while (ret == -EAGAIN);
|
||||
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
mc->ctx = ctx;
|
||||
list_add_tail(&mc->list, &ctx->mc_list);
|
||||
return mc;
|
||||
|
||||
error:
|
||||
kfree(mc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ucma_copy_conn_event(struct rdma_ucm_conn_param *dst,
|
||||
struct rdma_conn_param *src)
|
||||
{
|
||||
@@ -180,8 +227,19 @@ static void ucma_set_event_context(struct ucma_context *ctx,
|
||||
struct ucma_event *uevent)
|
||||
{
|
||||
uevent->ctx = ctx;
|
||||
uevent->resp.uid = ctx->uid;
|
||||
uevent->resp.id = ctx->id;
|
||||
switch (event->event) {
|
||||
case RDMA_CM_EVENT_MULTICAST_JOIN:
|
||||
case RDMA_CM_EVENT_MULTICAST_ERROR:
|
||||
uevent->mc = (struct ucma_multicast *)
|
||||
event->param.ud.private_data;
|
||||
uevent->resp.uid = uevent->mc->uid;
|
||||
uevent->resp.id = uevent->mc->id;
|
||||
break;
|
||||
default:
|
||||
uevent->resp.uid = ctx->uid;
|
||||
uevent->resp.id = ctx->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int ucma_event_handler(struct rdma_cm_id *cm_id,
|
||||
@@ -199,7 +257,7 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id,
|
||||
ucma_set_event_context(ctx, event, uevent);
|
||||
uevent->resp.event = event->event;
|
||||
uevent->resp.status = event->status;
|
||||
if (cm_id->ps == RDMA_PS_UDP)
|
||||
if (cm_id->ps == RDMA_PS_UDP || cm_id->ps == RDMA_PS_IPOIB)
|
||||
ucma_copy_ud_event(&uevent->resp.param.ud, &event->param.ud);
|
||||
else
|
||||
ucma_copy_conn_event(&uevent->resp.param.conn,
|
||||
@@ -290,6 +348,8 @@ static ssize_t ucma_get_event(struct ucma_file *file, const char __user *inbuf,
|
||||
|
||||
list_del(&uevent->list);
|
||||
uevent->ctx->events_reported++;
|
||||
if (uevent->mc)
|
||||
uevent->mc->events_reported++;
|
||||
kfree(uevent);
|
||||
done:
|
||||
mutex_unlock(&file->mut);
|
||||
@@ -342,6 +402,19 @@ err1:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ucma_cleanup_multicast(struct ucma_context *ctx)
|
||||
{
|
||||
struct ucma_multicast *mc, *tmp;
|
||||
|
||||
mutex_lock(&mut);
|
||||
list_for_each_entry_safe(mc, tmp, &ctx->mc_list, list) {
|
||||
list_del(&mc->list);
|
||||
idr_remove(&multicast_idr, mc->id);
|
||||
kfree(mc);
|
||||
}
|
||||
mutex_unlock(&mut);
|
||||
}
|
||||
|
||||
static void ucma_cleanup_events(struct ucma_context *ctx)
|
||||
{
|
||||
struct ucma_event *uevent, *tmp;
|
||||
@@ -360,6 +433,19 @@ static void ucma_cleanup_events(struct ucma_context *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
static void ucma_cleanup_mc_events(struct ucma_multicast *mc)
|
||||
{
|
||||
struct ucma_event *uevent, *tmp;
|
||||
|
||||
list_for_each_entry_safe(uevent, tmp, &mc->ctx->file->event_list, list) {
|
||||
if (uevent->mc != mc)
|
||||
continue;
|
||||
|
||||
list_del(&uevent->list);
|
||||
kfree(uevent);
|
||||
}
|
||||
}
|
||||
|
||||
static int ucma_free_ctx(struct ucma_context *ctx)
|
||||
{
|
||||
int events_reported;
|
||||
@@ -367,6 +453,8 @@ static int ucma_free_ctx(struct ucma_context *ctx)
|
||||
/* No new events will be generated after destroying the id. */
|
||||
rdma_destroy_id(ctx->cm_id);
|
||||
|
||||
ucma_cleanup_multicast(ctx);
|
||||
|
||||
/* Cleanup events not yet reported to the user. */
|
||||
mutex_lock(&ctx->file->mut);
|
||||
ucma_cleanup_events(ctx);
|
||||
@@ -731,6 +819,114 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t ucma_join_multicast(struct ucma_file *file,
|
||||
const char __user *inbuf,
|
||||
int in_len, int out_len)
|
||||
{
|
||||
struct rdma_ucm_join_mcast cmd;
|
||||
struct rdma_ucm_create_id_resp resp;
|
||||
struct ucma_context *ctx;
|
||||
struct ucma_multicast *mc;
|
||||
int ret;
|
||||
|
||||
if (out_len < sizeof(resp))
|
||||
return -ENOSPC;
|
||||
|
||||
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
|
||||
return -EFAULT;
|
||||
|
||||
ctx = ucma_get_ctx(file, cmd.id);
|
||||
if (IS_ERR(ctx))
|
||||
return PTR_ERR(ctx);
|
||||
|
||||
mutex_lock(&file->mut);
|
||||
mc = ucma_alloc_multicast(ctx);
|
||||
if (IS_ERR(mc)) {
|
||||
ret = PTR_ERR(mc);
|
||||
goto err1;
|
||||
}
|
||||
|
||||
mc->uid = cmd.uid;
|
||||
memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr);
|
||||
ret = rdma_join_multicast(ctx->cm_id, &mc->addr, mc);
|
||||
if (ret)
|
||||
goto err2;
|
||||
|
||||
resp.id = mc->id;
|
||||
if (copy_to_user((void __user *)(unsigned long)cmd.response,
|
||||
&resp, sizeof(resp))) {
|
||||
ret = -EFAULT;
|
||||
goto err3;
|
||||
}
|
||||
|
||||
mutex_unlock(&file->mut);
|
||||
ucma_put_ctx(ctx);
|
||||
return 0;
|
||||
|
||||
err3:
|
||||
rdma_leave_multicast(ctx->cm_id, &mc->addr);
|
||||
ucma_cleanup_mc_events(mc);
|
||||
err2:
|
||||
mutex_lock(&mut);
|
||||
idr_remove(&multicast_idr, mc->id);
|
||||
mutex_unlock(&mut);
|
||||
list_del(&mc->list);
|
||||
kfree(mc);
|
||||
err1:
|
||||
mutex_unlock(&file->mut);
|
||||
ucma_put_ctx(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t ucma_leave_multicast(struct ucma_file *file,
|
||||
const char __user *inbuf,
|
||||
int in_len, int out_len)
|
||||
{
|
||||
struct rdma_ucm_destroy_id cmd;
|
||||
struct rdma_ucm_destroy_id_resp resp;
|
||||
struct ucma_multicast *mc;
|
||||
int ret = 0;
|
||||
|
||||
if (out_len < sizeof(resp))
|
||||
return -ENOSPC;
|
||||
|
||||
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
|
||||
return -EFAULT;
|
||||
|
||||
mutex_lock(&mut);
|
||||
mc = idr_find(&multicast_idr, cmd.id);
|
||||
if (!mc)
|
||||
mc = ERR_PTR(-ENOENT);
|
||||
else if (mc->ctx->file != file)
|
||||
mc = ERR_PTR(-EINVAL);
|
||||
else {
|
||||
idr_remove(&multicast_idr, mc->id);
|
||||
atomic_inc(&mc->ctx->ref);
|
||||
}
|
||||
mutex_unlock(&mut);
|
||||
|
||||
if (IS_ERR(mc)) {
|
||||
ret = PTR_ERR(mc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rdma_leave_multicast(mc->ctx->cm_id, &mc->addr);
|
||||
mutex_lock(&mc->ctx->file->mut);
|
||||
ucma_cleanup_mc_events(mc);
|
||||
list_del(&mc->list);
|
||||
mutex_unlock(&mc->ctx->file->mut);
|
||||
|
||||
ucma_put_ctx(mc->ctx);
|
||||
resp.events_reported = mc->events_reported;
|
||||
kfree(mc);
|
||||
|
||||
if (copy_to_user((void __user *)(unsigned long)cmd.response,
|
||||
&resp, sizeof(resp)))
|
||||
ret = -EFAULT;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
|
||||
const char __user *inbuf,
|
||||
int in_len, int out_len) = {
|
||||
@@ -750,6 +946,8 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
|
||||
[RDMA_USER_CM_CMD_GET_OPTION] = NULL,
|
||||
[RDMA_USER_CM_CMD_SET_OPTION] = NULL,
|
||||
[RDMA_USER_CM_CMD_NOTIFY] = ucma_notify,
|
||||
[RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast,
|
||||
[RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast,
|
||||
};
|
||||
|
||||
static ssize_t ucma_write(struct file *filp, const char __user *buf,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user