Commit ef5fcdb7 authored by Mark Zhang's avatar Mark Zhang Committed by Leon Romanovsky
Browse files

RDMA/sa_query: Add RMPP support for SA queries



Register GSI mad agent with RMPP support and add rmpp_callback for
SA queries. This is needed for querying more than one service record
in one query.

Signed-off-by: default avatarOr Har-Toov <ohartoov@nvidia.com>
Signed-off-by: default avatarMark Zhang <markzhang@nvidia.com>
Reviewed-by: default avatarVlad Dumitrescu <vdumitrescu@nvidia.com>
Link: https://patch.msgid.link/81dbcb48682e1838dc40f381cdcc0dc63f25f0f1.1751279793.git.leonro@nvidia.com


Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent 8f5ae30d
Loading
Loading
Loading
Loading
+28 −11
Original line number Diff line number Diff line
@@ -107,6 +107,8 @@ struct ib_sa_device {
struct ib_sa_query {
	void (*callback)(struct ib_sa_query *sa_query, int status,
			 struct ib_sa_mad *mad);
	void (*rmpp_callback)(struct ib_sa_query *sa_query, int status,
			      struct ib_mad_recv_wc *mad);
	void (*release)(struct ib_sa_query *);
	struct ib_sa_client    *client;
	struct ib_sa_port      *port;
@@ -1987,23 +1989,29 @@ static void send_handler(struct ib_mad_agent *agent,
{
	struct ib_sa_query *query = mad_send_wc->send_buf->context[0];
	unsigned long flags;
	int status = 0;

	if (query->callback)
	if (query->callback || query->rmpp_callback) {
		switch (mad_send_wc->status) {
		case IB_WC_SUCCESS:
			/* No callback -- already got recv */
			break;
		case IB_WC_RESP_TIMEOUT_ERR:
			query->callback(query, -ETIMEDOUT, NULL);
			status = -ETIMEDOUT;
			break;
		case IB_WC_WR_FLUSH_ERR:
			query->callback(query, -EINTR, NULL);
			status = -EINTR;
			break;
		default:
			query->callback(query, -EIO, NULL);
			status = -EIO;
			break;
		}

		if (status)
			query->callback ? query->callback(query, status, NULL) :
				query->rmpp_callback(query, status, NULL);
	}

	xa_lock_irqsave(&queries, flags);
	__xa_erase(&queries, query->id);
	xa_unlock_irqrestore(&queries, flags);
@@ -2019,17 +2027,25 @@ static void recv_handler(struct ib_mad_agent *mad_agent,
			 struct ib_mad_recv_wc *mad_recv_wc)
{
	struct ib_sa_query *query;
	struct ib_mad *mad;


	if (!send_buf)
		return;

	query = send_buf->context[0];
	if (query->callback) {
	mad = mad_recv_wc->recv_buf.mad;

	if (query->rmpp_callback) {
		if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
			query->rmpp_callback(query, mad->mad_hdr.status ?
					     -EINVAL : 0, mad_recv_wc);
		else
			query->rmpp_callback(query, -EIO, NULL);
	} else if (query->callback) {
		if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
			query->callback(query,
					mad_recv_wc->recv_buf.mad->mad_hdr.status ?
					-EINVAL : 0,
					(struct ib_sa_mad *) mad_recv_wc->recv_buf.mad);
			query->callback(query, mad->mad_hdr.status ?
					-EINVAL : 0, (struct ib_sa_mad *)mad);
		else
			query->callback(query, -EIO, NULL);
	}
@@ -2181,8 +2197,9 @@ static int ib_sa_add_one(struct ib_device *device)

		sa_dev->port[i].agent =
			ib_register_mad_agent(device, i + s, IB_QPT_GSI,
					      NULL, 0, send_handler,
					      recv_handler, sa_dev, 0);
					      NULL, IB_MGMT_RMPP_VERSION,
					      send_handler, recv_handler,
					      sa_dev, 0);
		if (IS_ERR(sa_dev->port[i].agent)) {
			ret = PTR_ERR(sa_dev->port[i].agent);
			goto err;