1
votes

What is the use of the below structure and function in designing drivers for IB?

struct ib_sa_client {
    atomic_t users;
    struct completion comp;
};

/**
 * ib_sa_register_client - Register an SA client.
 */
void ib_sa_register_client(struct ib_sa_client *client);

It will very kind of someone to explain these.

1
Please change the title to match the question. - Tgilgul

1 Answers

3
votes

This is used for reference counting / lifetime handling for higher-level drivers that want to do SA (Subnet Administrator) queries. SA queries include path record or service record lookups — basically anything where a query is sent to the subnet manager to get information about other entities on the fabric.

These queries are done with functions like ib_sa_path_rec_get, and the first parameter to those functions is a pointer to a struct ib_sa_client. This is needed because those queries are network messages to the subnet manager, and we need to wait for a response, so the query function also takes a callback parameter. We don't want dangling callbacks if, say, the user removes the module that started the SA query.

So the IB core prevents ib_sa_unregister_client from returning until all pending queries are finished; any module that does SA queries needs to call the unregister function on its cleanup path. This protects the kernel from having a query finish after the module that started it is removed, which would lead to jumping to a callback function whose code is in freed memory.