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/hns: Use refcount_t APIs for HEM

refcount_t is better than integer for reference counting, it will WARN on
overflow/underflow and avoid use-after-free risks.

Link: https://lore.kernel.org/r/1621589395-2435-5-git-send-email-liweihang@huawei.com
Signed-off-by: Weihang Li <liweihang@huawei.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

authored by

Weihang Li and committed by
Jason Gunthorpe
82eb481d 5e6370d7

+17 -19
+15 -17
drivers/infiniband/hw/hns/hns_roce_hem.c
··· 271 271 if (!hem) 272 272 return NULL; 273 273 274 - hem->refcount = 0; 275 274 INIT_LIST_HEAD(&hem->chunk_list); 276 275 277 276 order = get_order(hem_alloc_size); ··· 617 618 618 619 mutex_lock(&table->mutex); 619 620 if (table->hem[index.buf]) { 620 - ++table->hem[index.buf]->refcount; 621 + refcount_inc(&table->hem[index.buf]->refcount); 621 622 goto out; 622 623 } 623 624 ··· 636 637 } 637 638 } 638 639 639 - ++table->hem[index.buf]->refcount; 640 + refcount_set(&table->hem[index.buf]->refcount, 1); 640 641 goto out; 641 642 642 643 err_alloc: ··· 662 663 mutex_lock(&table->mutex); 663 664 664 665 if (table->hem[i]) { 665 - ++table->hem[i]->refcount; 666 + refcount_inc(&table->hem[i]->refcount); 666 667 goto out; 667 668 } 668 669 ··· 685 686 goto out; 686 687 } 687 688 688 - ++table->hem[i]->refcount; 689 + refcount_set(&table->hem[i]->refcount, 1); 689 690 out: 690 691 mutex_unlock(&table->mutex); 691 692 return ret; ··· 752 753 return; 753 754 } 754 755 755 - mutex_lock(&table->mutex); 756 - if (check_refcount && (--table->hem[index.buf]->refcount > 0)) { 757 - mutex_unlock(&table->mutex); 756 + if (!check_refcount) 757 + mutex_lock(&table->mutex); 758 + else if (!refcount_dec_and_mutex_lock(&table->hem[index.buf]->refcount, 759 + &table->mutex)) 758 760 return; 759 - } 760 761 761 762 clear_mhop_hem(hr_dev, table, obj, &mhop, &index); 762 763 free_mhop_hem(hr_dev, table, &mhop, &index); ··· 778 779 i = (obj & (table->num_obj - 1)) / 779 780 (table->table_chunk_size / table->obj_size); 780 781 781 - mutex_lock(&table->mutex); 782 + if (!refcount_dec_and_mutex_lock(&table->hem[i]->refcount, 783 + &table->mutex)) 784 + return; 782 785 783 - if (--table->hem[i]->refcount == 0) { 784 - /* Clear HEM base address */ 785 - if (hr_dev->hw->clear_hem(hr_dev, table, obj, 0)) 786 - dev_warn(dev, "Clear HEM base address failed.\n"); 786 + if (hr_dev->hw->clear_hem(hr_dev, table, obj, 0)) 787 + dev_warn(dev, "failed to clear HEM base address.\n"); 787 788 788 - hns_roce_free_hem(hr_dev, table->hem[i]); 789 - table->hem[i] = NULL; 790 - } 789 + hns_roce_free_hem(hr_dev, table->hem[i]); 790 + table->hem[i] = NULL; 791 791 792 792 mutex_unlock(&table->mutex); 793 793 }
+2 -2
drivers/infiniband/hw/hns/hns_roce_hem.h
··· 88 88 }; 89 89 90 90 struct hns_roce_hem { 91 - struct list_head chunk_list; 92 - int refcount; 91 + struct list_head chunk_list; 92 + refcount_t refcount; 93 93 }; 94 94 95 95 struct hns_roce_hem_iter {