⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ucm.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		}	}	if (uevent->info) {		if (cmd.info_len < uevent->info_len) {			result = -ENOMEM;			goto done;		}		if (copy_to_user((void __user *)(unsigned long)cmd.info,				 uevent->info, uevent->info_len)) {			result = -EFAULT;			goto done;		}	}	list_del(&uevent->file_list);	list_del(&uevent->ctx_list);	uevent->ctx->events_reported++;	kfree(uevent->data);	kfree(uevent->info);	kfree(uevent);done:	up(&file->mutex);	return result;}static ssize_t ib_ucm_create_id(struct ib_ucm_file *file,				const char __user *inbuf,				int in_len, int out_len){	struct ib_ucm_create_id cmd;	struct ib_ucm_create_id_resp resp;	struct ib_ucm_context *ctx;	int result;	if (out_len < sizeof(resp))		return -ENOSPC;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	down(&file->mutex);	ctx = ib_ucm_ctx_alloc(file);	up(&file->mutex);	if (!ctx)		return -ENOMEM;	ctx->uid = cmd.uid;	ctx->cm_id = ib_create_cm_id(file->device->ib_dev,				     ib_ucm_event_handler, ctx);	if (IS_ERR(ctx->cm_id)) {		result = PTR_ERR(ctx->cm_id);		goto err1;	}	resp.id = ctx->id;	if (copy_to_user((void __user *)(unsigned long)cmd.response,			 &resp, sizeof(resp))) {		result = -EFAULT;		goto err2;	}	return 0;err2:	ib_destroy_cm_id(ctx->cm_id);err1:	down(&ctx_id_mutex);	idr_remove(&ctx_id_table, ctx->id);	up(&ctx_id_mutex);	kfree(ctx);	return result;}static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file,				 const char __user *inbuf,				 int in_len, int out_len){	struct ib_ucm_destroy_id cmd;	struct ib_ucm_destroy_id_resp resp;	struct ib_ucm_context *ctx;	int result = 0;	if (out_len < sizeof(resp))		return -ENOSPC;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	down(&ctx_id_mutex);	ctx = idr_find(&ctx_id_table, cmd.id);	if (!ctx)		ctx = ERR_PTR(-ENOENT);	else if (ctx->file != file)		ctx = ERR_PTR(-EINVAL);	else		idr_remove(&ctx_id_table, ctx->id);	up(&ctx_id_mutex);	if (IS_ERR(ctx))		return PTR_ERR(ctx);	atomic_dec(&ctx->ref);	wait_event(ctx->wait, !atomic_read(&ctx->ref));	/* No new events will be generated after destroying the cm_id. */	ib_destroy_cm_id(ctx->cm_id);	/* Cleanup events not yet reported to the user. */	ib_ucm_cleanup_events(ctx);	resp.events_reported = ctx->events_reported;	if (copy_to_user((void __user *)(unsigned long)cmd.response,			 &resp, sizeof(resp)))		result = -EFAULT;	kfree(ctx);	return result;}static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file,			      const char __user *inbuf,			      int in_len, int out_len){	struct ib_ucm_attr_id_resp resp;	struct ib_ucm_attr_id cmd;	struct ib_ucm_context *ctx;	int result = 0;	if (out_len < sizeof(resp))		return -ENOSPC;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	ctx = ib_ucm_ctx_get(file, cmd.id);	if (IS_ERR(ctx))		return PTR_ERR(ctx);	resp.service_id   = ctx->cm_id->service_id;	resp.service_mask = ctx->cm_id->service_mask;	resp.local_id     = ctx->cm_id->local_id;	resp.remote_id    = ctx->cm_id->remote_id;	if (copy_to_user((void __user *)(unsigned long)cmd.response,			 &resp, sizeof(resp)))		result = -EFAULT;	ib_ucm_ctx_put(ctx);	return result;}static void ib_ucm_copy_ah_attr(struct ib_ucm_ah_attr *dest_attr,				struct ib_ah_attr *src_attr){	memcpy(dest_attr->grh_dgid, src_attr->grh.dgid.raw,	       sizeof src_attr->grh.dgid);	dest_attr->grh_flow_label = src_attr->grh.flow_label;	dest_attr->grh_sgid_index = src_attr->grh.sgid_index;	dest_attr->grh_hop_limit = src_attr->grh.hop_limit;	dest_attr->grh_traffic_class = src_attr->grh.traffic_class;	dest_attr->dlid = src_attr->dlid;	dest_attr->sl = src_attr->sl;	dest_attr->src_path_bits = src_attr->src_path_bits;	dest_attr->static_rate = src_attr->static_rate;	dest_attr->is_global = (src_attr->ah_flags & IB_AH_GRH);	dest_attr->port_num = src_attr->port_num;}static void ib_ucm_copy_qp_attr(struct ib_ucm_init_qp_attr_resp *dest_attr,				struct ib_qp_attr *src_attr){	dest_attr->cur_qp_state = src_attr->cur_qp_state;	dest_attr->path_mtu = src_attr->path_mtu;	dest_attr->path_mig_state = src_attr->path_mig_state;	dest_attr->qkey = src_attr->qkey;	dest_attr->rq_psn = src_attr->rq_psn;	dest_attr->sq_psn = src_attr->sq_psn;	dest_attr->dest_qp_num = src_attr->dest_qp_num;	dest_attr->qp_access_flags = src_attr->qp_access_flags;	dest_attr->max_send_wr = src_attr->cap.max_send_wr;	dest_attr->max_recv_wr = src_attr->cap.max_recv_wr;	dest_attr->max_send_sge = src_attr->cap.max_send_sge;	dest_attr->max_recv_sge = src_attr->cap.max_recv_sge;	dest_attr->max_inline_data = src_attr->cap.max_inline_data;	ib_ucm_copy_ah_attr(&dest_attr->ah_attr, &src_attr->ah_attr);	ib_ucm_copy_ah_attr(&dest_attr->alt_ah_attr, &src_attr->alt_ah_attr);	dest_attr->pkey_index = src_attr->pkey_index;	dest_attr->alt_pkey_index = src_attr->alt_pkey_index;	dest_attr->en_sqd_async_notify = src_attr->en_sqd_async_notify;	dest_attr->sq_draining = src_attr->sq_draining;	dest_attr->max_rd_atomic = src_attr->max_rd_atomic;	dest_attr->max_dest_rd_atomic = src_attr->max_dest_rd_atomic;	dest_attr->min_rnr_timer = src_attr->min_rnr_timer;	dest_attr->port_num = src_attr->port_num;	dest_attr->timeout = src_attr->timeout;	dest_attr->retry_cnt = src_attr->retry_cnt;	dest_attr->rnr_retry = src_attr->rnr_retry;	dest_attr->alt_port_num = src_attr->alt_port_num;	dest_attr->alt_timeout = src_attr->alt_timeout;}static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file,				   const char __user *inbuf,				   int in_len, int out_len){	struct ib_ucm_init_qp_attr_resp resp;	struct ib_ucm_init_qp_attr cmd;	struct ib_ucm_context *ctx;	struct ib_qp_attr qp_attr;	int result = 0;	if (out_len < sizeof(resp))		return -ENOSPC;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	ctx = ib_ucm_ctx_get(file, cmd.id);	if (IS_ERR(ctx))		return PTR_ERR(ctx);	resp.qp_attr_mask = 0;	memset(&qp_attr, 0, sizeof qp_attr);	qp_attr.qp_state = cmd.qp_state;	result = ib_cm_init_qp_attr(ctx->cm_id, &qp_attr, &resp.qp_attr_mask);	if (result)		goto out;	ib_ucm_copy_qp_attr(&resp, &qp_attr);	if (copy_to_user((void __user *)(unsigned long)cmd.response,			 &resp, sizeof(resp)))		result = -EFAULT;out:	ib_ucm_ctx_put(ctx);	return result;}static ssize_t ib_ucm_listen(struct ib_ucm_file *file,			     const char __user *inbuf,			     int in_len, int out_len){	struct ib_ucm_listen cmd;	struct ib_ucm_context *ctx;	int result;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	ctx = ib_ucm_ctx_get(file, cmd.id);	if (IS_ERR(ctx))		return PTR_ERR(ctx);	result = ib_cm_listen(ctx->cm_id, cmd.service_id, cmd.service_mask);	ib_ucm_ctx_put(ctx);	return result;}static ssize_t ib_ucm_establish(struct ib_ucm_file *file,				const char __user *inbuf,				int in_len, int out_len){	struct ib_ucm_establish cmd;	struct ib_ucm_context *ctx;	int result;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	ctx = ib_ucm_ctx_get(file, cmd.id);	if (IS_ERR(ctx))		return PTR_ERR(ctx);	result = ib_cm_establish(ctx->cm_id);	ib_ucm_ctx_put(ctx);	return result;}static int ib_ucm_alloc_data(const void **dest, u64 src, u32 len){	void *data;	*dest = NULL;	if (!len)		return 0;	data = kmalloc(len, GFP_KERNEL);	if (!data)		return -ENOMEM;	if (copy_from_user(data, (void __user *)(unsigned long)src, len)) {		kfree(data);		return -EFAULT;	}	*dest = data;	return 0;}static int ib_ucm_path_get(struct ib_sa_path_rec **path, u64 src){	struct ib_ucm_path_rec ucm_path;	struct ib_sa_path_rec  *sa_path;	*path = NULL;	if (!src)		return 0;	sa_path = kmalloc(sizeof(*sa_path), GFP_KERNEL);	if (!sa_path)		return -ENOMEM;	if (copy_from_user(&ucm_path, (void __user *)(unsigned long)src,			   sizeof(ucm_path))) {		kfree(sa_path);		return -EFAULT;	}	memcpy(sa_path->dgid.raw, ucm_path.dgid, sizeof sa_path->dgid);	memcpy(sa_path->sgid.raw, ucm_path.sgid, sizeof sa_path->sgid);	sa_path->dlid	          = ucm_path.dlid;	sa_path->slid	          = ucm_path.slid;	sa_path->raw_traffic      = ucm_path.raw_traffic;	sa_path->flow_label       = ucm_path.flow_label;	sa_path->hop_limit        = ucm_path.hop_limit;	sa_path->traffic_class    = ucm_path.traffic_class;	sa_path->reversible       = ucm_path.reversible;	sa_path->numb_path        = ucm_path.numb_path;	sa_path->pkey             = ucm_path.pkey;	sa_path->sl               = ucm_path.sl;	sa_path->mtu_selector     = ucm_path.mtu_selector;	sa_path->mtu              = ucm_path.mtu;	sa_path->rate_selector    = ucm_path.rate_selector;	sa_path->rate             = ucm_path.rate;	sa_path->packet_life_time = ucm_path.packet_life_time;	sa_path->preference       = ucm_path.preference;	sa_path->packet_life_time_selector =		ucm_path.packet_life_time_selector;	*path = sa_path;	return 0;}static ssize_t ib_ucm_send_req(struct ib_ucm_file *file,			       const char __user *inbuf,			       int in_len, int out_len){	struct ib_cm_req_param param;	struct ib_ucm_context *ctx;	struct ib_ucm_req cmd;	int result;	param.private_data   = NULL;	param.primary_path   = NULL;	param.alternate_path = NULL;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	result = ib_ucm_alloc_data(&param.private_data, cmd.data, cmd.len);	if (result)		goto done;	result = ib_ucm_path_get(&param.primary_path, cmd.primary_path);	if (result)		goto done;	result = ib_ucm_path_get(&param.alternate_path, cmd.alternate_path);	if (result)		goto done;	param.private_data_len           = cmd.len;	param.service_id                 = cmd.sid;	param.qp_num                     = cmd.qpn;	param.qp_type                    = cmd.qp_type;	param.starting_psn               = cmd.psn;	param.peer_to_peer               = cmd.peer_to_peer;	param.responder_resources        = cmd.responder_resources;	param.initiator_depth            = cmd.initiator_depth;	param.remote_cm_response_timeout = cmd.remote_cm_response_timeout;	param.flow_control               = cmd.flow_control;	param.local_cm_response_timeout  = cmd.local_cm_response_timeout;	param.retry_count                = cmd.retry_count;	param.rnr_retry_count            = cmd.rnr_retry_count;	param.max_cm_retries             = cmd.max_cm_retries;	param.srq                        = cmd.srq;	ctx = ib_ucm_ctx_get(file, cmd.id);	if (!IS_ERR(ctx)) {		result = ib_send_cm_req(ctx->cm_id, &param);		ib_ucm_ctx_put(ctx);	} else		result = PTR_ERR(ctx);done:	kfree(param.private_data);	kfree(param.primary_path);	kfree(param.alternate_path);	return result;}static ssize_t ib_ucm_send_rep(struct ib_ucm_file *file,			       const char __user *inbuf,			       int in_len, int out_len){	struct ib_cm_rep_param param;	struct ib_ucm_context *ctx;	struct ib_ucm_rep cmd;	int result;	param.private_data = NULL;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	result = ib_ucm_alloc_data(&param.private_data, cmd.data, cmd.len);	if (result)		return result;	param.qp_num              = cmd.qpn;	param.starting_psn        = cmd.psn;	param.private_data_len    = cmd.len;	param.responder_resources = cmd.responder_resources;	param.initiator_depth     = cmd.initiator_depth;	param.target_ack_delay    = cmd.target_ack_delay;	param.failover_accepted   = cmd.failover_accepted;	param.flow_control        = cmd.flow_control;	param.rnr_retry_count     = cmd.rnr_retry_count;	param.srq                 = cmd.srq;	ctx = ib_ucm_ctx_get(file, cmd.id);	if (!IS_ERR(ctx)) {		ctx->uid = cmd.uid;		result = ib_send_cm_rep(ctx->cm_id, &param);		ib_ucm_ctx_put(ctx);	} else		result = PTR_ERR(ctx);	kfree(param.private_data);	return result;}static ssize_t ib_ucm_send_private_data(struct ib_ucm_file *file,					const char __user *inbuf, int in_len,					int (*func)(struct ib_cm_id *cm_id,						    const void *private_data,						    u8 private_data_len)){	struct ib_ucm_private_data cmd;	struct ib_ucm_context *ctx;	const void *private_data = NULL;	int result;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	result = ib_ucm_alloc_data(&private_data, cmd.data, cmd.len);	if (result)		return result;	ctx = ib_ucm_ctx_get(file, cmd.id);	if (!IS_ERR(ctx)) {		result = func(ctx->cm_id, private_data, cmd.len);		ib_ucm_ctx_put(ctx);	} else		result = PTR_ERR(ctx);	kfree(private_data);	return result;}static ssize_t ib_ucm_send_rtu(struct ib_ucm_file *file,			       const char __user *inbuf,			       int in_len, int out_len){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -