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: Or Har-Toov <ohartoov@nvidia.com>
Signed-off-by: Mark Zhang <markzhang@nvidia.com>
Reviewed-by: Vlad Dumitrescu <vdumitrescu@nvidia.com>
Link: https://patch.msgid.link/81dbcb48682e1838dc40f381cdcc0dc63f25f0f1.1751279793.git.leonro@nvidia.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
Mark Zhang 2025-06-30 13:52:31 +03:00 committed by Leon Romanovsky
parent 8f5ae30d69
commit ef5fcdb730

View File

@ -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->callback(query,
mad_recv_wc->recv_buf.mad->mad_hdr.status ?
-EINVAL : 0,
(struct ib_sa_mad *) mad_recv_wc->recv_buf.mad);
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->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;