diff options
| -rw-r--r-- | drivers/infiniband/core/ucm.c | 63 | ||||
| -rw-r--r-- | drivers/infiniband/core/user_mad.c | 173 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs.h | 11 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 175 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/cxio_hal.c | 15 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/cxio_hal.h | 4 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/cxio_wr.h | 17 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch.c | 80 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch.h | 2 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_provider.c | 2 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_qp.c | 9 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ehca/ehca_irq.c | 5 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ehca/ehca_qp.c | 4 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ehca/ehca_sqp.c | 2 | ||||
| -rw-r--r-- | drivers/net/cxgb3/adapter.h | 5 | ||||
| -rw-r--r-- | drivers/net/cxgb3/cxgb3_main.c | 57 | ||||
| -rw-r--r-- | drivers/net/cxgb3/cxgb3_offload.h | 5 | ||||
| -rw-r--r-- | drivers/net/cxgb3/regs.h | 16 | ||||
| -rw-r--r-- | drivers/net/cxgb3/sge.c | 10 | ||||
| -rw-r--r-- | drivers/net/cxgb3/t3_hw.c | 5 | ||||
| -rw-r--r-- | include/rdma/ib_verbs.h | 4 | ||||
| -rw-r--r-- | include/rdma/rdma_cm.h | 1 |
22 files changed, 462 insertions, 203 deletions
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index f504c9b00c1b..1b09b735c5a8 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c | |||
| @@ -1215,15 +1215,18 @@ static void ib_ucm_release_dev(struct device *dev) | |||
| 1215 | 1215 | ||
| 1216 | ucm_dev = container_of(dev, struct ib_ucm_device, dev); | 1216 | ucm_dev = container_of(dev, struct ib_ucm_device, dev); |
| 1217 | cdev_del(&ucm_dev->cdev); | 1217 | cdev_del(&ucm_dev->cdev); |
| 1218 | clear_bit(ucm_dev->devnum, dev_map); | 1218 | if (ucm_dev->devnum < IB_UCM_MAX_DEVICES) |
| 1219 | clear_bit(ucm_dev->devnum, dev_map); | ||
| 1220 | else | ||
| 1221 | clear_bit(ucm_dev->devnum - IB_UCM_MAX_DEVICES, dev_map); | ||
| 1219 | kfree(ucm_dev); | 1222 | kfree(ucm_dev); |
| 1220 | } | 1223 | } |
| 1221 | 1224 | ||
| 1222 | static const struct file_operations ucm_fops = { | 1225 | static const struct file_operations ucm_fops = { |
| 1223 | .owner = THIS_MODULE, | 1226 | .owner = THIS_MODULE, |
| 1224 | .open = ib_ucm_open, | 1227 | .open = ib_ucm_open, |
| 1225 | .release = ib_ucm_close, | 1228 | .release = ib_ucm_close, |
| 1226 | .write = ib_ucm_write, | 1229 | .write = ib_ucm_write, |
| 1227 | .poll = ib_ucm_poll, | 1230 | .poll = ib_ucm_poll, |
| 1228 | }; | 1231 | }; |
| 1229 | 1232 | ||
| @@ -1237,8 +1240,32 @@ static ssize_t show_ibdev(struct device *dev, struct device_attribute *attr, | |||
| 1237 | } | 1240 | } |
| 1238 | static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); | 1241 | static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); |
| 1239 | 1242 | ||
| 1243 | static dev_t overflow_maj; | ||
| 1244 | static DECLARE_BITMAP(overflow_map, IB_UCM_MAX_DEVICES); | ||
| 1245 | static int find_overflow_devnum(void) | ||
| 1246 | { | ||
| 1247 | int ret; | ||
| 1248 | |||
| 1249 | if (!overflow_maj) { | ||
| 1250 | ret = alloc_chrdev_region(&overflow_maj, 0, IB_UCM_MAX_DEVICES, | ||
| 1251 | "infiniband_cm"); | ||
| 1252 | if (ret) { | ||
| 1253 | printk(KERN_ERR "ucm: couldn't register dynamic device number\n"); | ||
| 1254 | return ret; | ||
| 1255 | } | ||
| 1256 | } | ||
| 1257 | |||
| 1258 | ret = find_first_zero_bit(overflow_map, IB_UCM_MAX_DEVICES); | ||
| 1259 | if (ret >= IB_UCM_MAX_DEVICES) | ||
| 1260 | return -1; | ||
| 1261 | |||
| 1262 | return ret; | ||
| 1263 | } | ||
| 1264 | |||
| 1240 | static void ib_ucm_add_one(struct ib_device *device) | 1265 | static void ib_ucm_add_one(struct ib_device *device) |
| 1241 | { | 1266 | { |
| 1267 | int devnum; | ||
| 1268 | dev_t base; | ||
| 1242 | struct ib_ucm_device *ucm_dev; | 1269 | struct ib_ucm_device *ucm_dev; |
| 1243 | 1270 | ||
| 1244 | if (!device->alloc_ucontext || | 1271 | if (!device->alloc_ucontext || |
| @@ -1251,16 +1278,25 @@ static void ib_ucm_add_one(struct ib_device *device) | |||
| 1251 | 1278 | ||
| 1252 | ucm_dev->ib_dev = device; | 1279 | ucm_dev->ib_dev = device; |
| 1253 | 1280 | ||
| 1254 | ucm_dev->devnum = find_first_zero_bit(dev_map, IB_UCM_MAX_DEVICES); | 1281 | devnum = find_first_zero_bit(dev_map, IB_UCM_MAX_DEVICES); |
| 1255 | if (ucm_dev->devnum >= IB_UCM_MAX_DEVICES) | 1282 | if (devnum >= IB_UCM_MAX_DEVICES) { |
| 1256 | goto err; | 1283 | devnum = find_overflow_devnum(); |
| 1257 | 1284 | if (devnum < 0) | |
| 1258 | set_bit(ucm_dev->devnum, dev_map); | 1285 | goto err; |
| 1286 | |||
| 1287 | ucm_dev->devnum = devnum + IB_UCM_MAX_DEVICES; | ||
| 1288 | base = devnum + overflow_maj; | ||
| 1289 | set_bit(devnum, overflow_map); | ||
| 1290 | } else { | ||
| 1291 | ucm_dev->devnum = devnum; | ||
| 1292 | base = devnum + IB_UCM_BASE_DEV; | ||
| 1293 | set_bit(devnum, dev_map); | ||
| 1294 | } | ||
| 1259 | 1295 | ||
| 1260 | cdev_init(&ucm_dev->cdev, &ucm_fops); | 1296 | cdev_init(&ucm_dev->cdev, &ucm_fops); |
| 1261 | ucm_dev->cdev.owner = THIS_MODULE; | 1297 | ucm_dev->cdev.owner = THIS_MODULE; |
| 1262 | kobject_set_name(&ucm_dev->cdev.kobj, "ucm%d", ucm_dev->devnum); | 1298 | kobject_set_name(&ucm_dev->cdev.kobj, "ucm%d", ucm_dev->devnum); |
| 1263 | if (cdev_add(&ucm_dev->cdev, IB_UCM_BASE_DEV + ucm_dev->devnum, 1)) | 1299 | if (cdev_add(&ucm_dev->cdev, base, 1)) |
| 1264 | goto err; | 1300 | goto err; |
| 1265 | 1301 | ||
| 1266 | ucm_dev->dev.class = &cm_class; | 1302 | ucm_dev->dev.class = &cm_class; |
| @@ -1281,7 +1317,10 @@ err_dev: | |||
| 1281 | device_unregister(&ucm_dev->dev); | 1317 | device_unregister(&ucm_dev->dev); |
| 1282 | err_cdev: | 1318 | err_cdev: |
| 1283 | cdev_del(&ucm_dev->cdev); | 1319 | cdev_del(&ucm_dev->cdev); |
| 1284 | clear_bit(ucm_dev->devnum, dev_map); | 1320 | if (ucm_dev->devnum < IB_UCM_MAX_DEVICES) |
| 1321 | clear_bit(devnum, dev_map); | ||
| 1322 | else | ||
| 1323 | clear_bit(devnum, overflow_map); | ||
| 1285 | err: | 1324 | err: |
| 1286 | kfree(ucm_dev); | 1325 | kfree(ucm_dev); |
| 1287 | return; | 1326 | return; |
| @@ -1340,6 +1379,8 @@ static void __exit ib_ucm_cleanup(void) | |||
| 1340 | ib_unregister_client(&ucm_client); | 1379 | ib_unregister_client(&ucm_client); |
| 1341 | class_remove_file(&cm_class, &class_attr_abi_version); | 1380 | class_remove_file(&cm_class, &class_attr_abi_version); |
| 1342 | unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); | 1381 | unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); |
| 1382 | if (overflow_maj) | ||
| 1383 | unregister_chrdev_region(overflow_maj, IB_UCM_MAX_DEVICES); | ||
| 1343 | idr_destroy(&ctx_id_table); | 1384 | idr_destroy(&ctx_id_table); |
| 1344 | } | 1385 | } |
| 1345 | 1386 | ||
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 7de02969ed7d..02d360cfc2f7 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
| @@ -65,12 +65,9 @@ enum { | |||
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | /* | 67 | /* |
| 68 | * Our lifetime rules for these structs are the following: each time a | 68 | * Our lifetime rules for these structs are the following: |
| 69 | * device special file is opened, we look up the corresponding struct | 69 | * device special file is opened, we take a reference on the |
| 70 | * ib_umad_port by minor in the umad_port[] table while holding the | 70 | * ib_umad_port's struct ib_umad_device. We drop these |
| 71 | * port_lock. If this lookup succeeds, we take a reference on the | ||
| 72 | * ib_umad_port's struct ib_umad_device while still holding the | ||
| 73 | * port_lock; if the lookup fails, we fail the open(). We drop these | ||
| 74 | * references in the corresponding close(). | 71 | * references in the corresponding close(). |
| 75 | * | 72 | * |
| 76 | * In addition to references coming from open character devices, there | 73 | * In addition to references coming from open character devices, there |
| @@ -78,19 +75,14 @@ enum { | |||
| 78 | * module's reference taken when allocating the ib_umad_device in | 75 | * module's reference taken when allocating the ib_umad_device in |
| 79 | * ib_umad_add_one(). | 76 | * ib_umad_add_one(). |
| 80 | * | 77 | * |
| 81 | * When destroying an ib_umad_device, we clear all of its | 78 | * When destroying an ib_umad_device, we drop the module's reference. |
| 82 | * ib_umad_ports from umad_port[] while holding port_lock before | ||
| 83 | * dropping the module's reference to the ib_umad_device. This is | ||
| 84 | * always safe because any open() calls will either succeed and obtain | ||
| 85 | * a reference before we clear the umad_port[] entries, or fail after | ||
| 86 | * we clear the umad_port[] entries. | ||
| 87 | */ | 79 | */ |
| 88 | 80 | ||
| 89 | struct ib_umad_port { | 81 | struct ib_umad_port { |
| 90 | struct cdev *cdev; | 82 | struct cdev cdev; |
| 91 | struct device *dev; | 83 | struct device *dev; |
| 92 | 84 | ||
| 93 | struct cdev *sm_cdev; | 85 | struct cdev sm_cdev; |
| 94 | struct device *sm_dev; | 86 | struct device *sm_dev; |
| 95 | struct semaphore sm_sem; | 87 | struct semaphore sm_sem; |
| 96 | 88 | ||
| @@ -136,7 +128,6 @@ static struct class *umad_class; | |||
| 136 | static const dev_t base_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE); | 128 | static const dev_t base_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE); |
| 137 | 129 | ||
| 138 | static DEFINE_SPINLOCK(port_lock); | 130 | static DEFINE_SPINLOCK(port_lock); |
| 139 | static struct ib_umad_port *umad_port[IB_UMAD_MAX_PORTS]; | ||
| 140 | static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS); | 131 | static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS); |
| 141 | 132 | ||
| 142 | static void ib_umad_add_one(struct ib_device *device); | 133 | static void ib_umad_add_one(struct ib_device *device); |
| @@ -496,8 +487,8 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
| 496 | ah_attr.ah_flags = IB_AH_GRH; | 487 | ah_attr.ah_flags = IB_AH_GRH; |
| 497 | memcpy(ah_attr.grh.dgid.raw, packet->mad.hdr.gid, 16); | 488 | memcpy(ah_attr.grh.dgid.raw, packet->mad.hdr.gid, 16); |
| 498 | ah_attr.grh.sgid_index = packet->mad.hdr.gid_index; | 489 | ah_attr.grh.sgid_index = packet->mad.hdr.gid_index; |
| 499 | ah_attr.grh.flow_label = be32_to_cpu(packet->mad.hdr.flow_label); | 490 | ah_attr.grh.flow_label = be32_to_cpu(packet->mad.hdr.flow_label); |
| 500 | ah_attr.grh.hop_limit = packet->mad.hdr.hop_limit; | 491 | ah_attr.grh.hop_limit = packet->mad.hdr.hop_limit; |
| 501 | ah_attr.grh.traffic_class = packet->mad.hdr.traffic_class; | 492 | ah_attr.grh.traffic_class = packet->mad.hdr.traffic_class; |
| 502 | } | 493 | } |
| 503 | 494 | ||
| @@ -528,9 +519,9 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
| 528 | goto err_ah; | 519 | goto err_ah; |
| 529 | } | 520 | } |
| 530 | 521 | ||
| 531 | packet->msg->ah = ah; | 522 | packet->msg->ah = ah; |
| 532 | packet->msg->timeout_ms = packet->mad.hdr.timeout_ms; | 523 | packet->msg->timeout_ms = packet->mad.hdr.timeout_ms; |
| 533 | packet->msg->retries = packet->mad.hdr.retries; | 524 | packet->msg->retries = packet->mad.hdr.retries; |
| 534 | packet->msg->context[0] = packet; | 525 | packet->msg->context[0] = packet; |
| 535 | 526 | ||
| 536 | /* Copy MAD header. Any RMPP header is already in place. */ | 527 | /* Copy MAD header. Any RMPP header is already in place. */ |
| @@ -779,15 +770,11 @@ static long ib_umad_compat_ioctl(struct file *filp, unsigned int cmd, | |||
| 779 | /* | 770 | /* |
| 780 | * ib_umad_open() does not need the BKL: | 771 | * ib_umad_open() does not need the BKL: |
| 781 | * | 772 | * |
| 782 | * - umad_port[] accesses are protected by port_lock, the | 773 | * - the ib_umad_port structures are properly reference counted, and |
| 783 | * ib_umad_port structures are properly reference counted, and | ||
| 784 | * everything else is purely local to the file being created, so | 774 | * everything else is purely local to the file being created, so |
| 785 | * races against other open calls are not a problem; | 775 | * races against other open calls are not a problem; |
| 786 | * - the ioctl method does not affect any global state outside of the | 776 | * - the ioctl method does not affect any global state outside of the |
| 787 | * file structure being operated on; | 777 | * file structure being operated on; |
| 788 | * - the port is added to umad_port[] as the last part of module | ||
| 789 | * initialization so the open method will either immediately run | ||
| 790 | * -ENXIO, or all required initialization will be done. | ||
| 791 | */ | 778 | */ |
| 792 | static int ib_umad_open(struct inode *inode, struct file *filp) | 779 | static int ib_umad_open(struct inode *inode, struct file *filp) |
| 793 | { | 780 | { |
| @@ -795,13 +782,10 @@ static int ib_umad_open(struct inode *inode, struct file *filp) | |||
| 795 | struct ib_umad_file *file; | 782 | struct ib_umad_file *file; |
| 796 | int ret = 0; | 783 | int ret = 0; |
| 797 | 784 | ||
| 798 | spin_lock(&port_lock); | 785 | port = container_of(inode->i_cdev, struct ib_umad_port, cdev); |
| 799 | port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE]; | ||
| 800 | if (port) | 786 | if (port) |
| 801 | kref_get(&port->umad_dev->ref); | 787 | kref_get(&port->umad_dev->ref); |
| 802 | spin_unlock(&port_lock); | 788 | else |
| 803 | |||
| 804 | if (!port) | ||
| 805 | return -ENXIO; | 789 | return -ENXIO; |
| 806 | 790 | ||
| 807 | mutex_lock(&port->file_mutex); | 791 | mutex_lock(&port->file_mutex); |
| @@ -872,16 +856,16 @@ static int ib_umad_close(struct inode *inode, struct file *filp) | |||
| 872 | } | 856 | } |
| 873 | 857 | ||
| 874 | static const struct file_operations umad_fops = { | 858 | static const struct file_operations umad_fops = { |
| 875 | .owner = THIS_MODULE, | 859 | .owner = THIS_MODULE, |
| 876 | .read = ib_umad_read, | 860 | .read = ib_umad_read, |
| 877 | .write = ib_umad_write, | 861 | .write = ib_umad_write, |
| 878 | .poll = ib_umad_poll, | 862 | .poll = ib_umad_poll, |
| 879 | .unlocked_ioctl = ib_umad_ioctl, | 863 | .unlocked_ioctl = ib_umad_ioctl, |
| 880 | #ifdef CONFIG_COMPAT | 864 | #ifdef CONFIG_COMPAT |
| 881 | .compat_ioctl = ib_umad_compat_ioctl, | 865 | .compat_ioctl = ib_umad_compat_ioctl, |
| 882 | #endif | 866 | #endif |
| 883 | .open = ib_umad_open, | 867 | .open = ib_umad_open, |
| 884 | .release = ib_umad_close | 868 | .release = ib_umad_close |
| 885 | }; | 869 | }; |
| 886 | 870 | ||
| 887 | static int ib_umad_sm_open(struct inode *inode, struct file *filp) | 871 | static int ib_umad_sm_open(struct inode *inode, struct file *filp) |
| @@ -892,13 +876,10 @@ static int ib_umad_sm_open(struct inode *inode, struct file *filp) | |||
| 892 | }; | 876 | }; |
| 893 | int ret; | 877 | int ret; |
| 894 | 878 | ||
| 895 | spin_lock(&port_lock); | 879 | port = container_of(inode->i_cdev, struct ib_umad_port, sm_cdev); |
| 896 | port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE - IB_UMAD_MAX_PORTS]; | ||
| 897 | if (port) | 880 | if (port) |
| 898 | kref_get(&port->umad_dev->ref); | 881 | kref_get(&port->umad_dev->ref); |
| 899 | spin_unlock(&port_lock); | 882 | else |
| 900 | |||
| 901 | if (!port) | ||
| 902 | return -ENXIO; | 883 | return -ENXIO; |
| 903 | 884 | ||
| 904 | if (filp->f_flags & O_NONBLOCK) { | 885 | if (filp->f_flags & O_NONBLOCK) { |
| @@ -949,8 +930,8 @@ static int ib_umad_sm_close(struct inode *inode, struct file *filp) | |||
| 949 | } | 930 | } |
| 950 | 931 | ||
| 951 | static const struct file_operations umad_sm_fops = { | 932 | static const struct file_operations umad_sm_fops = { |
| 952 | .owner = THIS_MODULE, | 933 | .owner = THIS_MODULE, |
| 953 | .open = ib_umad_sm_open, | 934 | .open = ib_umad_sm_open, |
| 954 | .release = ib_umad_sm_close | 935 | .release = ib_umad_sm_close |
| 955 | }; | 936 | }; |
| 956 | 937 | ||
| @@ -990,16 +971,51 @@ static ssize_t show_abi_version(struct class *class, char *buf) | |||
| 990 | } | 971 | } |
| 991 | static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); | 972 | static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); |
| 992 | 973 | ||
| 974 | static dev_t overflow_maj; | ||
| 975 | static DECLARE_BITMAP(overflow_map, IB_UMAD_MAX_PORTS); | ||
| 976 | static int find_overflow_devnum(void) | ||
| 977 | { | ||
| 978 | int ret; | ||
| 979 | |||
| 980 | if (!overflow_maj) { | ||
| 981 | ret = alloc_chrdev_region(&overflow_maj, 0, IB_UMAD_MAX_PORTS * 2, | ||
| 982 | "infiniband_mad"); | ||
| 983 | if (ret) { | ||
| 984 | printk(KERN_ERR "user_mad: couldn't register dynamic device number\n"); | ||
| 985 | return ret; | ||
| 986 | } | ||
| 987 | } | ||
| 988 | |||
| 989 | ret = find_first_zero_bit(overflow_map, IB_UMAD_MAX_PORTS); | ||
| 990 | if (ret >= IB_UMAD_MAX_PORTS) | ||
| 991 | return -1; | ||
| 992 | |||
| 993 | return ret; | ||
| 994 | } | ||
| 995 | |||
| 993 | static int ib_umad_init_port(struct ib_device *device, int port_num, | 996 | static int ib_umad_init_port(struct ib_device *device, int port_num, |
| 994 | struct ib_umad_port *port) | 997 | struct ib_umad_port *port) |
| 995 | { | 998 | { |
| 999 | int devnum; | ||
| 1000 | dev_t base; | ||
| 1001 | |||
| 996 | spin_lock(&port_lock); | 1002 | spin_lock(&port_lock); |
| 997 | port->dev_num = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS); | 1003 | devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS); |
| 998 | if (port->dev_num >= IB_UMAD_MAX_PORTS) { | 1004 | if (devnum >= IB_UMAD_MAX_PORTS) { |
| 999 | spin_unlock(&port_lock); | 1005 | spin_unlock(&port_lock); |
| 1000 | return -1; | 1006 | devnum = find_overflow_devnum(); |
| 1007 | if (devnum < 0) | ||
| 1008 | return -1; | ||
| 1009 | |||
| 1010 | spin_lock(&port_lock); | ||
| 1011 | port->dev_num = devnum + IB_UMAD_MAX_PORTS; | ||
| 1012 | base = devnum + overflow_maj; | ||
| 1013 | set_bit(devnum, overflow_map); | ||
| 1014 | } else { | ||
| 1015 | port->dev_num = devnum; | ||
| 1016 | base = devnum + base_dev; | ||
| 1017 | set_bit(devnum, dev_map); | ||
| 1001 | } | 1018 | } |
| 1002 | set_bit(port->dev_num, dev_map); | ||
| 1003 | spin_unlock(&port_lock); | 1019 | spin_unlock(&port_lock); |
| 1004 | 1020 | ||
| 1005 | port->ib_dev = device; | 1021 | port->ib_dev = device; |
| @@ -1008,17 +1024,14 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, | |||
| 1008 | mutex_init(&port->file_mutex); | 1024 | mutex_init(&port->file_mutex); |
| 1009 | INIT_LIST_HEAD(&port->file_list); | 1025 | INIT_LIST_HEAD(&port->file_list); |
| 1010 | 1026 | ||
| 1011 | port->cdev = cdev_alloc(); | 1027 | cdev_init(&port->cdev, &umad_fops); |
| 1012 | if (!port->cdev) | 1028 | port->cdev.owner = THIS_MODULE; |
| 1013 | return -1; | 1029 | kobject_set_name(&port->cdev.kobj, "umad%d", port->dev_num); |
| 1014 | port->cdev->owner = THIS_MODULE; | 1030 | if (cdev_add(&port->cdev, base, 1)) |
| 1015 | port->cdev->ops = &umad_fops; | ||
| 1016 | kobject_set_name(&port->cdev->kobj, "umad%d", port->dev_num); | ||
| 1017 | if (cdev_add(port->cdev, base_dev + port->dev_num, 1)) | ||
| 1018 | goto err_cdev; | 1031 | goto err_cdev; |
| 1019 | 1032 | ||
| 1020 | port->dev = device_create(umad_class, device->dma_device, | 1033 | port->dev = device_create(umad_class, device->dma_device, |
| 1021 | port->cdev->dev, port, | 1034 | port->cdev.dev, port, |
| 1022 | "umad%d", port->dev_num); | 1035 | "umad%d", port->dev_num); |
| 1023 | if (IS_ERR(port->dev)) | 1036 | if (IS_ERR(port->dev)) |
| 1024 | goto err_cdev; | 1037 | goto err_cdev; |
| @@ -1028,17 +1041,15 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, | |||
| 1028 | if (device_create_file(port->dev, &dev_attr_port)) | 1041 | if (device_create_file(port->dev, &dev_attr_port)) |
| 1029 | goto err_dev; | 1042 | goto err_dev; |
| 1030 | 1043 | ||
| 1031 | port->sm_cdev = cdev_alloc(); | 1044 | base += IB_UMAD_MAX_PORTS; |
| 1032 | if (!port->sm_cdev) | 1045 | cdev_init(&port->sm_cdev, &umad_sm_fops); |
| 1033 | goto err_dev; | 1046 | port->sm_cdev.owner = THIS_MODULE; |
| 1034 | port->sm_cdev->owner = THIS_MODULE; | 1047 | kobject_set_name(&port->sm_cdev.kobj, "issm%d", port->dev_num); |
| 1035 | port->sm_cdev->ops = &umad_sm_fops; | 1048 | if (cdev_add(&port->sm_cdev, base, 1)) |
| 1036 | kobject_set_name(&port->sm_cdev->kobj, "issm%d", port->dev_num); | ||
| 1037 | if (cdev_add(port->sm_cdev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1)) | ||
| 1038 | goto err_sm_cdev; | 1049 | goto err_sm_cdev; |
| 1039 | 1050 | ||
| 1040 | port->sm_dev = device_create(umad_class, device->dma_device, | 1051 | port->sm_dev = device_create(umad_class, device->dma_device, |
| 1041 | port->sm_cdev->dev, port, | 1052 | port->sm_cdev.dev, port, |
| 1042 | "issm%d", port->dev_num); | 1053 | "issm%d", port->dev_num); |
| 1043 | if (IS_ERR(port->sm_dev)) | 1054 | if (IS_ERR(port->sm_dev)) |
| 1044 | goto err_sm_cdev; | 1055 | goto err_sm_cdev; |
| @@ -1048,24 +1059,23 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, | |||
| 1048 | if (device_create_file(port->sm_dev, &dev_attr_port)) | 1059 | if (device_create_file(port->sm_dev, &dev_attr_port)) |
| 1049 | goto err_sm_dev; | 1060 | goto err_sm_dev; |
| 1050 | 1061 | ||
| 1051 | spin_lock(&port_lock); | ||
| 1052 | umad_port[port->dev_num] = port; | ||
| 1053 | spin_unlock(&port_lock); | ||
| 1054 | |||
| 1055 | return 0; | 1062 | return 0; |
| 1056 | 1063 | ||
| 1057 | err_sm_dev: | 1064 | err_sm_dev: |
| 1058 | device_destroy(umad_class, port->sm_cdev->dev); | 1065 | device_destroy(umad_class, port->sm_cdev.dev); |
| 1059 | 1066 | ||
| 1060 | err_sm_cdev: | 1067 | err_sm_cdev: |
| 1061 | cdev_del(port->sm_cdev); | 1068 | cdev_del(&port->sm_cdev); |
| 1062 | 1069 | ||
| 1063 | err_dev: | 1070 | err_dev: |
| 1064 | device_destroy(umad_class, port->cdev->dev); | 1071 | device_destroy(umad_class, port->cdev.dev); |
| 1065 | 1072 | ||
| 1066 | err_cdev: | 1073 | err_cdev: |
| 1067 | cdev_del(port->cdev); | 1074 | cdev_del(&port->cdev); |
| 1068 | clear_bit(port->dev_num, dev_map); | 1075 | if (port->dev_num < IB_UMAD_MAX_PORTS) |
| 1076 | clear_bit(devnum, dev_map); | ||
| 1077 | else | ||
| 1078 | clear_bit(devnum, overflow_map); | ||
| 1069 | 1079 | ||
| 1070 | return -1; | 1080 | return -1; |
| 1071 | } | 1081 | } |
| @@ -1079,15 +1089,11 @@ static void ib_umad_kill_port(struct ib_umad_port *port) | |||
| 1079 | dev_set_drvdata(port->dev, NULL); | 1089 | dev_set_drvdata(port->dev, NULL); |
| 1080 | dev_set_drvdata(port->sm_dev, NULL); | 1090 | dev_set_drvdata(port->sm_dev, NULL); |
| 1081 | 1091 | ||
| 1082 | device_destroy(umad_class, port->cdev->dev); | 1092 | device_destroy(umad_class, port->cdev.dev); |
| 1083 | device_destroy(umad_class, port->sm_cdev->dev); | 1093 | device_destroy(umad_class, port->sm_cdev.dev); |
| 1084 | 1094 | ||
| 1085 | cdev_del(port->cdev); | 1095 | cdev_del(&port->cdev); |
| 1086 | cdev_del(port->sm_cdev); | 1096 | cdev_del(&port->sm_cdev); |
| 1087 | |||
| 1088 | spin_lock(&port_lock); | ||
| 1089 | umad_port[port->dev_num] = NULL; | ||
| 1090 | spin_unlock(&port_lock); | ||
| 1091 | 1097 | ||
| 1092 | mutex_lock(&port->file_mutex); | 1098 | mutex_lock(&port->file_mutex); |
| 1093 | 1099 | ||
| @@ -1106,7 +1112,10 @@ static void ib_umad_kill_port(struct ib_umad_port *port) | |||
| 1106 | 1112 | ||
| 1107 | mutex_unlock(&port->file_mutex); | 1113 | mutex_unlock(&port->file_mutex); |
| 1108 | 1114 | ||
| 1109 | clear_bit(port->dev_num, dev_map); | 1115 | if (port->dev_num < IB_UMAD_MAX_PORTS) |
| 1116 | clear_bit(port->dev_num, dev_map); | ||
| 1117 | else | ||
| 1118 | clear_bit(port->dev_num - IB_UMAD_MAX_PORTS, overflow_map); | ||
| 1110 | } | 1119 | } |
| 1111 | 1120 | ||
| 1112 | static void ib_umad_add_one(struct ib_device *device) | 1121 | static void ib_umad_add_one(struct ib_device *device) |
| @@ -1214,6 +1223,8 @@ static void __exit ib_umad_cleanup(void) | |||
| 1214 | ib_unregister_client(&umad_client); | 1223 | ib_unregister_client(&umad_client); |
| 1215 | class_destroy(umad_class); | 1224 | class_destroy(umad_class); |
| 1216 | unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2); | 1225 | unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2); |
| 1226 | if (overflow_maj) | ||
| 1227 | unregister_chrdev_region(overflow_maj, IB_UMAD_MAX_PORTS * 2); | ||
| 1217 | } | 1228 | } |
| 1218 | 1229 | ||
| 1219 | module_init(ib_umad_init); | 1230 | module_init(ib_umad_init); |
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index b3ea9587dc80..e54d9ac6d1ca 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/idr.h> | 41 | #include <linux/idr.h> |
| 42 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
| 43 | #include <linux/completion.h> | 43 | #include <linux/completion.h> |
| 44 | #include <linux/cdev.h> | ||
| 44 | 45 | ||
| 45 | #include <rdma/ib_verbs.h> | 46 | #include <rdma/ib_verbs.h> |
| 46 | #include <rdma/ib_umem.h> | 47 | #include <rdma/ib_umem.h> |
| @@ -69,23 +70,23 @@ | |||
| 69 | 70 | ||
| 70 | struct ib_uverbs_device { | 71 | struct ib_uverbs_device { |
| 71 | struct kref ref; | 72 | struct kref ref; |
| 73 | int num_comp_vectors; | ||
| 72 | struct completion comp; | 74 | struct completion comp; |
| 73 | int devnum; | ||
| 74 | struct cdev *cdev; | ||
| 75 | struct device *dev; | 75 | struct device *dev; |
| 76 | struct ib_device *ib_dev; | 76 | struct ib_device *ib_dev; |
| 77 | int num_comp_vectors; | 77 | int devnum; |
| 78 | struct cdev cdev; | ||
| 78 | }; | 79 | }; |
| 79 | 80 | ||
| 80 | struct ib_uverbs_event_file { | 81 | struct ib_uverbs_event_file { |
| 81 | struct kref ref; | 82 | struct kref ref; |
| 83 | int is_async; | ||
| 82 | struct ib_uverbs_file *uverbs_file; | 84 | struct ib_uverbs_file *uverbs_file; |
| 83 | spinlock_t lock; | 85 | spinlock_t lock; |
| 86 | int is_closed; | ||
| 84 | wait_queue_head_t poll_wait; | 87 | wait_queue_head_t poll_wait; |
| 85 | struct fasync_struct *async_queue; | 88 | struct fasync_struct *async_queue; |
| 86 | struct list_head event_list; | 89 | struct list_head event_list; |
| 87 | int is_async; | ||
| 88 | int is_closed; | ||
| 89 | }; | 90 | }; |
| 90 | 91 | ||
| 91 | struct ib_uverbs_file { | 92 | struct ib_uverbs_file { |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 5f284ffd430e..dbf04511cf0a 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
| @@ -43,7 +43,6 @@ | |||
| 43 | #include <linux/sched.h> | 43 | #include <linux/sched.h> |
| 44 | #include <linux/file.h> | 44 | #include <linux/file.h> |
| 45 | #include <linux/mount.h> | 45 | #include <linux/mount.h> |
| 46 | #include <linux/cdev.h> | ||
| 47 | 46 | ||
| 48 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
| 49 | 48 | ||
| @@ -75,40 +74,39 @@ DEFINE_IDR(ib_uverbs_qp_idr); | |||
| 75 | DEFINE_IDR(ib_uverbs_srq_idr); | 74 | DEFINE_IDR(ib_uverbs_srq_idr); |
| 76 | 75 | ||
| 77 | static DEFINE_SPINLOCK(map_lock); | 76 | static DEFINE_SPINLOCK(map_lock); |
| 78 | static struct ib_uverbs_device *dev_table[IB_UVERBS_MAX_DEVICES]; | ||
| 79 | static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); | 77 | static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); |
| 80 | 78 | ||
| 81 | static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, | 79 | static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, |
| 82 | const char __user *buf, int in_len, | 80 | const char __user *buf, int in_len, |
| 83 | int out_len) = { | 81 | int out_len) = { |
| 84 | [IB_USER_VERBS_CMD_GET_CONTEXT] = ib_uverbs_get_context, | 82 | [IB_USER_VERBS_CMD_GET_CONTEXT] = ib_uverbs_get_context, |
| 85 | [IB_USER_VERBS_CMD_QUERY_DEVICE] = ib_uverbs_query_device, | 83 | [IB_USER_VERBS_CMD_QUERY_DEVICE] = ib_uverbs_query_device, |
| 86 | [IB_USER_VERBS_CMD_QUERY_PORT] = ib_uverbs_query_port, | 84 | [IB_USER_VERBS_CMD_QUERY_PORT] = ib_uverbs_query_port, |
| 87 | [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd, | 85 | [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd, |
| 88 | [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd, | 86 | [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd, |
| 89 | [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr, | 87 | [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr, |
| 90 | [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr, | 88 | [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr, |
| 91 | [IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL] = ib_uverbs_create_comp_channel, | 89 | [IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL] = ib_uverbs_create_comp_channel, |
| 92 | [IB_USER_VERBS_CMD_CREATE_CQ] = ib_uverbs_create_cq, | 90 | [IB_USER_VERBS_CMD_CREATE_CQ] = ib_uverbs_create_cq, |
| 93 | [IB_USER_VERBS_CMD_RESIZE_CQ] = ib_uverbs_resize_cq, | 91 | [IB_USER_VERBS_CMD_RESIZE_CQ] = ib_uverbs_resize_cq, |
| 94 | [IB_USER_VERBS_CMD_POLL_CQ] = ib_uverbs_poll_cq, | 92 | [IB_USER_VERBS_CMD_POLL_CQ] = ib_uverbs_poll_cq, |
| 95 | [IB_USER_VERBS_CMD_REQ_NOTIFY_CQ] = ib_uverbs_req_notify_cq, | 93 | [IB_USER_VERBS_CMD_REQ_NOTIFY_CQ] = ib_uverbs_req_notify_cq, |
| 96 | [IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq, | 94 | [IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq, |
| 97 | [IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp, | 95 | [IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp, |
| 98 | [IB_USER_VERBS_CMD_QUERY_QP] = ib_uverbs_query_qp, | 96 | [IB_USER_VERBS_CMD_QUERY_QP] = ib_uverbs_query_qp, |
| 99 | [IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp, | 97 | [IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp, |
| 100 | [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp, | 98 | [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp, |
| 101 | [IB_USER_VERBS_CMD_POST_SEND] = ib_uverbs_post_send, | 99 | [IB_USER_VERBS_CMD_POST_SEND] = ib_uverbs_post_send, |
| 102 | [IB_USER_VERBS_CMD_POST_RECV] = ib_uverbs_post_recv, | 100 | [IB_USER_VERBS_CMD_POST_RECV] = ib_uverbs_post_recv, |
| 103 | [IB_USER_VERBS_CMD_POST_SRQ_RECV] = ib_uverbs_post_srq_recv, | 101 | [IB_USER_VERBS_CMD_POST_SRQ_RECV] = ib_uverbs_post_srq_recv, |
| 104 | [IB_USER_VERBS_CMD_CREATE_AH] = ib_uverbs_create_ah, | 102 | [IB_USER_VERBS_CMD_CREATE_AH] = ib_uverbs_create_ah, |
| 105 | [IB_USER_VERBS_CMD_DESTROY_AH] = ib_uverbs_destroy_ah, | 103 | [IB_USER_VERBS_CMD_DESTROY_AH] = ib_uverbs_destroy_ah, |
| 106 | [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast, | 104 | [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast, |
| 107 | [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast, | 105 | [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast, |
| 108 | [IB_USER_VERBS_CMD_CREATE_SRQ] = ib_uverbs_create_srq, | 106 | [IB_USER_VERBS_CMD_CREATE_SRQ] = ib_uverbs_create_srq, |
| 109 | [IB_USER_VERBS_CMD_MODIFY_SRQ] = ib_uverbs_modify_srq, | 107 | [IB_USER_VERBS_CMD_MODIFY_SRQ] = ib_uverbs_modify_srq, |
| 110 | [IB_USER_VERBS_CMD_QUERY_SRQ] = ib_uverbs_query_srq, | 108 | [IB_USER_VERBS_CMD_QUERY_SRQ] = ib_uverbs_query_srq, |
| 111 | [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq, | 109 | [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq, |
| 112 | }; | 110 | }; |
| 113 | 111 | ||
| 114 | static struct vfsmount *uverbs_event_mnt; | 112 | static struct vfsmount *uverbs_event_mnt; |
| @@ -370,7 +368,7 @@ static int ib_uverbs_event_close(struct inode *inode, struct file *filp) | |||
| 370 | 368 | ||
| 371 | static const struct file_operations uverbs_event_fops = { | 369 | static const struct file_operations uverbs_event_fops = { |
| 372 | .owner = THIS_MODULE, | 370 | .owner = THIS_MODULE, |
| 373 | .read = ib_uverbs_event_read, | 371 | .read = ib_uverbs_event_read, |
| 374 | .poll = ib_uverbs_event_poll, | 372 | .poll = ib_uverbs_event_poll, |
| 375 | .release = ib_uverbs_event_close, | 373 | .release = ib_uverbs_event_close, |
| 376 | .fasync = ib_uverbs_event_fasync | 374 | .fasync = ib_uverbs_event_fasync |
| @@ -617,14 +615,12 @@ static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma) | |||
| 617 | /* | 615 | /* |
| 618 | * ib_uverbs_open() does not need the BKL: | 616 | * ib_uverbs_open() does not need the BKL: |
| 619 | * | 617 | * |
| 620 | * - dev_table[] accesses are protected by map_lock, the | 618 | * - the ib_uverbs_device structures are properly reference counted and |
| 621 | * ib_uverbs_device structures are properly reference counted, and | ||
| 622 | * everything else is purely local to the file being created, so | 619 | * everything else is purely local to the file being created, so |
| 623 | * races against other open calls are not a problem; | 620 | * races against other open calls are not a problem; |
| 624 | * - there is no ioctl method to race against; | 621 | * - there is no ioctl method to race against; |
| 625 | * - the device is added to dev_table[] as the last part of module | 622 | * - the open method will either immediately run -ENXIO, or all |
| 626 | * initialization, the open method will either immediately run | 623 | * required initialization will be done. |
| 627 | * -ENXIO, or all required initialization will be done. | ||
| 628 | */ | 624 | */ |
| 629 | static int ib_uverbs_open(struct inode *inode, struct file *filp) | 625 | static int ib_uverbs_open(struct inode *inode, struct file *filp) |
| 630 | { | 626 | { |
| @@ -632,13 +628,10 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) | |||
| 632 | struct ib_uverbs_file *file; | 628 | struct ib_uverbs_file *file; |
| 633 | int ret; | 629 | int ret; |
| 634 | 630 | ||
| 635 | spin_lock(&map_lock); | 631 | dev = container_of(inode->i_cdev, struct ib_uverbs_device, cdev); |
| 636 | dev = dev_table[iminor(inode) - IB_UVERBS_BASE_MINOR]; | ||
| 637 | if (dev) | 632 | if (dev) |
| 638 | kref_get(&dev->ref); | 633 | kref_get(&dev->ref); |
| 639 | spin_unlock(&map_lock); | 634 | else |
| 640 | |||
| 641 | if (!dev) | ||
| 642 | return -ENXIO; | 635 | return -ENXIO; |
| 643 | 636 | ||
| 644 | if (!try_module_get(dev->ib_dev->owner)) { | 637 | if (!try_module_get(dev->ib_dev->owner)) { |
| @@ -685,17 +678,17 @@ static int ib_uverbs_close(struct inode *inode, struct file *filp) | |||
| 685 | } | 678 | } |
| 686 | 679 | ||
| 687 | static const struct file_operations uverbs_fops = { | 680 | static const struct file_operations uverbs_fops = { |
| 688 | .owner = THIS_MODULE, | 681 | .owner = THIS_MODULE, |
| 689 | .write = ib_uverbs_write, | 682 | .write = ib_uverbs_write, |
| 690 | .open = ib_uverbs_open, | 683 | .open = ib_uverbs_open, |
| 691 | .release = ib_uverbs_close | 684 | .release = ib_uverbs_close |
| 692 | }; | 685 | }; |
| 693 | 686 | ||
| 694 | static const struct file_operations uverbs_mmap_fops = { | 687 | static const struct file_operations uverbs_mmap_fops = { |
| 695 | .owner = THIS_MODULE, | 688 | .owner = THIS_MODULE, |
| 696 | .write = ib_uverbs_write, | 689 | .write = ib_uverbs_write, |
| 697 | .mmap = ib_uverbs_mmap, | 690 | .mmap = ib_uverbs_mmap, |
| 698 | .open = ib_uverbs_open, | 691 | .open = ib_uverbs_open, |
| 699 | .release = ib_uverbs_close | 692 | .release = ib_uverbs_close |
| 700 | }; | 693 | }; |
| 701 | 694 | ||
| @@ -735,8 +728,38 @@ static ssize_t show_abi_version(struct class *class, char *buf) | |||
| 735 | } | 728 | } |
| 736 | static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); | 729 | static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); |
| 737 | 730 | ||
| 731 | static dev_t overflow_maj; | ||
| 732 | static 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 | */ | ||
| 739 | static 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 | |||
| 738 | static void ib_uverbs_add_one(struct ib_device *device) | 759 | static void ib_uverbs_add_one(struct ib_device *device) |
| 739 | { | 760 | { |
| 761 | int devnum; | ||
| 762 | dev_t base; | ||
| 740 | struct ib_uverbs_device *uverbs_dev; | 763 | struct ib_uverbs_device *uverbs_dev; |
| 741 | 764 | ||
| 742 | if (!device->alloc_ucontext) | 765 | if (!device->alloc_ucontext) |
| @@ -750,28 +773,36 @@ static void ib_uverbs_add_one(struct ib_device *device) | |||
| 750 | init_completion(&uverbs_dev->comp); | 773 | init_completion(&uverbs_dev->comp); |
| 751 | 774 | ||
| 752 | spin_lock(&map_lock); | 775 | spin_lock(&map_lock); |
| 753 | uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES); | 776 | devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES); |
| 754 | if (uverbs_dev->devnum >= IB_UVERBS_MAX_DEVICES) { | 777 | if (devnum >= IB_UVERBS_MAX_DEVICES) { |
| 755 | spin_unlock(&map_lock); | 778 | spin_unlock(&map_lock); |
| 756 | 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); | ||
| 757 | } | 791 | } |
| 758 | set_bit(uverbs_dev->devnum, dev_map); | ||
| 759 | spin_unlock(&map_lock); | 792 | spin_unlock(&map_lock); |
| 760 | 793 | ||
| 761 | uverbs_dev->ib_dev = device; | 794 | uverbs_dev->ib_dev = device; |
| 762 | uverbs_dev->num_comp_vectors = device->num_comp_vectors; | 795 | uverbs_dev->num_comp_vectors = device->num_comp_vectors; |
| 763 | 796 | ||
| 764 | uverbs_dev->cdev = cdev_alloc(); | 797 | cdev_init(&uverbs_dev->cdev, NULL); |
| 765 | if (!uverbs_dev->cdev) | 798 | uverbs_dev->cdev.owner = THIS_MODULE; |
| 766 | goto err; | 799 | uverbs_dev->cdev.ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops; |
| 767 | uverbs_dev->cdev->owner = THIS_MODULE; | 800 | kobject_set_name(&uverbs_dev->cdev.kobj, "uverbs%d", uverbs_dev->devnum); |
| 768 | uverbs_dev->cdev->ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops; | 801 | if (cdev_add(&uverbs_dev->cdev, base, 1)) |
| 769 | kobject_set_name(&uverbs_dev->cdev->kobj, "uverbs%d", uverbs_dev->devnum); | ||
| 770 | if (cdev_add(uverbs_dev->cdev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1)) | ||
| 771 | goto err_cdev; | 802 | goto err_cdev; |
| 772 | 803 | ||
| 773 | uverbs_dev->dev = device_create(uverbs_class, device->dma_device, | 804 | uverbs_dev->dev = device_create(uverbs_class, device->dma_device, |
| 774 | uverbs_dev->cdev->dev, uverbs_dev, | 805 | uverbs_dev->cdev.dev, uverbs_dev, |
| 775 | "uverbs%d", uverbs_dev->devnum); | 806 | "uverbs%d", uverbs_dev->devnum); |
| 776 | if (IS_ERR(uverbs_dev->dev)) | 807 | if (IS_ERR(uverbs_dev->dev)) |
| 777 | goto err_cdev; | 808 | goto err_cdev; |
| @@ -781,20 +812,19 @@ static void ib_uverbs_add_one(struct ib_device *device) | |||
| 781 | if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version)) | 812 | if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version)) |
| 782 | goto err_class; | 813 | goto err_class; |
| 783 | 814 | ||
| 784 | spin_lock(&map_lock); | ||
| 785 | dev_table[uverbs_dev->devnum] = uverbs_dev; | ||
| 786 | spin_unlock(&map_lock); | ||
| 787 | |||
| 788 | ib_set_client_data(device, &uverbs_client, uverbs_dev); | 815 | ib_set_client_data(device, &uverbs_client, uverbs_dev); |
| 789 | 816 | ||
| 790 | return; | 817 | return; |
| 791 | 818 | ||
| 792 | err_class: | 819 | err_class: |
| 793 | device_destroy(uverbs_class, uverbs_dev->cdev->dev); | 820 | device_destroy(uverbs_class, uverbs_dev->cdev.dev); |
| 794 | 821 | ||
| 795 | err_cdev: | 822 | err_cdev: |
| 796 | cdev_del(uverbs_dev->cdev); | 823 | cdev_del(&uverbs_dev->cdev); |
| 797 | clear_bit(uverbs_dev->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); | ||
| 798 | 828 | ||
| 799 | err: | 829 | err: |
| 800 | kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); | 830 | kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); |
| @@ -811,14 +841,13 @@ static void ib_uverbs_remove_one(struct ib_device *device) | |||
| 811 | return; | 841 | return; |
| 812 | 842 | ||
| 813 | dev_set_drvdata(uverbs_dev->dev, NULL); | 843 | dev_set_drvdata(uverbs_dev->dev, NULL); |
| 814 | device_destroy(uverbs_class, uverbs_dev->cdev->dev); | 844 | device_destroy(uverbs_class, uverbs_dev->cdev.dev); |
| 815 | cdev_del(uverbs_dev->cdev); | 845 | cdev_del(&uverbs_dev->cdev); |
| 816 | 846 | ||
| 817 | spin_lock(&map_lock); | 847 | if (uverbs_dev->devnum < IB_UVERBS_MAX_DEVICES) |
| 818 | dev_table[uverbs_dev->devnum] = NULL; | 848 | clear_bit(uverbs_dev->devnum, dev_map); |
| 819 | spin_unlock(&map_lock); | 849 | else |
| 820 | 850 | clear_bit(uverbs_dev->devnum - IB_UVERBS_MAX_DEVICES, overflow_map); | |
| 821 | clear_bit(uverbs_dev->devnum, dev_map); | ||
| 822 | 851 | ||
| 823 | kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); | 852 | kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); |
| 824 | wait_for_completion(&uverbs_dev->comp); | 853 | wait_for_completion(&uverbs_dev->comp); |
| @@ -908,6 +937,8 @@ static void __exit ib_uverbs_cleanup(void) | |||
| 908 | unregister_filesystem(&uverbs_event_fs); | 937 | unregister_filesystem(&uverbs_event_fs); |
| 909 | class_destroy(uverbs_class); | 938 | class_destroy(uverbs_class); |
| 910 | 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); | ||
| 911 | idr_destroy(&ib_uverbs_pd_idr); | 942 | idr_destroy(&ib_uverbs_pd_idr); |
| 912 | idr_destroy(&ib_uverbs_mr_idr); | 943 | idr_destroy(&ib_uverbs_mr_idr); |
| 913 | idr_destroy(&ib_uverbs_mw_idr); | 944 | idr_destroy(&ib_uverbs_mw_idr); |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index 0677fc7dfd51..a28e862f2d68 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c | |||
| @@ -109,7 +109,6 @@ int cxio_hal_cq_op(struct cxio_rdev *rdev_p, struct t3_cq *cq, | |||
| 109 | while (!CQ_VLD_ENTRY(rptr, cq->size_log2, cqe)) { | 109 | while (!CQ_VLD_ENTRY(rptr, cq->size_log2, cqe)) { |
| 110 | udelay(1); | 110 | udelay(1); |
| 111 | if (i++ > 1000000) { | 111 | if (i++ > 1000000) { |
| 112 | BUG_ON(1); | ||
| 113 | printk(KERN_ERR "%s: stalled rnic\n", | 112 | printk(KERN_ERR "%s: stalled rnic\n", |
| 114 | rdev_p->dev_name); | 113 | rdev_p->dev_name); |
| 115 | return -EIO; | 114 | return -EIO; |
| @@ -155,7 +154,7 @@ static int cxio_hal_clear_qp_ctx(struct cxio_rdev *rdev_p, u32 qpid) | |||
| 155 | return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb); | 154 | return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb); |
| 156 | } | 155 | } |
| 157 | 156 | ||
| 158 | int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq) | 157 | int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq, int kernel) |
| 159 | { | 158 | { |
| 160 | struct rdma_cq_setup setup; | 159 | struct rdma_cq_setup setup; |
| 161 | int size = (1UL << (cq->size_log2)) * sizeof(struct t3_cqe); | 160 | int size = (1UL << (cq->size_log2)) * sizeof(struct t3_cqe); |
| @@ -163,12 +162,12 @@ int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq) | |||
| 163 | cq->cqid = cxio_hal_get_cqid(rdev_p->rscp); | 162 | cq->cqid = cxio_hal_get_cqid(rdev_p->rscp); |
| 164 | if (!cq->cqid) | 163 | if (!cq->cqid) |
| 165 | return -ENOMEM; | 164 | return -ENOMEM; |
| 166 | cq->sw_queue = kzalloc(size, GFP_KERNEL); | 165 | if (kernel) { |
| 167 | if (!cq->sw_queue) | 166 | cq->sw_queue = kzalloc(size, GFP_KERNEL); |
| 168 | return -ENOMEM; | 167 | if (!cq->sw_queue) |
| 169 | cq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev), | 168 | return -ENOMEM; |
| 170 | (1UL << (cq->size_log2)) * | 169 | } |
| 171 | sizeof(struct t3_cqe), | 170 | cq->queue = dma_alloc_coherent(&(rdev_p->rnic_info.pdev->dev), size, |
| 172 | &(cq->dma_addr), GFP_KERNEL); | 171 | &(cq->dma_addr), GFP_KERNEL); |
| 173 | if (!cq->queue) { | 172 | if (!cq->queue) { |
| 174 | kfree(cq->sw_queue); | 173 | kfree(cq->sw_queue); |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index f3d440cc68f2..073373c2c560 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h | |||
| @@ -53,7 +53,7 @@ | |||
| 53 | #define T3_MAX_PBL_SIZE 256 | 53 | #define T3_MAX_PBL_SIZE 256 |
| 54 | #define T3_MAX_RQ_SIZE 1024 | 54 | #define T3_MAX_RQ_SIZE 1024 |
| 55 | #define T3_MAX_QP_DEPTH (T3_MAX_RQ_SIZE-1) | 55 | #define T3_MAX_QP_DEPTH (T3_MAX_RQ_SIZE-1) |
| 56 | #define T3_MAX_CQ_DEPTH 8192 | 56 | #define T3_MAX_CQ_DEPTH 262144 |
| 57 | #define T3_MAX_NUM_STAG (1<<15) | 57 | #define T3_MAX_NUM_STAG (1<<15) |
| 58 | #define T3_MAX_MR_SIZE 0x100000000ULL | 58 | #define T3_MAX_MR_SIZE 0x100000000ULL |
| 59 | #define T3_PAGESIZE_MASK 0xffff000 /* 4KB-128MB */ | 59 | #define T3_PAGESIZE_MASK 0xffff000 /* 4KB-128MB */ |
| @@ -157,7 +157,7 @@ int cxio_rdev_open(struct cxio_rdev *rdev); | |||
| 157 | void cxio_rdev_close(struct cxio_rdev *rdev); | 157 | void cxio_rdev_close(struct cxio_rdev *rdev); |
| 158 | int cxio_hal_cq_op(struct cxio_rdev *rdev, struct t3_cq *cq, | 158 | int cxio_hal_cq_op(struct cxio_rdev *rdev, struct t3_cq *cq, |
| 159 | enum t3_cq_opcode op, u32 credit); | 159 | enum t3_cq_opcode op, u32 credit); |
| 160 | int cxio_create_cq(struct cxio_rdev *rdev, struct t3_cq *cq); | 160 | int cxio_create_cq(struct cxio_rdev *rdev, struct t3_cq *cq, int kernel); |
| 161 | int cxio_destroy_cq(struct cxio_rdev *rdev, struct t3_cq *cq); | 161 | int cxio_destroy_cq(struct cxio_rdev *rdev, struct t3_cq *cq); |
| 162 | int cxio_resize_cq(struct cxio_rdev *rdev, struct t3_cq *cq); | 162 | int cxio_resize_cq(struct cxio_rdev *rdev, struct t3_cq *cq); |
| 163 | void cxio_release_ucontext(struct cxio_rdev *rdev, struct cxio_ucontext *uctx); | 163 | void cxio_release_ucontext(struct cxio_rdev *rdev, struct cxio_ucontext *uctx); |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h index a197a5b7ac7f..15073b2da1c5 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_wr.h +++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h | |||
| @@ -730,7 +730,22 @@ struct t3_cq { | |||
| 730 | 730 | ||
| 731 | static inline void cxio_set_wq_in_error(struct t3_wq *wq) | 731 | static inline void cxio_set_wq_in_error(struct t3_wq *wq) |
| 732 | { | 732 | { |
| 733 | wq->queue->wq_in_err.err = 1; | 733 | wq->queue->wq_in_err.err |= 1; |
| 734 | } | ||
| 735 | |||
| 736 | static inline void cxio_disable_wq_db(struct t3_wq *wq) | ||
| 737 | { | ||
| 738 | wq->queue->wq_in_err.err |= 2; | ||
| 739 | } | ||
| 740 | |||
| 741 | static inline void cxio_enable_wq_db(struct t3_wq *wq) | ||
| 742 | { | ||
| 743 | wq->queue->wq_in_err.err &= ~2; | ||
| 744 | } | ||
| 745 | |||
| 746 | static inline int cxio_wq_db_enabled(struct t3_wq *wq) | ||
| 747 | { | ||
| 748 | return !(wq->queue->wq_in_err.err & 2); | ||
| 734 | } | 749 | } |
| 735 | 750 | ||
| 736 | static inline struct t3_cqe *cxio_next_hw_cqe(struct t3_cq *cq) | 751 | static inline struct t3_cqe *cxio_next_hw_cqe(struct t3_cq *cq) |
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c index b0ea0105ddf6..ee1d8b4d4541 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.c +++ b/drivers/infiniband/hw/cxgb3/iwch.c | |||
| @@ -65,6 +65,46 @@ struct cxgb3_client t3c_client = { | |||
| 65 | static LIST_HEAD(dev_list); | 65 | static LIST_HEAD(dev_list); |
| 66 | static DEFINE_MUTEX(dev_mutex); | 66 | static DEFINE_MUTEX(dev_mutex); |
| 67 | 67 | ||
| 68 | static int disable_qp_db(int id, void *p, void *data) | ||
| 69 | { | ||
| 70 | struct iwch_qp *qhp = p; | ||
| 71 | |||
| 72 | cxio_disable_wq_db(&qhp->wq); | ||
| 73 | return 0; | ||
| 74 | } | ||
| 75 | |||
| 76 | static int enable_qp_db(int id, void *p, void *data) | ||
| 77 | { | ||
| 78 | struct iwch_qp *qhp = p; | ||
| 79 | |||
| 80 | if (data) | ||
| 81 | ring_doorbell(qhp->rhp->rdev.ctrl_qp.doorbell, qhp->wq.qpid); | ||
| 82 | cxio_enable_wq_db(&qhp->wq); | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | |||
| 86 | static void disable_dbs(struct iwch_dev *rnicp) | ||
| 87 | { | ||
| 88 | spin_lock_irq(&rnicp->lock); | ||
| 89 | idr_for_each(&rnicp->qpidr, disable_qp_db, NULL); | ||
| 90 | spin_unlock_irq(&rnicp->lock); | ||
| 91 | } | ||
| 92 | |||
| 93 | static void enable_dbs(struct iwch_dev *rnicp, int ring_db) | ||
| 94 | { | ||
| 95 | spin_lock_irq(&rnicp->lock); | ||
| 96 | idr_for_each(&rnicp->qpidr, enable_qp_db, | ||
| 97 | (void *)(unsigned long)ring_db); | ||
| 98 | spin_unlock_irq(&rnicp->lock); | ||
| 99 | } | ||
| 100 | |||
| 101 | static void iwch_db_drop_task(struct work_struct *work) | ||
| 102 | { | ||
| 103 | struct iwch_dev *rnicp = container_of(work, struct iwch_dev, | ||
| 104 | db_drop_task.work); | ||
| 105 | enable_dbs(rnicp, 1); | ||
| 106 | } | ||
| 107 | |||
| 68 | static void rnic_init(struct iwch_dev *rnicp) | 108 | static void rnic_init(struct iwch_dev *rnicp) |
| 69 | { | 109 | { |
| 70 | PDBG("%s iwch_dev %p\n", __func__, rnicp); | 110 | PDBG("%s iwch_dev %p\n", __func__, rnicp); |
| @@ -72,6 +112,7 @@ static void rnic_init(struct iwch_dev *rnicp) | |||
| 72 | idr_init(&rnicp->qpidr); | 112 | idr_init(&rnicp->qpidr); |
| 73 | idr_init(&rnicp->mmidr); | 113 | idr_init(&rnicp->mmidr); |
| 74 | spin_lock_init(&rnicp->lock); | 114 | spin_lock_init(&rnicp->lock); |
| 115 | INIT_DELAYED_WORK(&rnicp->db_drop_task, iwch_db_drop_task); | ||
| 75 | 116 | ||
| 76 | rnicp->attr.max_qps = T3_MAX_NUM_QP - 32; | 117 | rnicp->attr.max_qps = T3_MAX_NUM_QP - 32; |
| 77 | rnicp->attr.max_wrs = T3_MAX_QP_DEPTH; | 118 | rnicp->attr.max_wrs = T3_MAX_QP_DEPTH; |
| @@ -147,6 +188,8 @@ static void close_rnic_dev(struct t3cdev *tdev) | |||
| 147 | mutex_lock(&dev_mutex); | 188 | mutex_lock(&dev_mutex); |
| 148 | list_for_each_entry_safe(dev, tmp, &dev_list, entry) { | 189 | list_for_each_entry_safe(dev, tmp, &dev_list, entry) { |
| 149 | if (dev->rdev.t3cdev_p == tdev) { | 190 | if (dev->rdev.t3cdev_p == tdev) { |
| 191 | dev->rdev.flags = CXIO_ERROR_FATAL; | ||
| 192 | cancel_delayed_work_sync(&dev->db_drop_task); | ||
| 150 | list_del(&dev->entry); | 193 | list_del(&dev->entry); |
| 151 | iwch_unregister_device(dev); | 194 | iwch_unregister_device(dev); |
| 152 | cxio_rdev_close(&dev->rdev); | 195 | cxio_rdev_close(&dev->rdev); |
| @@ -165,7 +208,8 @@ static void iwch_event_handler(struct t3cdev *tdev, u32 evt, u32 port_id) | |||
| 165 | struct cxio_rdev *rdev = tdev->ulp; | 208 | struct cxio_rdev *rdev = tdev->ulp; |
| 166 | struct iwch_dev *rnicp; | 209 | struct iwch_dev *rnicp; |
| 167 | struct ib_event event; | 210 | struct ib_event event; |
| 168 | u32 portnum = port_id + 1; | 211 | u32 portnum = port_id + 1; |
| 212 | int dispatch = 0; | ||
| 169 | 213 | ||
| 170 | if (!rdev) | 214 | if (!rdev) |
| 171 | return; | 215 | return; |
| @@ -174,21 +218,49 @@ static void iwch_event_handler(struct t3cdev *tdev, u32 evt, u32 port_id) | |||
| 174 | case OFFLOAD_STATUS_DOWN: { | 218 | case OFFLOAD_STATUS_DOWN: { |
| 175 | rdev->flags = CXIO_ERROR_FATAL; | 219 | rdev->flags = CXIO_ERROR_FATAL; |
| 176 | event.event = IB_EVENT_DEVICE_FATAL; | 220 | event.event = IB_EVENT_DEVICE_FATAL; |
| 221 | dispatch = 1; | ||
| 177 | break; | 222 | break; |
| 178 | } | 223 | } |
| 179 | case OFFLOAD_PORT_DOWN: { | 224 | case OFFLOAD_PORT_DOWN: { |
| 180 | event.event = IB_EVENT_PORT_ERR; | 225 | event.event = IB_EVENT_PORT_ERR; |
| 226 | dispatch = 1; | ||
| 181 | break; | 227 | break; |
| 182 | } | 228 | } |
| 183 | case OFFLOAD_PORT_UP: { | 229 | case OFFLOAD_PORT_UP: { |
| 184 | event.event = IB_EVENT_PORT_ACTIVE; | 230 | event.event = IB_EVENT_PORT_ACTIVE; |
| 231 | dispatch = 1; | ||
| 232 | break; | ||
| 233 | } | ||
| 234 | case OFFLOAD_DB_FULL: { | ||
| 235 | disable_dbs(rnicp); | ||
| 236 | break; | ||
| 237 | } | ||
| 238 | case OFFLOAD_DB_EMPTY: { | ||
| 239 | enable_dbs(rnicp, 1); | ||
| 240 | break; | ||
| 241 | } | ||
| 242 | case OFFLOAD_DB_DROP: { | ||
| 243 | unsigned long delay = 1000; | ||
| 244 | unsigned short r; | ||
| 245 | |||
| 246 | disable_dbs(rnicp); | ||
| 247 | get_random_bytes(&r, 2); | ||
| 248 | delay += r & 1023; | ||
| 249 | |||
| 250 | /* | ||
| 251 | * delay is between 1000-2023 usecs. | ||
| 252 | */ | ||
| 253 | schedule_delayed_work(&rnicp->db_drop_task, | ||
| 254 | usecs_to_jiffies(delay)); | ||
| 185 | break; | 255 | break; |
| 186 | } | 256 | } |
| 187 | } | 257 | } |
| 188 | 258 | ||
| 189 | event.device = &rnicp->ibdev; | 259 | if (dispatch) { |
| 190 | event.element.port_num = portnum; | 260 | event.device = &rnicp->ibdev; |
| 191 | ib_dispatch_event(&event); | 261 | event.element.port_num = portnum; |
| 262 | ib_dispatch_event(&event); | ||
| 263 | } | ||
| 192 | 264 | ||
| 193 | return; | 265 | return; |
| 194 | } | 266 | } |
diff --git a/drivers/infiniband/hw/cxgb3/iwch.h b/drivers/infiniband/hw/cxgb3/iwch.h index 84735506333f..a1c44578e039 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.h +++ b/drivers/infiniband/hw/cxgb3/iwch.h | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <linux/list.h> | 36 | #include <linux/list.h> |
| 37 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
| 38 | #include <linux/idr.h> | 38 | #include <linux/idr.h> |
| 39 | #include <linux/workqueue.h> | ||
| 39 | 40 | ||
| 40 | #include <rdma/ib_verbs.h> | 41 | #include <rdma/ib_verbs.h> |
| 41 | 42 | ||
| @@ -110,6 +111,7 @@ struct iwch_dev { | |||
| 110 | struct idr mmidr; | 111 | struct idr mmidr; |
| 111 | spinlock_t lock; | 112 | spinlock_t lock; |
| 112 | struct list_head entry; | 113 | struct list_head entry; |
| 114 | struct delayed_work db_drop_task; | ||
| 113 | }; | 115 | }; |
| 114 | 116 | ||
| 115 | static inline struct iwch_dev *to_iwch_dev(struct ib_device *ibdev) | 117 | static inline struct iwch_dev *to_iwch_dev(struct ib_device *ibdev) |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index ed7175549ebd..47b35c6608d2 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c | |||
| @@ -187,7 +187,7 @@ static struct ib_cq *iwch_create_cq(struct ib_device *ibdev, int entries, int ve | |||
| 187 | entries = roundup_pow_of_two(entries); | 187 | entries = roundup_pow_of_two(entries); |
| 188 | chp->cq.size_log2 = ilog2(entries); | 188 | chp->cq.size_log2 = ilog2(entries); |
| 189 | 189 | ||
| 190 | if (cxio_create_cq(&rhp->rdev, &chp->cq)) { | 190 | if (cxio_create_cq(&rhp->rdev, &chp->cq, !ucontext)) { |
| 191 | kfree(chp); | 191 | kfree(chp); |
| 192 | return ERR_PTR(-ENOMEM); | 192 | return ERR_PTR(-ENOMEM); |
| 193 | } | 193 | } |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index 3eb8cecf81d7..b4d893de3650 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c | |||
| @@ -452,7 +452,8 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
| 452 | ++(qhp->wq.sq_wptr); | 452 | ++(qhp->wq.sq_wptr); |
| 453 | } | 453 | } |
| 454 | spin_unlock_irqrestore(&qhp->lock, flag); | 454 | spin_unlock_irqrestore(&qhp->lock, flag); |
| 455 | ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid); | 455 | if (cxio_wq_db_enabled(&qhp->wq)) |
| 456 | ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid); | ||
| 456 | 457 | ||
| 457 | out: | 458 | out: |
| 458 | if (err) | 459 | if (err) |
| @@ -514,7 +515,8 @@ int iwch_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | |||
| 514 | num_wrs--; | 515 | num_wrs--; |
| 515 | } | 516 | } |
| 516 | spin_unlock_irqrestore(&qhp->lock, flag); | 517 | spin_unlock_irqrestore(&qhp->lock, flag); |
| 517 | ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid); | 518 | if (cxio_wq_db_enabled(&qhp->wq)) |
| 519 | ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid); | ||
| 518 | 520 | ||
| 519 | out: | 521 | out: |
| 520 | if (err) | 522 | if (err) |
| @@ -597,7 +599,8 @@ int iwch_bind_mw(struct ib_qp *qp, | |||
| 597 | ++(qhp->wq.sq_wptr); | 599 | ++(qhp->wq.sq_wptr); |
| 598 | spin_unlock_irqrestore(&qhp->lock, flag); | 600 | spin_unlock_irqrestore(&qhp->lock, flag); |
| 599 | 601 | ||
| 600 | ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid); | 602 | if (cxio_wq_db_enabled(&qhp->wq)) |
| 603 | ring_doorbell(qhp->wq.doorbell, qhp->wq.qpid); | ||
| 601 | 604 | ||
| 602 | return err; | 605 | return err; |
| 603 | } | 606 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index 42be0b15084b..b2b6fea2b141 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c | |||
| @@ -548,11 +548,10 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq) | |||
| 548 | struct ehca_eq *eq = &shca->eq; | 548 | struct ehca_eq *eq = &shca->eq; |
| 549 | struct ehca_eqe_cache_entry *eqe_cache = eq->eqe_cache; | 549 | struct ehca_eqe_cache_entry *eqe_cache = eq->eqe_cache; |
| 550 | u64 eqe_value, ret; | 550 | u64 eqe_value, ret; |
| 551 | unsigned long flags; | ||
| 552 | int eqe_cnt, i; | 551 | int eqe_cnt, i; |
| 553 | int eq_empty = 0; | 552 | int eq_empty = 0; |
| 554 | 553 | ||
| 555 | spin_lock_irqsave(&eq->irq_spinlock, flags); | 554 | spin_lock(&eq->irq_spinlock); |
| 556 | if (is_irq) { | 555 | if (is_irq) { |
| 557 | const int max_query_cnt = 100; | 556 | const int max_query_cnt = 100; |
| 558 | int query_cnt = 0; | 557 | int query_cnt = 0; |
| @@ -643,7 +642,7 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq) | |||
| 643 | } while (1); | 642 | } while (1); |
| 644 | 643 | ||
| 645 | unlock_irq_spinlock: | 644 | unlock_irq_spinlock: |
| 646 | spin_unlock_irqrestore(&eq->irq_spinlock, flags); | 645 | spin_unlock(&eq->irq_spinlock); |
| 647 | } | 646 | } |
| 648 | 647 | ||
| 649 | void ehca_tasklet_eq(unsigned long data) | 648 | void ehca_tasklet_eq(unsigned long data) |
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 0338f1fabe8a..b105f664d3ef 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
| @@ -55,9 +55,7 @@ static struct kmem_cache *qp_cache; | |||
| 55 | /* | 55 | /* |
| 56 | * attributes not supported by query qp | 56 | * attributes not supported by query qp |
| 57 | */ | 57 | */ |
| 58 | #define QP_ATTR_QUERY_NOT_SUPPORTED (IB_QP_MAX_DEST_RD_ATOMIC | \ | 58 | #define QP_ATTR_QUERY_NOT_SUPPORTED (IB_QP_ACCESS_FLAGS | \ |
| 59 | IB_QP_MAX_QP_RD_ATOMIC | \ | ||
| 60 | IB_QP_ACCESS_FLAGS | \ | ||
| 61 | IB_QP_EN_SQD_ASYNC_NOTIFY) | 59 | IB_QP_EN_SQD_ASYNC_NOTIFY) |
| 62 | 60 | ||
| 63 | /* | 61 | /* |
diff --git a/drivers/infiniband/hw/ehca/ehca_sqp.c b/drivers/infiniband/hw/ehca/ehca_sqp.c index 8c1213f8916a..dba8f9f8b996 100644 --- a/drivers/infiniband/hw/ehca/ehca_sqp.c +++ b/drivers/infiniband/hw/ehca/ehca_sqp.c | |||
| @@ -222,7 +222,7 @@ int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, | |||
| 222 | { | 222 | { |
| 223 | int ret; | 223 | int ret; |
| 224 | 224 | ||
| 225 | if (!port_num || port_num > ibdev->phys_port_cnt) | 225 | if (!port_num || port_num > ibdev->phys_port_cnt || !in_wc) |
| 226 | return IB_MAD_RESULT_FAILURE; | 226 | return IB_MAD_RESULT_FAILURE; |
| 227 | 227 | ||
| 228 | /* accept only pma request */ | 228 | /* accept only pma request */ |
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 3e8618b4efbc..4cd7f420766a 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h | |||
| @@ -264,6 +264,10 @@ struct adapter { | |||
| 264 | struct work_struct fatal_error_handler_task; | 264 | struct work_struct fatal_error_handler_task; |
| 265 | struct work_struct link_fault_handler_task; | 265 | struct work_struct link_fault_handler_task; |
| 266 | 266 | ||
| 267 | struct work_struct db_full_task; | ||
| 268 | struct work_struct db_empty_task; | ||
| 269 | struct work_struct db_drop_task; | ||
| 270 | |||
| 267 | struct dentry *debugfs_root; | 271 | struct dentry *debugfs_root; |
| 268 | 272 | ||
| 269 | struct mutex mdio_lock; | 273 | struct mutex mdio_lock; |
| @@ -335,6 +339,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, | |||
| 335 | int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx, | 339 | int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx, |
| 336 | unsigned char *data); | 340 | unsigned char *data); |
| 337 | irqreturn_t t3_sge_intr_msix(int irq, void *cookie); | 341 | irqreturn_t t3_sge_intr_msix(int irq, void *cookie); |
| 342 | extern struct workqueue_struct *cxgb3_wq; | ||
| 338 | 343 | ||
| 339 | int t3_get_edc_fw(struct cphy *phy, int edc_idx, int size); | 344 | int t3_get_edc_fw(struct cphy *phy, int edc_idx, int size); |
| 340 | 345 | ||
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 89bec9c3c141..37945fce7fa5 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #include <linux/firmware.h> | 45 | #include <linux/firmware.h> |
| 46 | #include <linux/log2.h> | 46 | #include <linux/log2.h> |
| 47 | #include <linux/stringify.h> | 47 | #include <linux/stringify.h> |
| 48 | #include <linux/sched.h> | ||
| 48 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
| 49 | 50 | ||
| 50 | #include "common.h" | 51 | #include "common.h" |
| @@ -140,7 +141,7 @@ MODULE_PARM_DESC(ofld_disable, "whether to enable offload at init time or not"); | |||
| 140 | * will block keventd as it needs the rtnl lock, and we'll deadlock waiting | 141 | * will block keventd as it needs the rtnl lock, and we'll deadlock waiting |
| 141 | * for our work to complete. Get our own work queue to solve this. | 142 | * for our work to complete. Get our own work queue to solve this. |
| 142 | */ | 143 | */ |
| 143 | static struct workqueue_struct *cxgb3_wq; | 144 | struct workqueue_struct *cxgb3_wq; |
| 144 | 145 | ||
| 145 | /** | 146 | /** |
| 146 | * link_report - show link status and link speed/duplex | 147 | * link_report - show link status and link speed/duplex |
| @@ -590,6 +591,19 @@ static void setup_rss(struct adapter *adap) | |||
| 590 | V_RRCPLCPUSIZE(6) | F_HASHTOEPLITZ, cpus, rspq_map); | 591 | V_RRCPLCPUSIZE(6) | F_HASHTOEPLITZ, cpus, rspq_map); |
| 591 | } | 592 | } |
| 592 | 593 | ||
| 594 | static void ring_dbs(struct adapter *adap) | ||
| 595 | { | ||
| 596 | int i, j; | ||
| 597 | |||
| 598 | for (i = 0; i < SGE_QSETS; i++) { | ||
| 599 | struct sge_qset *qs = &adap->sge.qs[i]; | ||
| 600 | |||
| 601 | if (qs->adap) | ||
| 602 | for (j = 0; j < SGE_TXQ_PER_SET; j++) | ||
| 603 | t3_write_reg(adap, A_SG_KDOORBELL, F_SELEGRCNTX | V_EGRCNTX(qs->txq[j].cntxt_id)); | ||
| 604 | } | ||
| 605 | } | ||
| 606 | |||
| 593 | static void init_napi(struct adapter *adap) | 607 | static void init_napi(struct adapter *adap) |
| 594 | { | 608 | { |
| 595 | int i; | 609 | int i; |
| @@ -2754,6 +2768,42 @@ static void t3_adap_check_task(struct work_struct *work) | |||
| 2754 | spin_unlock_irq(&adapter->work_lock); | 2768 | spin_unlock_irq(&adapter->work_lock); |
| 2755 | } | 2769 | } |
| 2756 | 2770 | ||
| 2771 | static void db_full_task(struct work_struct *work) | ||
| 2772 | { | ||
| 2773 | struct adapter *adapter = container_of(work, struct adapter, | ||
| 2774 | db_full_task); | ||
| 2775 | |||
| 2776 | cxgb3_event_notify(&adapter->tdev, OFFLOAD_DB_FULL, 0); | ||
| 2777 | } | ||
| 2778 | |||
| 2779 | static void db_empty_task(struct work_struct *work) | ||
| 2780 | { | ||
| 2781 | struct adapter *adapter = container_of(work, struct adapter, | ||
| 2782 | db_empty_task); | ||
| 2783 | |||
| 2784 | cxgb3_event_notify(&adapter->tdev, OFFLOAD_DB_EMPTY, 0); | ||
| 2785 | } | ||
| 2786 | |||
| 2787 | static void db_drop_task(struct work_struct *work) | ||
| 2788 | { | ||
| 2789 | struct adapter *adapter = container_of(work, struct adapter, | ||
| 2790 | db_drop_task); | ||
| 2791 | unsigned long delay = 1000; | ||
| 2792 | unsigned short r; | ||
| 2793 | |||
| 2794 | cxgb3_event_notify(&adapter->tdev, OFFLOAD_DB_DROP, 0); | ||
| 2795 | |||
| 2796 | /* | ||
| 2797 | * Sleep a while before ringing the driver qset dbs. | ||
| 2798 | * The delay is between 1000-2023 usecs. | ||
| 2799 | */ | ||
| 2800 | get_random_bytes(&r, 2); | ||
| 2801 | delay += r & 1023; | ||
| 2802 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 2803 | schedule_timeout(usecs_to_jiffies(delay)); | ||
| 2804 | ring_dbs(adapter); | ||
| 2805 | } | ||
| 2806 | |||
| 2757 | /* | 2807 | /* |
| 2758 | * Processes external (PHY) interrupts in process context. | 2808 | * Processes external (PHY) interrupts in process context. |
| 2759 | */ | 2809 | */ |
| @@ -3222,6 +3272,11 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
| 3222 | INIT_LIST_HEAD(&adapter->adapter_list); | 3272 | INIT_LIST_HEAD(&adapter->adapter_list); |
| 3223 | INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task); | 3273 | INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task); |
| 3224 | INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task); | 3274 | INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task); |
| 3275 | |||
| 3276 | INIT_WORK(&adapter->db_full_task, db_full_task); | ||
| 3277 | INIT_WORK(&adapter->db_empty_task, db_empty_task); | ||
| 3278 | INIT_WORK(&adapter->db_drop_task, db_drop_task); | ||
| 3279 | |||
| 3225 | INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task); | 3280 | INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task); |
| 3226 | 3281 | ||
| 3227 | for (i = 0; i < ai->nports0 + ai->nports1; ++i) { | 3282 | for (i = 0; i < ai->nports0 + ai->nports1; ++i) { |
diff --git a/drivers/net/cxgb3/cxgb3_offload.h b/drivers/net/cxgb3/cxgb3_offload.h index 670aa62042da..929c298115ca 100644 --- a/drivers/net/cxgb3/cxgb3_offload.h +++ b/drivers/net/cxgb3/cxgb3_offload.h | |||
| @@ -73,7 +73,10 @@ enum { | |||
| 73 | OFFLOAD_STATUS_UP, | 73 | OFFLOAD_STATUS_UP, |
| 74 | OFFLOAD_STATUS_DOWN, | 74 | OFFLOAD_STATUS_DOWN, |
| 75 | OFFLOAD_PORT_DOWN, | 75 | OFFLOAD_PORT_DOWN, |
| 76 | OFFLOAD_PORT_UP | 76 | OFFLOAD_PORT_UP, |
| 77 | OFFLOAD_DB_FULL, | ||
| 78 | OFFLOAD_DB_EMPTY, | ||
| 79 | OFFLOAD_DB_DROP | ||
| 77 | }; | 80 | }; |
| 78 | 81 | ||
| 79 | struct cxgb3_client { | 82 | struct cxgb3_client { |
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h index 1b5327b5a965..cb42353c9fdd 100644 --- a/drivers/net/cxgb3/regs.h +++ b/drivers/net/cxgb3/regs.h | |||
| @@ -254,6 +254,22 @@ | |||
| 254 | #define V_LOPIODRBDROPERR(x) ((x) << S_LOPIODRBDROPERR) | 254 | #define V_LOPIODRBDROPERR(x) ((x) << S_LOPIODRBDROPERR) |
| 255 | #define F_LOPIODRBDROPERR V_LOPIODRBDROPERR(1U) | 255 | #define F_LOPIODRBDROPERR V_LOPIODRBDROPERR(1U) |
| 256 | 256 | ||
| 257 | #define S_HIPRIORITYDBFULL 7 | ||
| 258 | #define V_HIPRIORITYDBFULL(x) ((x) << S_HIPRIORITYDBFULL) | ||
| 259 | #define F_HIPRIORITYDBFULL V_HIPRIORITYDBFULL(1U) | ||
| 260 | |||
| 261 | #define S_HIPRIORITYDBEMPTY 6 | ||
| 262 | #define V_HIPRIORITYDBEMPTY(x) ((x) << S_HIPRIORITYDBEMPTY) | ||
| 263 | #define F_HIPRIORITYDBEMPTY V_HIPRIORITYDBEMPTY(1U) | ||
| 264 | |||
| 265 | #define S_LOPRIORITYDBFULL 5 | ||
| 266 | #define V_LOPRIORITYDBFULL(x) ((x) << S_LOPRIORITYDBFULL) | ||
| 267 | #define F_LOPRIORITYDBFULL V_LOPRIORITYDBFULL(1U) | ||
| 268 | |||
| 269 | #define S_LOPRIORITYDBEMPTY 4 | ||
| 270 | #define V_LOPRIORITYDBEMPTY(x) ((x) << S_LOPRIORITYDBEMPTY) | ||
| 271 | #define F_LOPRIORITYDBEMPTY V_LOPRIORITYDBEMPTY(1U) | ||
| 272 | |||
| 257 | #define S_RSPQDISABLED 3 | 273 | #define S_RSPQDISABLED 3 |
| 258 | #define V_RSPQDISABLED(x) ((x) << S_RSPQDISABLED) | 274 | #define V_RSPQDISABLED(x) ((x) << S_RSPQDISABLED) |
| 259 | #define F_RSPQDISABLED V_RSPQDISABLED(1U) | 275 | #define F_RSPQDISABLED V_RSPQDISABLED(1U) |
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 318a018ca7c5..9b434461c4f1 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | #include "sge_defs.h" | 42 | #include "sge_defs.h" |
| 43 | #include "t3_cpl.h" | 43 | #include "t3_cpl.h" |
| 44 | #include "firmware_exports.h" | 44 | #include "firmware_exports.h" |
| 45 | #include "cxgb3_offload.h" | ||
| 45 | 46 | ||
| 46 | #define USE_GTS 0 | 47 | #define USE_GTS 0 |
| 47 | 48 | ||
| @@ -2833,8 +2834,13 @@ void t3_sge_err_intr_handler(struct adapter *adapter) | |||
| 2833 | } | 2834 | } |
| 2834 | 2835 | ||
| 2835 | if (status & (F_HIPIODRBDROPERR | F_LOPIODRBDROPERR)) | 2836 | if (status & (F_HIPIODRBDROPERR | F_LOPIODRBDROPERR)) |
| 2836 | CH_ALERT(adapter, "SGE dropped %s priority doorbell\n", | 2837 | queue_work(cxgb3_wq, &adapter->db_drop_task); |
| 2837 | status & F_HIPIODRBDROPERR ? "high" : "lo"); | 2838 | |
| 2839 | if (status & (F_HIPRIORITYDBFULL | F_LOPRIORITYDBFULL)) | ||
| 2840 | queue_work(cxgb3_wq, &adapter->db_full_task); | ||
| 2841 | |||
| 2842 | if (status & (F_HIPRIORITYDBEMPTY | F_LOPRIORITYDBEMPTY)) | ||
| 2843 | queue_work(cxgb3_wq, &adapter->db_empty_task); | ||
| 2838 | 2844 | ||
| 2839 | t3_write_reg(adapter, A_SG_INT_CAUSE, status); | 2845 | t3_write_reg(adapter, A_SG_INT_CAUSE, status); |
| 2840 | if (status & SGE_FATALERR) | 2846 | if (status & SGE_FATALERR) |
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 032cfe065570..c38fc717a0d1 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c | |||
| @@ -1432,7 +1432,10 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg, | |||
| 1432 | F_IRPARITYERROR | V_ITPARITYERROR(M_ITPARITYERROR) | \ | 1432 | F_IRPARITYERROR | V_ITPARITYERROR(M_ITPARITYERROR) | \ |
| 1433 | V_FLPARITYERROR(M_FLPARITYERROR) | F_LODRBPARITYERROR | \ | 1433 | V_FLPARITYERROR(M_FLPARITYERROR) | F_LODRBPARITYERROR | \ |
| 1434 | F_HIDRBPARITYERROR | F_LORCQPARITYERROR | \ | 1434 | F_HIDRBPARITYERROR | F_LORCQPARITYERROR | \ |
| 1435 | F_HIRCQPARITYERROR) | 1435 | F_HIRCQPARITYERROR | F_LOPRIORITYDBFULL | \ |
| 1436 | F_HIPRIORITYDBFULL | F_LOPRIORITYDBEMPTY | \ | ||
| 1437 | F_HIPRIORITYDBEMPTY | F_HIPIODRBDROPERR | \ | ||
| 1438 | F_LOPIODRBDROPERR) | ||
| 1436 | #define MC5_INTR_MASK (F_PARITYERR | F_ACTRGNFULL | F_UNKNOWNCMD | \ | 1439 | #define MC5_INTR_MASK (F_PARITYERR | F_ACTRGNFULL | F_UNKNOWNCMD | \ |
| 1437 | F_REQQPARERR | F_DISPQPARERR | F_DELACTEMPTY | \ | 1440 | F_REQQPARERR | F_DISPQPARERR | F_DELACTEMPTY | \ |
| 1438 | F_NFASRCHFAIL) | 1441 | F_NFASRCHFAIL) |
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 09509edb1c5f..a585e0f92bc3 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h | |||
| @@ -984,9 +984,9 @@ struct ib_device { | |||
| 984 | struct list_head event_handler_list; | 984 | struct list_head event_handler_list; |
| 985 | spinlock_t event_handler_lock; | 985 | spinlock_t event_handler_lock; |
| 986 | 986 | ||
| 987 | spinlock_t client_data_lock; | ||
| 987 | struct list_head core_list; | 988 | struct list_head core_list; |
| 988 | struct list_head client_data_list; | 989 | struct list_head client_data_list; |
| 989 | spinlock_t client_data_lock; | ||
| 990 | 990 | ||
| 991 | struct ib_cache cache; | 991 | struct ib_cache cache; |
| 992 | int *pkey_tbl_len; | 992 | int *pkey_tbl_len; |
| @@ -1144,8 +1144,8 @@ struct ib_device { | |||
| 1144 | IB_DEV_UNREGISTERED | 1144 | IB_DEV_UNREGISTERED |
| 1145 | } reg_state; | 1145 | } reg_state; |
| 1146 | 1146 | ||
| 1147 | u64 uverbs_cmd_mask; | ||
| 1148 | int uverbs_abi_ver; | 1147 | int uverbs_abi_ver; |
| 1148 | u64 uverbs_cmd_mask; | ||
| 1149 | 1149 | ||
| 1150 | char node_desc[64]; | 1150 | char node_desc[64]; |
| 1151 | __be64 node_guid; | 1151 | __be64 node_guid; |
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h index c6b2962315b3..4fae90304648 100644 --- a/include/rdma/rdma_cm.h +++ b/include/rdma/rdma_cm.h | |||
| @@ -67,7 +67,6 @@ enum rdma_port_space { | |||
| 67 | RDMA_PS_IPOIB = 0x0002, | 67 | RDMA_PS_IPOIB = 0x0002, |
| 68 | RDMA_PS_TCP = 0x0106, | 68 | RDMA_PS_TCP = 0x0106, |
| 69 | RDMA_PS_UDP = 0x0111, | 69 | RDMA_PS_UDP = 0x0111, |
| 70 | RDMA_PS_SCTP = 0x0183 | ||
| 71 | }; | 70 | }; |
| 72 | 71 | ||
| 73 | struct rdma_addr { | 72 | struct rdma_addr { |
