Commit 2dd3c1df authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' from master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband

parents 5c382300 a1c337af
...@@ -69,6 +69,7 @@ struct ib_uverbs_event_file { ...@@ -69,6 +69,7 @@ struct ib_uverbs_event_file {
struct ib_uverbs_file { struct ib_uverbs_file {
struct kref ref; struct kref ref;
struct semaphore mutex;
struct ib_uverbs_device *device; struct ib_uverbs_device *device;
struct ib_ucontext *ucontext; struct ib_ucontext *ucontext;
struct ib_event_handler event_handler; struct ib_event_handler event_handler;
......
...@@ -76,8 +76,9 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, ...@@ -76,8 +76,9 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
struct ib_uverbs_get_context_resp resp; struct ib_uverbs_get_context_resp resp;
struct ib_udata udata; struct ib_udata udata;
struct ib_device *ibdev = file->device->ib_dev; struct ib_device *ibdev = file->device->ib_dev;
struct ib_ucontext *ucontext;
int i; int i;
int ret = in_len; int ret;
if (out_len < sizeof resp) if (out_len < sizeof resp)
return -ENOSPC; return -ENOSPC;
...@@ -85,45 +86,56 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, ...@@ -85,45 +86,56 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd)) if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT; return -EFAULT;
down(&file->mutex);
if (file->ucontext) {
ret = -EINVAL;
goto err;
}
INIT_UDATA(&udata, buf + sizeof cmd, INIT_UDATA(&udata, buf + sizeof cmd,
(unsigned long) cmd.response + sizeof resp, (unsigned long) cmd.response + sizeof resp,
in_len - sizeof cmd, out_len - sizeof resp); in_len - sizeof cmd, out_len - sizeof resp);
file->ucontext = ibdev->alloc_ucontext(ibdev, &udata); ucontext = ibdev->alloc_ucontext(ibdev, &udata);
if (IS_ERR(file->ucontext)) { if (IS_ERR(ucontext))
ret = PTR_ERR(file->ucontext); return PTR_ERR(file->ucontext);
file->ucontext = NULL;
return ret;
}
file->ucontext->device = ibdev; ucontext->device = ibdev;
INIT_LIST_HEAD(&file->ucontext->pd_list); INIT_LIST_HEAD(&ucontext->pd_list);
INIT_LIST_HEAD(&file->ucontext->mr_list); INIT_LIST_HEAD(&ucontext->mr_list);
INIT_LIST_HEAD(&file->ucontext->mw_list); INIT_LIST_HEAD(&ucontext->mw_list);
INIT_LIST_HEAD(&file->ucontext->cq_list); INIT_LIST_HEAD(&ucontext->cq_list);
INIT_LIST_HEAD(&file->ucontext->qp_list); INIT_LIST_HEAD(&ucontext->qp_list);
INIT_LIST_HEAD(&file->ucontext->srq_list); INIT_LIST_HEAD(&ucontext->srq_list);
INIT_LIST_HEAD(&file->ucontext->ah_list); INIT_LIST_HEAD(&ucontext->ah_list);
spin_lock_init(&file->ucontext->lock);
resp.async_fd = file->async_file.fd; resp.async_fd = file->async_file.fd;
for (i = 0; i < file->device->num_comp; ++i) for (i = 0; i < file->device->num_comp; ++i)
if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab + if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab +
i * sizeof (__u32), i * sizeof (__u32),
&file->comp_file[i].fd, sizeof (__u32))) &file->comp_file[i].fd, sizeof (__u32))) {
goto err; ret = -EFAULT;
goto err_free;
}
if (copy_to_user((void __user *) (unsigned long) cmd.response, if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) &resp, sizeof resp)) {
goto err; ret = -EFAULT;
goto err_free;
}
file->ucontext = ucontext;
up(&file->mutex);
return in_len; return in_len;
err: err_free:
ibdev->dealloc_ucontext(file->ucontext); ibdev->dealloc_ucontext(ucontext);
file->ucontext = NULL;
return -EFAULT; err:
up(&file->mutex);
return ret;
} }
ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
...@@ -352,9 +364,9 @@ retry: ...@@ -352,9 +364,9 @@ retry:
if (ret) if (ret)
goto err_pd; goto err_pd;
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_add_tail(&uobj->list, &file->ucontext->pd_list); list_add_tail(&uobj->list, &file->ucontext->pd_list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
memset(&resp, 0, sizeof resp); memset(&resp, 0, sizeof resp);
resp.pd_handle = uobj->id; resp.pd_handle = uobj->id;
...@@ -368,9 +380,9 @@ retry: ...@@ -368,9 +380,9 @@ retry:
return in_len; return in_len;
err_list: err_list:
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_del(&uobj->list); list_del(&uobj->list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
down(&ib_uverbs_idr_mutex); down(&ib_uverbs_idr_mutex);
idr_remove(&ib_uverbs_pd_idr, uobj->id); idr_remove(&ib_uverbs_pd_idr, uobj->id);
...@@ -410,9 +422,9 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file, ...@@ -410,9 +422,9 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle); idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle);
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_del(&uobj->list); list_del(&uobj->list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
kfree(uobj); kfree(uobj);
...@@ -512,9 +524,9 @@ retry: ...@@ -512,9 +524,9 @@ retry:
resp.mr_handle = obj->uobject.id; resp.mr_handle = obj->uobject.id;
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
if (copy_to_user((void __user *) (unsigned long) cmd.response, if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) { &resp, sizeof resp)) {
...@@ -527,9 +539,9 @@ retry: ...@@ -527,9 +539,9 @@ retry:
return in_len; return in_len;
err_list: err_list:
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_del(&obj->uobject.list); list_del(&obj->uobject.list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
err_unreg: err_unreg:
ib_dereg_mr(mr); ib_dereg_mr(mr);
...@@ -570,9 +582,9 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, ...@@ -570,9 +582,9 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle); idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle);
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_del(&memobj->uobject.list); list_del(&memobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
ib_umem_release(file->device->ib_dev, &memobj->umem); ib_umem_release(file->device->ib_dev, &memobj->umem);
kfree(memobj); kfree(memobj);
...@@ -647,9 +659,9 @@ retry: ...@@ -647,9 +659,9 @@ retry:
if (ret) if (ret)
goto err_cq; goto err_cq;
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
memset(&resp, 0, sizeof resp); memset(&resp, 0, sizeof resp);
resp.cq_handle = uobj->uobject.id; resp.cq_handle = uobj->uobject.id;
...@@ -664,9 +676,9 @@ retry: ...@@ -664,9 +676,9 @@ retry:
return in_len; return in_len;
err_list: err_list:
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_del(&uobj->uobject.list); list_del(&uobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
down(&ib_uverbs_idr_mutex); down(&ib_uverbs_idr_mutex);
idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id); idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id);
...@@ -712,9 +724,9 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, ...@@ -712,9 +724,9 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle); idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle);
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_del(&uobj->uobject.list); list_del(&uobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
spin_lock_irq(&file->comp_file[0].lock); spin_lock_irq(&file->comp_file[0].lock);
list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) { list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) {
...@@ -847,9 +859,9 @@ retry: ...@@ -847,9 +859,9 @@ retry:
resp.qp_handle = uobj->uobject.id; resp.qp_handle = uobj->uobject.id;
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list); list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
if (copy_to_user((void __user *) (unsigned long) cmd.response, if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) { &resp, sizeof resp)) {
...@@ -862,9 +874,9 @@ retry: ...@@ -862,9 +874,9 @@ retry:
return in_len; return in_len;
err_list: err_list:
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_del(&uobj->uobject.list); list_del(&uobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
err_destroy: err_destroy:
ib_destroy_qp(qp); ib_destroy_qp(qp);
...@@ -989,9 +1001,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, ...@@ -989,9 +1001,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle); idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle);
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_del(&uobj->uobject.list); list_del(&uobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
spin_lock_irq(&file->async_file.lock); spin_lock_irq(&file->async_file.lock);
list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
...@@ -1136,9 +1148,9 @@ retry: ...@@ -1136,9 +1148,9 @@ retry:
resp.srq_handle = uobj->uobject.id; resp.srq_handle = uobj->uobject.id;
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
if (copy_to_user((void __user *) (unsigned long) cmd.response, if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) { &resp, sizeof resp)) {
...@@ -1151,9 +1163,9 @@ retry: ...@@ -1151,9 +1163,9 @@ retry:
return in_len; return in_len;
err_list: err_list:
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_del(&uobj->uobject.list); list_del(&uobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
err_destroy: err_destroy:
ib_destroy_srq(srq); ib_destroy_srq(srq);
...@@ -1227,9 +1239,9 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, ...@@ -1227,9 +1239,9 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle); idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle);
spin_lock_irq(&file->ucontext->lock); down(&file->mutex);
list_del(&uobj->uobject.list); list_del(&uobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock); up(&file->mutex);
spin_lock_irq(&file->async_file.lock); spin_lock_irq(&file->async_file.lock);
list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
......
...@@ -448,7 +448,9 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, ...@@ -448,7 +448,9 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
if (hdr.in_words * 4 != count) if (hdr.in_words * 4 != count)
return -EINVAL; return -EINVAL;
if (hdr.command < 0 || hdr.command >= ARRAY_SIZE(uverbs_cmd_table)) if (hdr.command < 0 ||
hdr.command >= ARRAY_SIZE(uverbs_cmd_table) ||
!uverbs_cmd_table[hdr.command])
return -EINVAL; return -EINVAL;
if (!file->ucontext && if (!file->ucontext &&
...@@ -484,27 +486,29 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) ...@@ -484,27 +486,29 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
file = kmalloc(sizeof *file + file = kmalloc(sizeof *file +
(dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file), (dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file),
GFP_KERNEL); GFP_KERNEL);
if (!file) if (!file) {
return -ENOMEM; ret = -ENOMEM;
goto err;
}
file->device = dev; file->device = dev;
kref_init(&file->ref); kref_init(&file->ref);
init_MUTEX(&file->mutex);
file->ucontext = NULL; file->ucontext = NULL;
kref_get(&file->ref);
ret = ib_uverbs_event_init(&file->async_file, file); ret = ib_uverbs_event_init(&file->async_file, file);
if (ret) if (ret)
goto err; goto err_kref;
file->async_file.is_async = 1; file->async_file.is_async = 1;
kref_get(&file->ref);
for (i = 0; i < dev->num_comp; ++i) { for (i = 0; i < dev->num_comp; ++i) {
kref_get(&file->ref);
ret = ib_uverbs_event_init(&file->comp_file[i], file); ret = ib_uverbs_event_init(&file->comp_file[i], file);
if (ret) if (ret)
goto err_async; goto err_async;
kref_get(&file->ref);
file->comp_file[i].is_async = 0; file->comp_file[i].is_async = 0;
} }
...@@ -524,9 +528,16 @@ err_async: ...@@ -524,9 +528,16 @@ err_async:
ib_uverbs_event_release(&file->async_file); ib_uverbs_event_release(&file->async_file);
err: err_kref:
/*
* One extra kref_put() because we took a reference before the
* event file creation that failed and got us here.
*/
kref_put(&file->ref, ib_uverbs_release_file);
kref_put(&file->ref, ib_uverbs_release_file); kref_put(&file->ref, ib_uverbs_release_file);
err:
module_put(dev->ib_dev->owner);
return ret; return ret;
} }
......
...@@ -605,7 +605,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, ...@@ -605,7 +605,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm,
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i, ++nent) { for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i) {
if (virt != -1) { if (virt != -1) {
pages[nent * 2] = cpu_to_be64(virt); pages[nent * 2] = cpu_to_be64(virt);
virt += 1 << lg; virt += 1 << lg;
...@@ -616,7 +616,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, ...@@ -616,7 +616,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm,
ts += 1 << (lg - 10); ts += 1 << (lg - 10);
++tc; ++tc;
if (nent == MTHCA_MAILBOX_SIZE / 16) { if (++nent == MTHCA_MAILBOX_SIZE / 16) {
err = mthca_cmd(dev, mailbox->dma, nent, 0, op, err = mthca_cmd(dev, mailbox->dma, nent, 0, op,
CMD_TIME_CLASS_B, status); CMD_TIME_CLASS_B, status);
if (err || *status) if (err || *status)
......
...@@ -836,7 +836,7 @@ int __devinit mthca_init_eq_table(struct mthca_dev *dev) ...@@ -836,7 +836,7 @@ int __devinit mthca_init_eq_table(struct mthca_dev *dev)
dev->eq_table.clr_mask = dev->eq_table.clr_mask =
swab32(1 << (dev->eq_table.inta_pin & 31)); swab32(1 << (dev->eq_table.inta_pin & 31));
dev->eq_table.clr_int = dev->clr_base + dev->eq_table.clr_int = dev->clr_base +
(dev->eq_table.inta_pin < 31 ? 4 : 0); (dev->eq_table.inta_pin < 32 ? 4 : 0);
} }
dev->eq_table.arm_mask = 0; dev->eq_table.arm_mask = 0;
......
...@@ -290,7 +290,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev, ...@@ -290,7 +290,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
int i; int i;
u8 status; u8 status;
num_icm = obj_size * nobj / MTHCA_TABLE_CHUNK_SIZE; num_icm = (obj_size * nobj + MTHCA_TABLE_CHUNK_SIZE - 1) / MTHCA_TABLE_CHUNK_SIZE;
table = kmalloc(sizeof *table + num_icm * sizeof *table->icm, GFP_KERNEL); table = kmalloc(sizeof *table + num_icm * sizeof *table->icm, GFP_KERNEL);
if (!table) if (!table)
...@@ -529,12 +529,25 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db) ...@@ -529,12 +529,25 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db)
goto found; goto found;
} }
for (i = start; i != end; i += dir)
if (!dev->db_tab->page[i].db_rec) {
page = dev->db_tab->page + i;
goto alloc;
}
if (dev->db_tab->max_group1 >= dev->db_tab->min_group2 - 1) { if (dev->db_tab->max_group1 >= dev->db_tab->min_group2 - 1) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
if (group == 0)
++dev->db_tab->max_group1;
else
--dev->db_tab->min_group2;
page = dev->db_tab->page + end; page = dev->db_tab->page + end;
alloc:
page->db_rec = dma_alloc_coherent(&dev->pdev->dev, 4096, page->db_rec = dma_alloc_coherent(&dev->pdev->dev, 4096,
&page->mapping, GFP_KERNEL); &page->mapping, GFP_KERNEL);
if (!page->db_rec) { if (!page->db_rec) {
...@@ -554,10 +567,6 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db) ...@@ -554,10 +567,6 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db)
} }
bitmap_zero(page->used, MTHCA_DB_REC_PER_PAGE); bitmap_zero(page->used, MTHCA_DB_REC_PER_PAGE);
if (group == 0)
++dev->db_tab->max_group1;
else
--dev->db_tab->min_group2;
found: found:
j = find_first_zero_bit(page->used, MTHCA_DB_REC_PER_PAGE); j = find_first_zero_bit(page->used, MTHCA_DB_REC_PER_PAGE);
......
...@@ -84,7 +84,7 @@ static int mthca_query_device(struct ib_device *ibdev, ...@@ -84,7 +84,7 @@ static int mthca_query_device(struct ib_device *ibdev,
props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) & props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) &
0xffffff; 0xffffff;
props->vendor_part_id = be16_to_cpup((__be16 *) (out_mad->data + 30)); props->vendor_part_id = be16_to_cpup((__be16 *) (out_mad->data + 30));
props->hw_ver = be16_to_cpup((__be16 *) (out_mad->data + 32)); props->hw_ver = be32_to_cpup((__be32 *) (out_mad->data + 32));
memcpy(&props->sys_image_guid, out_mad->data + 4, 8); memcpy(&props->sys_image_guid, out_mad->data + 4, 8);
memcpy(&props->node_guid, out_mad->data + 12, 8); memcpy(&props->node_guid, out_mad->data + 12, 8);
......
...@@ -665,7 +665,6 @@ struct ib_ucontext { ...@@ -665,7 +665,6 @@ struct ib_ucontext {
struct list_head qp_list; struct list_head qp_list;
struct list_head srq_list; struct list_head srq_list;
struct list_head ah_list; struct list_head ah_list;
spinlock_t lock;
}; };
struct ib_uobject { struct ib_uobject {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment