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.

RDMA/efa: Fix use of completion ctx after free

On admin queue completion handling, if the admin command completed with
error we print data from the completion context. The issue is that we
already freed the completion context in polling/interrupts handler which
means we print data from context in an unknown state (it might be
already used again).
Change the admin submission flow so alloc/dealloc of the context will be
symmetric and dealloc will be called after any potential use of the
context.

Fixes: 68fb9f3e312a ("RDMA/efa: Remove redundant NULL pointer check of CQE")
Reviewed-by: Daniel Kranzdorf <dkkranzd@amazon.com>
Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Signed-off-by: Yonatan Nachum <ynachum@amazon.com>
Link: https://patch.msgid.link/20260308165350.18219-1-ynachum@amazon.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>

authored by

Yonatan Nachum and committed by
Leon Romanovsky
ef3b0674 c242e92c

+39 -48
+39 -48
drivers/infiniband/hw/efa/efa_com.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause 2 2 /* 3 - * Copyright 2018-2025 Amazon.com, Inc. or its affiliates. All rights reserved. 3 + * Copyright 2018-2026 Amazon.com, Inc. or its affiliates. All rights reserved. 4 4 */ 5 5 6 6 #include <linux/log2.h> ··· 310 310 return &aq->comp_ctx[ctx_id]; 311 311 } 312 312 313 - static struct efa_comp_ctx *__efa_com_submit_admin_cmd(struct efa_com_admin_queue *aq, 314 - struct efa_admin_aq_entry *cmd, 315 - size_t cmd_size_in_bytes, 316 - struct efa_admin_acq_entry *comp, 317 - size_t comp_size_in_bytes) 313 + static void __efa_com_submit_admin_cmd(struct efa_com_admin_queue *aq, 314 + struct efa_comp_ctx *comp_ctx, 315 + struct efa_admin_aq_entry *cmd, 316 + size_t cmd_size_in_bytes, 317 + struct efa_admin_acq_entry *comp, 318 + size_t comp_size_in_bytes) 318 319 { 319 320 struct efa_admin_aq_entry *aqe; 320 - struct efa_comp_ctx *comp_ctx; 321 321 u16 queue_size_mask; 322 322 u16 cmd_id; 323 323 u16 ctx_id; 324 324 u16 pi; 325 - 326 - comp_ctx = efa_com_alloc_comp_ctx(aq); 327 - if (!comp_ctx) 328 - return ERR_PTR(-EINVAL); 329 325 330 326 queue_size_mask = aq->depth - 1; 331 327 pi = aq->sq.pc & queue_size_mask; ··· 356 360 357 361 /* barrier not needed in case of writel */ 358 362 writel(aq->sq.pc, aq->sq.db_addr); 359 - 360 - return comp_ctx; 361 363 } 362 364 363 365 static inline int efa_com_init_comp_ctxt(struct efa_com_admin_queue *aq) ··· 388 394 return 0; 389 395 } 390 396 391 - static struct efa_comp_ctx *efa_com_submit_admin_cmd(struct efa_com_admin_queue *aq, 392 - struct efa_admin_aq_entry *cmd, 393 - size_t cmd_size_in_bytes, 394 - struct efa_admin_acq_entry *comp, 395 - size_t comp_size_in_bytes) 397 + static int efa_com_submit_admin_cmd(struct efa_com_admin_queue *aq, 398 + struct efa_comp_ctx *comp_ctx, 399 + struct efa_admin_aq_entry *cmd, 400 + size_t cmd_size_in_bytes, 401 + struct efa_admin_acq_entry *comp, 402 + size_t comp_size_in_bytes) 396 403 { 397 - struct efa_comp_ctx *comp_ctx; 398 - 399 404 spin_lock(&aq->sq.lock); 400 405 if (!test_bit(EFA_AQ_STATE_RUNNING_BIT, &aq->state)) { 401 406 ibdev_err_ratelimited(aq->efa_dev, "Admin queue is closed\n"); 402 407 spin_unlock(&aq->sq.lock); 403 - return ERR_PTR(-ENODEV); 408 + return -ENODEV; 404 409 } 405 410 406 - comp_ctx = __efa_com_submit_admin_cmd(aq, cmd, cmd_size_in_bytes, comp, 407 - comp_size_in_bytes); 411 + __efa_com_submit_admin_cmd(aq, comp_ctx, cmd, cmd_size_in_bytes, comp, 412 + comp_size_in_bytes); 408 413 spin_unlock(&aq->sq.lock); 409 - if (IS_ERR(comp_ctx)) 410 - clear_bit(EFA_AQ_STATE_RUNNING_BIT, &aq->state); 411 414 412 - return comp_ctx; 415 + return 0; 413 416 } 414 417 415 418 static int efa_com_handle_single_admin_completion(struct efa_com_admin_queue *aq, ··· 503 512 { 504 513 unsigned long timeout; 505 514 unsigned long flags; 506 - int err; 507 515 508 516 timeout = jiffies + usecs_to_jiffies(aq->completion_timeout); 509 517 ··· 522 532 atomic64_inc(&aq->stats.no_completion); 523 533 524 534 clear_bit(EFA_AQ_STATE_RUNNING_BIT, &aq->state); 525 - err = -ETIME; 526 - goto out; 535 + return -ETIME; 527 536 } 528 537 529 538 msleep(aq->poll_interval); 530 539 } 531 540 532 - err = efa_com_comp_status_to_errno(comp_ctx->user_cqe->acq_common_descriptor.status); 533 - out: 534 - efa_com_dealloc_comp_ctx(aq, comp_ctx); 535 - return err; 541 + return efa_com_comp_status_to_errno( 542 + comp_ctx->user_cqe->acq_common_descriptor.status); 536 543 } 537 544 538 545 static int efa_com_wait_and_process_admin_cq_interrupts(struct efa_comp_ctx *comp_ctx, 539 546 struct efa_com_admin_queue *aq) 540 547 { 541 548 unsigned long flags; 542 - int err; 543 549 544 550 wait_for_completion_timeout(&comp_ctx->wait_event, 545 551 usecs_to_jiffies(aq->completion_timeout)); ··· 571 585 aq->cq.cc); 572 586 573 587 clear_bit(EFA_AQ_STATE_RUNNING_BIT, &aq->state); 574 - err = -ETIME; 575 - goto out; 588 + return -ETIME; 576 589 } 577 590 578 - err = efa_com_comp_status_to_errno(comp_ctx->user_cqe->acq_common_descriptor.status); 579 - out: 580 - efa_com_dealloc_comp_ctx(aq, comp_ctx); 581 - return err; 591 + return efa_com_comp_status_to_errno( 592 + comp_ctx->user_cqe->acq_common_descriptor.status); 582 593 } 583 594 584 595 /* ··· 625 642 ibdev_dbg(aq->efa_dev, "%s (opcode %d)\n", 626 643 efa_com_cmd_str(cmd->aq_common_descriptor.opcode), 627 644 cmd->aq_common_descriptor.opcode); 628 - comp_ctx = efa_com_submit_admin_cmd(aq, cmd, cmd_size, comp, comp_size); 629 - if (IS_ERR(comp_ctx)) { 645 + 646 + comp_ctx = efa_com_alloc_comp_ctx(aq); 647 + if (!comp_ctx) { 648 + clear_bit(EFA_AQ_STATE_RUNNING_BIT, &aq->state); 649 + return -EINVAL; 650 + } 651 + 652 + err = efa_com_submit_admin_cmd(aq, comp_ctx, cmd, cmd_size, comp, comp_size); 653 + if (err) { 630 654 ibdev_err_ratelimited( 631 655 aq->efa_dev, 632 - "Failed to submit command %s (opcode %u) err %pe\n", 656 + "Failed to submit command %s (opcode %u) err %d\n", 633 657 efa_com_cmd_str(cmd->aq_common_descriptor.opcode), 634 - cmd->aq_common_descriptor.opcode, comp_ctx); 658 + cmd->aq_common_descriptor.opcode, err); 635 659 660 + efa_com_dealloc_comp_ctx(aq, comp_ctx); 636 661 up(&aq->avail_cmds); 637 662 atomic64_inc(&aq->stats.cmd_err); 638 - return PTR_ERR(comp_ctx); 663 + return err; 639 664 } 640 665 641 666 err = efa_com_wait_and_process_admin_cq(comp_ctx, aq); 642 667 if (err) { 643 668 ibdev_err_ratelimited( 644 669 aq->efa_dev, 645 - "Failed to process command %s (opcode %u) comp_status %d err %d\n", 670 + "Failed to process command %s (opcode %u) err %d\n", 646 671 efa_com_cmd_str(cmd->aq_common_descriptor.opcode), 647 - cmd->aq_common_descriptor.opcode, 648 - comp_ctx->user_cqe->acq_common_descriptor.status, err); 672 + cmd->aq_common_descriptor.opcode, err); 649 673 atomic64_inc(&aq->stats.cmd_err); 650 674 } 651 675 676 + efa_com_dealloc_comp_ctx(aq, comp_ctx); 652 677 up(&aq->avail_cmds); 653 678 654 679 return err;