Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1a0b23b authored by Michael S. Tsirkin's avatar Michael S. Tsirkin Committed by Roland Dreier
Browse files

IB/sa: Require SA registration



Require users to register with SA module, to prevent the sa_query
module text from going away while an SA query callback is still
running.  Update all in-tree users for the new interface.

Signed-off-by: default avatarMichael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: default avatarSean Hefty <sean.hefty@intel.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 2439a6e6
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ static struct ib_client cma_client = {
	.remove = cma_remove_one
};

static struct ib_sa_client sa_client;
static LIST_HEAD(dev_list);
static LIST_HEAD(listen_any_list);
static DEFINE_MUTEX(lock);
@@ -1323,7 +1324,7 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
	path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(addr));
	path_rec.numb_path = 1;

	id_priv->query_id = ib_sa_path_rec_get(id_priv->id.device,
	id_priv->query_id = ib_sa_path_rec_get(&sa_client, id_priv->id.device,
				id_priv->id.port_num, &path_rec,
				IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID |
				IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH,
@@ -2199,12 +2200,15 @@ static int cma_init(void)
	if (!cma_wq)
		return -ENOMEM;

	ib_sa_register_client(&sa_client);

	ret = ib_register_client(&cma_client);
	if (ret)
		goto err;
	return 0;

err:
	ib_sa_unregister_client(&sa_client);
	destroy_workqueue(cma_wq);
	return ret;
}
@@ -2212,6 +2216,7 @@ static int cma_init(void)
static void cma_cleanup(void)
{
	ib_unregister_client(&cma_client);
	ib_sa_unregister_client(&sa_client);
	destroy_workqueue(cma_wq);
	idr_destroy(&sdp_ps);
	idr_destroy(&tcp_ps);
+51 −9
Original line number Diff line number Diff line
/*
 * 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
@@ -75,6 +76,7 @@ struct ib_sa_device {
struct ib_sa_query {
	void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *);
	void (*release)(struct ib_sa_query *);
	struct ib_sa_client    *client;
	struct ib_sa_port      *port;
	struct ib_mad_send_buf *mad_buf;
	struct ib_sa_sm_ah     *sm_ah;
@@ -415,6 +417,31 @@ static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event
	}
}

void ib_sa_register_client(struct ib_sa_client *client)
{
	atomic_set(&client->users, 1);
	init_completion(&client->comp);
}
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);
	wait_for_completion(&client->comp);
}
EXPORT_SYMBOL(ib_sa_unregister_client);

/**
 * ib_sa_cancel_query - try to cancel an SA query
 * @id:ID of query to cancel
@@ -557,6 +584,7 @@ static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)

/**
 * ib_sa_path_rec_get - Start a Path get query
 * @client:SA client
 * @device:device to send query on
 * @port_num: port number to send query on
 * @rec:Path Record to send in query
@@ -579,7 +607,8 @@ static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
 * error code.  Otherwise it is a query ID that can be used to cancel
 * the query.
 */
int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
int ib_sa_path_rec_get(struct ib_sa_client *client,
		       struct ib_device *device, u8 port_num,
		       struct ib_sa_path_rec *rec,
		       ib_sa_comp_mask comp_mask,
		       int timeout_ms, gfp_t gfp_mask,
@@ -614,6 +643,8 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
		goto err1;
	}

	ib_sa_client_get(client);
	query->sa_query.client = client;
	query->callback        = callback;
	query->context         = context;

@@ -639,6 +670,7 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,

err2:
	*sa_query = NULL;
	ib_sa_client_put(query->sa_query.client);
	ib_free_send_mad(query->sa_query.mad_buf);

err1:
@@ -671,6 +703,7 @@ static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)

/**
 * ib_sa_service_rec_query - Start Service Record operation
 * @client:SA client
 * @device:device to send request on
 * @port_num: port number to send request on
 * @method:SA method - should be get, set, or delete
@@ -695,7 +728,8 @@ static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
 * error code.  Otherwise it is a request ID that can be used to cancel
 * the query.
 */
int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
int ib_sa_service_rec_query(struct ib_sa_client *client,
			    struct ib_device *device, u8 port_num, u8 method,
			    struct ib_sa_service_rec *rec,
			    ib_sa_comp_mask comp_mask,
			    int timeout_ms, gfp_t gfp_mask,
@@ -735,6 +769,8 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
		goto err1;
	}

	ib_sa_client_get(client);
	query->sa_query.client = client;
	query->callback        = callback;
	query->context         = context;

@@ -761,6 +797,7 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,

err2:
	*sa_query = NULL;
	ib_sa_client_put(query->sa_query.client);
	ib_free_send_mad(query->sa_query.mad_buf);

err1:
@@ -791,7 +828,8 @@ static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query)
	kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query));
}

int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
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,
@@ -827,6 +865,8 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
		goto err1;
	}

	ib_sa_client_get(client);
	query->sa_query.client = client;
	query->callback        = callback;
	query->context         = context;

@@ -853,6 +893,7 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,

err2:
	*sa_query = NULL;
	ib_sa_client_put(query->sa_query.client);
	ib_free_send_mad(query->sa_query.mad_buf);

err1:
@@ -889,6 +930,7 @@ static void send_handler(struct ib_mad_agent *agent,

	ib_free_send_mad(mad_send_wc->send_buf);
	kref_put(&query->sm_ah->ref, free_sm_ah);
	ib_sa_client_put(query->client);
	query->release(query);
}

+2 −0
Original line number Diff line number Diff line
@@ -336,6 +336,8 @@ static inline void ipoib_unregister_debugfs(void) { }
extern int ipoib_sendq_size;
extern int ipoib_recvq_size;

extern struct ib_sa_client ipoib_sa_client;

#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
extern int ipoib_debug_level;

+9 −3
Original line number Diff line number Diff line
@@ -82,6 +82,8 @@ static const u8 ipv4_bcast_addr[] = {

struct workqueue_struct *ipoib_workqueue;

struct ib_sa_client ipoib_sa_client;

static void ipoib_add_one(struct ib_device *device);
static void ipoib_remove_one(struct ib_device *device);

@@ -463,7 +465,7 @@ static int path_rec_start(struct net_device *dev,
	init_completion(&path->done);

	path->query_id =
		ib_sa_path_rec_get(priv->ca, priv->port,
		ib_sa_path_rec_get(&ipoib_sa_client, priv->ca, priv->port,
				   &path->pathrec,
				   IB_SA_PATH_REC_DGID		|
				   IB_SA_PATH_REC_SGID		|
@@ -1191,13 +1193,16 @@ static int __init ipoib_init_module(void)
		goto err_fs;
	}

	ib_sa_register_client(&ipoib_sa_client);

	ret = ib_register_client(&ipoib_client);
	if (ret)
		goto err_wq;
		goto err_sa;

	return 0;

err_wq:
err_sa:
	ib_sa_unregister_client(&ipoib_sa_client);
	destroy_workqueue(ipoib_workqueue);

err_fs:
@@ -1209,6 +1214,7 @@ static int __init ipoib_init_module(void)
static void __exit ipoib_cleanup_module(void)
{
	ib_unregister_client(&ipoib_client);
	ib_sa_unregister_client(&ipoib_sa_client);
	ipoib_unregister_debugfs();
	destroy_workqueue(ipoib_workqueue);
}
+6 −6
Original line number Diff line number Diff line
@@ -361,7 +361,7 @@ static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast)

	init_completion(&mcast->done);

	ret = ib_sa_mcmember_rec_set(priv->ca, priv->port, &rec,
	ret = ib_sa_mcmember_rec_set(&ipoib_sa_client, priv->ca, priv->port, &rec,
				     IB_SA_MCMEMBER_REC_MGID		|
				     IB_SA_MCMEMBER_REC_PORT_GID	|
				     IB_SA_MCMEMBER_REC_PKEY		|
@@ -485,9 +485,9 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast,

	init_completion(&mcast->done);

	ret = ib_sa_mcmember_rec_set(priv->ca, priv->port, &rec, comp_mask,
				     mcast->backoff * 1000, GFP_ATOMIC,
				     ipoib_mcast_join_complete,
	ret = ib_sa_mcmember_rec_set(&ipoib_sa_client, priv->ca, priv->port,
				     &rec, comp_mask, mcast->backoff * 1000,
				     GFP_ATOMIC, ipoib_mcast_join_complete,
				     mcast, &mcast->query);

	if (ret < 0) {
@@ -681,7 +681,7 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
	 * Just make one shot at leaving and don't wait for a reply;
	 * if we fail, too bad.
	 */
	ret = ib_sa_mcmember_rec_delete(priv->ca, priv->port, &rec,
	ret = ib_sa_mcmember_rec_delete(&ipoib_sa_client, priv->ca, priv->port, &rec,
					IB_SA_MCMEMBER_REC_MGID		|
					IB_SA_MCMEMBER_REC_PORT_GID	|
					IB_SA_MCMEMBER_REC_PKEY		|
Loading