mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 13:23:02 -04:00
svcrdma: Handle ADDR_CHANGE CM event properly
Sagi tells me that when a bonded device reports an address change,
the consumer must destroy its listener IDs and create new ones.
See commit a032e4f6d6 ("nvmet-rdma: fix bonding failover possible
NULL deref").
Suggested-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
@@ -284,17 +284,31 @@ static void handle_connect_req(struct rdma_cm_id *new_cma_id,
|
|||||||
*
|
*
|
||||||
* Return values:
|
* Return values:
|
||||||
* %0: Do not destroy @cma_id
|
* %0: Do not destroy @cma_id
|
||||||
* %1: Destroy @cma_id (never returned here)
|
* %1: Destroy @cma_id
|
||||||
*
|
*
|
||||||
* NB: There is never a DEVICE_REMOVAL event for INADDR_ANY listeners.
|
* NB: There is never a DEVICE_REMOVAL event for INADDR_ANY listeners.
|
||||||
*/
|
*/
|
||||||
static int svc_rdma_listen_handler(struct rdma_cm_id *cma_id,
|
static int svc_rdma_listen_handler(struct rdma_cm_id *cma_id,
|
||||||
struct rdma_cm_event *event)
|
struct rdma_cm_event *event)
|
||||||
{
|
{
|
||||||
|
struct sockaddr *sap = (struct sockaddr *)&cma_id->route.addr.src_addr;
|
||||||
|
struct svcxprt_rdma *cma_xprt = cma_id->context;
|
||||||
|
struct svc_xprt *cma_rdma = &cma_xprt->sc_xprt;
|
||||||
|
struct rdma_cm_id *listen_id;
|
||||||
|
|
||||||
switch (event->event) {
|
switch (event->event) {
|
||||||
case RDMA_CM_EVENT_CONNECT_REQUEST:
|
case RDMA_CM_EVENT_CONNECT_REQUEST:
|
||||||
handle_connect_req(cma_id, &event->param.conn);
|
handle_connect_req(cma_id, &event->param.conn);
|
||||||
break;
|
break;
|
||||||
|
case RDMA_CM_EVENT_ADDR_CHANGE:
|
||||||
|
listen_id = svc_rdma_create_listen_id(cma_rdma->xpt_net,
|
||||||
|
sap, cma_xprt);
|
||||||
|
if (IS_ERR(listen_id)) {
|
||||||
|
pr_err("Listener dead, address change failed for device %s\n",
|
||||||
|
cma_id->device->name);
|
||||||
|
} else
|
||||||
|
cma_xprt->sc_cm_id = listen_id;
|
||||||
|
return 1;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user