Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

smb: server: make use of smbdirect_socket_{listen,accept}()

We no longer need the custom rdma listener.

The code logic is very similar to transport_tcp.c now
using a kernel thread that loops over smbdirect_socket_accept().

This is the first step in the direction of using IPPROTO_SMBDIRECT
sockets in future.

Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>

authored by

Stefan Metzmacher and committed by
Steve French
2eff5e51 1b2d94a3

+128 -132
+128 -132
fs/smb/server/transport_rdma.c
··· 89 89 90 90 static struct smb_direct_listener { 91 91 int port; 92 - struct rdma_cm_id *cm_id; 92 + 93 + struct task_struct *thread; 94 + 95 + struct smbdirect_socket *socket; 93 96 } smb_direct_ib_listener, smb_direct_iw_listener; 94 97 95 98 static struct workqueue_struct *smb_direct_wq; ··· 188 185 return sp->max_read_write_size; 189 186 } 190 187 191 - static struct smb_direct_transport *alloc_transport(struct rdma_cm_id *cm_id) 188 + static struct smb_direct_transport *alloc_transport(struct smbdirect_socket *sc) 192 189 { 193 190 struct smb_direct_transport *t; 194 - struct smbdirect_socket *sc; 195 - struct smbdirect_socket_parameters init_params = {}; 196 - struct smbdirect_socket_parameters *sp; 197 191 struct ksmbd_conn *conn; 198 - int ret; 199 - 200 - /* 201 - * Create the initial parameters 202 - */ 203 - sp = &init_params; 204 - sp->negotiate_timeout_msec = SMB_DIRECT_NEGOTIATE_TIMEOUT * 1000; 205 - sp->initiator_depth = SMB_DIRECT_CM_INITIATOR_DEPTH; 206 - sp->responder_resources = 1; 207 - sp->recv_credit_max = smb_direct_receive_credit_max; 208 - sp->send_credit_target = smb_direct_send_credit_target; 209 - sp->max_send_size = smb_direct_max_send_size; 210 - sp->max_fragmented_recv_size = smb_direct_max_fragmented_recv_size; 211 - sp->max_recv_size = smb_direct_max_receive_size; 212 - sp->max_read_write_size = smb_direct_max_read_write_size; 213 - sp->keepalive_interval_msec = SMB_DIRECT_KEEPALIVE_SEND_INTERVAL * 1000; 214 - sp->keepalive_timeout_msec = SMB_DIRECT_KEEPALIVE_RECV_TIMEOUT * 1000; 215 192 216 193 t = kzalloc_obj(*t, KSMBD_DEFAULT_GFP); 217 194 if (!t) 218 195 return NULL; 219 - ret = smbdirect_socket_create_accepting(cm_id, &sc); 220 - if (ret) 221 - goto socket_create_failed; 222 - smbdirect_socket_set_logging(sc, NULL, 223 - smb_direct_logging_needed, 224 - smb_direct_logging_vaprintf); 225 - ret = smbdirect_socket_set_initial_parameters(sc, sp); 226 - if (ret) 227 - goto set_params_failed; 228 - ret = smbdirect_socket_set_kernel_settings(sc, IB_POLL_WORKQUEUE, KSMBD_DEFAULT_GFP); 229 - if (ret) 230 - goto set_settings_failed; 231 - ret = smbdirect_socket_set_custom_workqueue(sc, smb_direct_wq); 232 - if (ret) 233 - goto set_workqueue_failed; 196 + t->socket = sc; 234 197 235 198 conn = ksmbd_conn_alloc(); 236 199 if (!conn) ··· 210 241 KSMBD_TRANS(t)->conn = conn; 211 242 KSMBD_TRANS(t)->ops = &ksmbd_smb_direct_transport_ops; 212 243 213 - t->socket = sc; 214 244 return t; 215 245 216 246 conn_alloc_failed: 217 - set_workqueue_failed: 218 - set_settings_failed: 219 - set_params_failed: 220 - smbdirect_socket_release(sc); 221 - socket_create_failed: 222 247 kfree(t); 223 248 return NULL; 224 249 } ··· 309 346 smbdirect_socket_shutdown(sc); 310 347 } 311 348 312 - static int smb_direct_prepare(struct ksmbd_transport *t) 349 + static int smb_direct_new_connection(struct smb_direct_listener *listener, 350 + struct smbdirect_socket *client_sc) 313 351 { 314 - struct smb_direct_transport *st = SMBD_TRANS(t); 315 - struct smbdirect_socket *sc = st->socket; 316 - int ret; 317 - 318 - ksmbd_debug(RDMA, "SMB_DIRECT Waiting for connection\n"); 319 - ret = smbdirect_connection_wait_for_connected(sc); 320 - if (ret) { 321 - ksmbd_debug(RDMA, "SMB_DIRECT connection failed %d => %1pe\n", 322 - ret, ERR_PTR(ret)); 323 - return ret; 324 - } 325 - 326 - ksmbd_debug(RDMA, "SMB_DIRECT connection ready\n"); 327 - return 0; 328 - } 329 - 330 - static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id, 331 - struct rdma_cm_event *event) 332 - { 333 - struct smb_direct_listener *listener = new_cm_id->context; 334 352 struct smb_direct_transport *t; 335 - struct smbdirect_socket *sc; 336 353 struct task_struct *handler; 337 354 int ret; 338 355 339 - if (!smbdirect_frwr_is_supported(&new_cm_id->device->attrs)) { 340 - ksmbd_debug(RDMA, 341 - "Fast Registration Work Requests is not supported. device capabilities=%llx\n", 342 - new_cm_id->device->attrs.device_cap_flags); 343 - return -EPROTONOSUPPORT; 344 - } 345 - 346 - t = alloc_transport(new_cm_id); 347 - if (!t) 356 + t = alloc_transport(client_sc); 357 + if (!t) { 358 + smbdirect_socket_release(client_sc); 348 359 return -ENOMEM; 349 - sc = t->socket; 350 - 351 - ret = smbdirect_accept_connect_request(sc, &event->param.conn); 352 - if (ret) 353 - goto out_err; 360 + } 354 361 355 362 handler = kthread_run(ksmbd_conn_handler_loop, 356 363 KSMBD_TRANS(t)->conn, "ksmbd:r%u", ··· 337 404 return ret; 338 405 } 339 406 340 - static int smb_direct_listen_handler(struct rdma_cm_id *cm_id, 341 - struct rdma_cm_event *event) 407 + static int smb_direct_listener_kthread_fn(void *p) 342 408 { 343 - switch (event->event) { 344 - case RDMA_CM_EVENT_CONNECT_REQUEST: { 345 - int ret = smb_direct_handle_connect_request(cm_id, event); 409 + struct smb_direct_listener *listener = (struct smb_direct_listener *)p; 410 + struct smbdirect_socket *client_sc = NULL; 346 411 347 - if (ret) { 348 - pr_err("Can't create transport: %d\n", ret); 349 - return ret; 350 - } 412 + while (!kthread_should_stop()) { 413 + struct proto_accept_arg arg = { .err = -EINVAL, }; 414 + long timeo = MAX_SCHEDULE_TIMEOUT; 351 415 352 - ksmbd_debug(RDMA, "Received connection request. cm_id=%p\n", 353 - cm_id); 354 - break; 416 + if (!listener->socket) 417 + break; 418 + client_sc = smbdirect_socket_accept(listener->socket, timeo, &arg); 419 + if (!client_sc && arg.err == -EINVAL) 420 + break; 421 + if (!client_sc) 422 + continue; 423 + 424 + ksmbd_debug(CONN, "connect success: accepted new connection\n"); 425 + smb_direct_new_connection(listener, client_sc); 355 426 } 356 - default: 357 - pr_err("Unexpected listen event. cm_id=%p, event=%s (%d)\n", 358 - cm_id, rdma_event_msg(event->event), event->event); 359 - break; 360 - } 427 + 428 + ksmbd_debug(CONN, "releasing socket\n"); 361 429 return 0; 430 + } 431 + 432 + static void smb_direct_listener_destroy(struct smb_direct_listener *listener) 433 + { 434 + int ret; 435 + 436 + if (listener->socket) 437 + smbdirect_socket_shutdown(listener->socket); 438 + 439 + if (listener->thread) { 440 + ret = kthread_stop(listener->thread); 441 + if (ret) 442 + pr_err("failed to stop forker thread\n"); 443 + listener->thread = NULL; 444 + } 445 + 446 + if (listener->socket) { 447 + smbdirect_socket_release(listener->socket); 448 + listener->socket = NULL; 449 + } 450 + 451 + listener->port = 0; 362 452 } 363 453 364 454 static int smb_direct_listen(struct smb_direct_listener *listener, 365 455 int port) 366 456 { 367 - int ret; 368 - struct rdma_cm_id *cm_id; 369 - u8 node_type = RDMA_NODE_UNSPECIFIED; 457 + struct net *net = current->nsproxy->net_ns; 458 + struct task_struct *kthread; 370 459 struct sockaddr_in sin = { 371 460 .sin_family = AF_INET, 372 461 .sin_addr.s_addr = htonl(INADDR_ANY), 373 462 .sin_port = htons(port), 374 463 }; 464 + struct smbdirect_socket_parameters init_params = {}; 465 + struct smbdirect_socket_parameters *sp; 466 + struct smbdirect_socket *sc; 467 + u64 port_flags = 0; 468 + int ret; 375 469 376 470 switch (port) { 377 471 case SMB_DIRECT_PORT_IWARP: ··· 406 446 * only allow iWarp devices 407 447 * for port 5445. 408 448 */ 409 - node_type = RDMA_NODE_RNIC; 449 + port_flags |= SMBDIRECT_FLAG_PORT_RANGE_ONLY_IW; 410 450 break; 411 451 case SMB_DIRECT_PORT_INFINIBAND: 412 452 /* ··· 415 455 * 416 456 * (Basically don't allow iWarp devices) 417 457 */ 418 - node_type = RDMA_NODE_IB_CA; 458 + port_flags |= SMBDIRECT_FLAG_PORT_RANGE_ONLY_IB; 419 459 break; 420 460 default: 421 461 pr_err("unsupported smbdirect port=%d!\n", port); 422 462 return -ENODEV; 423 463 } 424 464 425 - cm_id = rdma_create_id(&init_net, smb_direct_listen_handler, 426 - listener, RDMA_PS_TCP, IB_QPT_RC); 427 - if (IS_ERR(cm_id)) { 428 - pr_err("Can't create cm id: %ld\n", PTR_ERR(cm_id)); 429 - return PTR_ERR(cm_id); 465 + ret = smbdirect_socket_create_kern(net, &sc); 466 + if (ret) { 467 + pr_err("smbdirect_socket_create_kern() failed: %d %1pe\n", 468 + ret, ERR_PTR(ret)); 469 + return ret; 430 470 } 431 471 432 - ret = rdma_restrict_node_type(cm_id, node_type); 472 + /* 473 + * Create the initial parameters 474 + */ 475 + sp = &init_params; 476 + sp->flags |= port_flags; 477 + sp->negotiate_timeout_msec = SMB_DIRECT_NEGOTIATE_TIMEOUT * 1000; 478 + sp->initiator_depth = SMB_DIRECT_CM_INITIATOR_DEPTH; 479 + sp->responder_resources = 1; 480 + sp->recv_credit_max = smb_direct_receive_credit_max; 481 + sp->send_credit_target = smb_direct_send_credit_target; 482 + sp->max_send_size = smb_direct_max_send_size; 483 + sp->max_fragmented_recv_size = smb_direct_max_fragmented_recv_size; 484 + sp->max_recv_size = smb_direct_max_receive_size; 485 + sp->max_read_write_size = smb_direct_max_read_write_size; 486 + sp->keepalive_interval_msec = SMB_DIRECT_KEEPALIVE_SEND_INTERVAL * 1000; 487 + sp->keepalive_timeout_msec = SMB_DIRECT_KEEPALIVE_RECV_TIMEOUT * 1000; 488 + 489 + smbdirect_socket_set_logging(sc, NULL, 490 + smb_direct_logging_needed, 491 + smb_direct_logging_vaprintf); 492 + ret = smbdirect_socket_set_initial_parameters(sc, sp); 433 493 if (ret) { 434 - pr_err("rdma_restrict_node_type(%u) failed %d\n", 435 - node_type, ret); 494 + pr_err("Failed smbdirect_socket_set_initial_parameters(): %d %1pe\n", 495 + ret, ERR_PTR(ret)); 496 + goto err; 497 + } 498 + ret = smbdirect_socket_set_kernel_settings(sc, IB_POLL_WORKQUEUE, KSMBD_DEFAULT_GFP); 499 + if (ret) { 500 + pr_err("Failed smbdirect_socket_set_kernel_settings(): %d %1pe\n", 501 + ret, ERR_PTR(ret)); 502 + goto err; 503 + } 504 + ret = smbdirect_socket_set_custom_workqueue(sc, smb_direct_wq); 505 + if (ret) { 506 + pr_err("Failed smbdirect_socket_set_custom_workqueue(): %d %1pe\n", 507 + ret, ERR_PTR(ret)); 436 508 goto err; 437 509 } 438 510 439 - ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin); 511 + ret = smbdirect_socket_bind(sc, (struct sockaddr *)&sin); 440 512 if (ret) { 441 - pr_err("Can't bind: %d\n", ret); 513 + pr_err("smbdirect_socket_bind() failed: %d %1pe\n", 514 + ret, ERR_PTR(ret)); 442 515 goto err; 443 516 } 444 517 445 - ret = rdma_listen(cm_id, 10); 518 + ret = smbdirect_socket_listen(sc, 10); 446 519 if (ret) { 447 - pr_err("Can't listen: %d\n", ret); 520 + pr_err("Port[%d] smbdirect_socket_listen() failed: %d %1pe\n", 521 + port, ret, ERR_PTR(ret)); 448 522 goto err; 449 523 } 450 524 451 525 listener->port = port; 452 - listener->cm_id = cm_id; 526 + listener->socket = sc; 453 527 528 + kthread = kthread_run(smb_direct_listener_kthread_fn, 529 + listener, 530 + "ksmbd-smbdirect-listener-%u", port); 531 + if (IS_ERR(kthread)) { 532 + ret = PTR_ERR(kthread); 533 + pr_err("Can't start ksmbd listen kthread: %d %1pe\n", 534 + ret, ERR_PTR(ret)); 535 + goto err; 536 + } 537 + 538 + listener->thread = kthread; 454 539 return 0; 455 540 err: 456 - listener->port = 0; 457 - listener->cm_id = NULL; 458 - rdma_destroy_id(cm_id); 541 + smb_direct_listener_destroy(listener); 459 542 return ret; 460 543 } 461 544 ··· 549 546 int ret; 550 547 551 548 smb_direct_ib_listener = smb_direct_iw_listener = (struct smb_direct_listener) { 552 - .cm_id = NULL, 549 + .socket = NULL, 553 550 }; 554 551 555 552 ret = ib_register_client(&smb_direct_ib_client); ··· 578 575 goto err; 579 576 } 580 577 581 - ksmbd_debug(RDMA, "InfiniBand/RoCEv1/RoCEv2 RDMA listener. cm_id=%p\n", 582 - smb_direct_ib_listener.cm_id); 578 + ksmbd_debug(RDMA, "InfiniBand/RoCEv1/RoCEv2 RDMA listener. socket=%p\n", 579 + smb_direct_ib_listener.socket); 583 580 584 581 ret = smb_direct_listen(&smb_direct_iw_listener, 585 582 SMB_DIRECT_PORT_IWARP); ··· 588 585 goto err; 589 586 } 590 587 591 - ksmbd_debug(RDMA, "iWarp RDMA listener. cm_id=%p\n", 592 - smb_direct_iw_listener.cm_id); 588 + ksmbd_debug(RDMA, "iWarp RDMA listener. socket=%p\n", 589 + smb_direct_iw_listener.socket); 593 590 594 591 return 0; 595 592 err: ··· 600 597 601 598 void ksmbd_rdma_stop_listening(void) 602 599 { 603 - if (!smb_direct_ib_listener.cm_id && !smb_direct_iw_listener.cm_id) 600 + if (!smb_direct_ib_listener.socket && !smb_direct_iw_listener.socket) 604 601 return; 605 602 606 603 ib_unregister_client(&smb_direct_ib_client); 607 604 608 - if (smb_direct_ib_listener.cm_id) 609 - rdma_destroy_id(smb_direct_ib_listener.cm_id); 610 - if (smb_direct_iw_listener.cm_id) 611 - rdma_destroy_id(smb_direct_iw_listener.cm_id); 612 - 613 - smb_direct_ib_listener = smb_direct_iw_listener = (struct smb_direct_listener) { 614 - .cm_id = NULL, 615 - }; 605 + smb_direct_listener_destroy(&smb_direct_ib_listener); 606 + smb_direct_listener_destroy(&smb_direct_iw_listener); 616 607 } 617 608 618 609 void ksmbd_rdma_destroy(void) ··· 682 685 } 683 686 684 687 static const struct ksmbd_transport_ops ksmbd_smb_direct_transport_ops = { 685 - .prepare = smb_direct_prepare, 686 688 .disconnect = smb_direct_disconnect, 687 689 .shutdown = smb_direct_shutdown, 688 690 .writev = smb_direct_writev,