aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core
diff options
context:
space:
mode:
authorAlexander Chiang <achiang@hp.com>2010-02-02 14:08:09 -0500
committerRoland Dreier <rolandd@cisco.com>2010-02-24 13:23:41 -0500
commit6d6a0e71eec5886f2511632a38f28f1ed7794d70 (patch)
treef00a26094daa8b221e9f2075be1206e4219f8a65 /drivers/infiniband/core
parentddbd6883013dcc9f9ca5c0b26f79d9334a95926c (diff)
IB/uverbs: Increase maximum devices supported
Some large systems may support more than IB_UVERBS_MAX_DEVICES (currently 32). This change allows us to support more devices in a backwards-compatible manner. The first IB_UVERBS_MAX_DEVICES keep the same major/minor device numbers that they've always had. If there are more than IB_UVERBS_MAX_DEVICES, we then dynamically request a new major device number (new minors start at 0). This change increases the maximum number of HCAs to 64 (from 32). Signed-off-by: Alex Chiang <achiang@hp.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r--drivers/infiniband/core/uverbs_main.c56
1 files changed, 50 insertions, 6 deletions
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 8c594cde8a1..7d42d550e87 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -728,6 +728,34 @@ static ssize_t show_abi_version(struct class *class, char *buf)
728} 728}
729static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); 729static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
730 730
731static dev_t overflow_maj;
732static DECLARE_BITMAP(overflow_map, IB_UVERBS_MAX_DEVICES);
733
734/*
735 * If we have more than IB_UVERBS_MAX_DEVICES, dynamically overflow by
736 * requesting a new major number and doubling the number of max devices we
737 * support. It's stupid, but simple.
738 */
739static int find_overflow_devnum(void)
740{
741 int ret;
742
743 if (!overflow_maj) {
744 ret = alloc_chrdev_region(&overflow_maj, 0, IB_UVERBS_MAX_DEVICES,
745 "infiniband_verbs");
746 if (ret) {
747 printk(KERN_ERR "user_verbs: couldn't register dynamic device number\n");
748 return ret;
749 }
750 }
751
752 ret = find_first_zero_bit(overflow_map, IB_UVERBS_MAX_DEVICES);
753 if (ret >= IB_UVERBS_MAX_DEVICES)
754 return -1;
755
756 return ret;
757}
758
731static void ib_uverbs_add_one(struct ib_device *device) 759static void ib_uverbs_add_one(struct ib_device *device)
732{ 760{
733 int devnum; 761 int devnum;
@@ -748,11 +776,19 @@ static void ib_uverbs_add_one(struct ib_device *device)
748 devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES); 776 devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES);
749 if (devnum >= IB_UVERBS_MAX_DEVICES) { 777 if (devnum >= IB_UVERBS_MAX_DEVICES) {
750 spin_unlock(&map_lock); 778 spin_unlock(&map_lock);
751 goto err; 779 devnum = find_overflow_devnum();
780 if (devnum < 0)
781 goto err;
782
783 spin_lock(&map_lock);
784 uverbs_dev->devnum = devnum + IB_UVERBS_MAX_DEVICES;
785 base = devnum + overflow_maj;
786 set_bit(devnum, overflow_map);
787 } else {
788 uverbs_dev->devnum = devnum;
789 base = devnum + IB_UVERBS_BASE_DEV;
790 set_bit(devnum, dev_map);
752 } 791 }
753 uverbs_dev->devnum = devnum;
754 base = devnum + IB_UVERBS_BASE_DEV;
755 set_bit(devnum, dev_map);
756 spin_unlock(&map_lock); 792 spin_unlock(&map_lock);
757 793
758 uverbs_dev->ib_dev = device; 794 uverbs_dev->ib_dev = device;
@@ -785,7 +821,10 @@ err_class:
785 821
786err_cdev: 822err_cdev:
787 cdev_del(&uverbs_dev->cdev); 823 cdev_del(&uverbs_dev->cdev);
788 clear_bit(devnum, dev_map); 824 if (uverbs_dev->devnum < IB_UVERBS_MAX_DEVICES)
825 clear_bit(devnum, dev_map);
826 else
827 clear_bit(devnum, overflow_map);
789 828
790err: 829err:
791 kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); 830 kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
@@ -805,7 +844,10 @@ static void ib_uverbs_remove_one(struct ib_device *device)
805 device_destroy(uverbs_class, uverbs_dev->cdev.dev); 844 device_destroy(uverbs_class, uverbs_dev->cdev.dev);
806 cdev_del(&uverbs_dev->cdev); 845 cdev_del(&uverbs_dev->cdev);
807 846
808 clear_bit(uverbs_dev->devnum, dev_map); 847 if (uverbs_dev->devnum < IB_UVERBS_MAX_DEVICES)
848 clear_bit(uverbs_dev->devnum, dev_map);
849 else
850 clear_bit(uverbs_dev->devnum - IB_UVERBS_MAX_DEVICES, overflow_map);
809 851
810 kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); 852 kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
811 wait_for_completion(&uverbs_dev->comp); 853 wait_for_completion(&uverbs_dev->comp);
@@ -895,6 +937,8 @@ static void __exit ib_uverbs_cleanup(void)
895 unregister_filesystem(&uverbs_event_fs); 937 unregister_filesystem(&uverbs_event_fs);
896 class_destroy(uverbs_class); 938 class_destroy(uverbs_class);
897 unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); 939 unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
940 if (overflow_maj)
941 unregister_chrdev_region(overflow_maj, IB_UVERBS_MAX_DEVICES);
898 idr_destroy(&ib_uverbs_pd_idr); 942 idr_destroy(&ib_uverbs_pd_idr);
899 idr_destroy(&ib_uverbs_mr_idr); 943 idr_destroy(&ib_uverbs_mr_idr);
900 idr_destroy(&ib_uverbs_mw_idr); 944 idr_destroy(&ib_uverbs_mw_idr);