Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
[linux-2.6-microblaze.git] / drivers / infiniband / hw / hfi1 / pio.c
index d89b874..615be68 100644 (file)
@@ -758,6 +758,7 @@ struct send_context *sc_alloc(struct hfi1_devdata *dd, int type,
        sc->hw_context = hw_context;
        cr_group_addresses(sc, &dma);
        sc->credits = sci->credits;
+       sc->size = sc->credits * PIO_BLOCK_SIZE;
 
 /* PIO Send Memory Address details */
 #define PIO_ADDR_CONTEXT_MASK 0xfful
@@ -1242,6 +1243,7 @@ int sc_enable(struct send_context *sc)
        sc->free = 0;
        sc->alloc_free = 0;
        sc->fill = 0;
+       sc->fill_wrap = 0;
        sc->sr_head = 0;
        sc->sr_tail = 0;
        sc->flags = 0;
@@ -1385,7 +1387,7 @@ struct pio_buf *sc_buffer_alloc(struct send_context *sc, u32 dw_len,
        unsigned long flags;
        unsigned long avail;
        unsigned long blocks = dwords_to_blocks(dw_len);
-       unsigned long start_fill;
+       u32 fill_wrap;
        int trycount = 0;
        u32 head, next;
 
@@ -1410,9 +1412,7 @@ retry:
                        (sc->fill - sc->alloc_free);
                if (blocks > avail) {
                        /* still no room, actively update */
-                       spin_unlock_irqrestore(&sc->alloc_lock, flags);
                        sc_release_update(sc);
-                       spin_lock_irqsave(&sc->alloc_lock, flags);
                        sc->alloc_free = ACCESS_ONCE(sc->free);
                        trycount++;
                        goto retry;
@@ -1428,8 +1428,11 @@ retry:
        head = sc->sr_head;
 
        /* "allocate" the buffer */
-       start_fill = sc->fill;
        sc->fill += blocks;
+       fill_wrap = sc->fill_wrap;
+       sc->fill_wrap += blocks;
+       if (sc->fill_wrap >= sc->credits)
+               sc->fill_wrap = sc->fill_wrap - sc->credits;
 
        /*
         * Fill the parts that the releaser looks at before moving the head.
@@ -1458,11 +1461,8 @@ retry:
        spin_unlock_irqrestore(&sc->alloc_lock, flags);
 
        /* finish filling in the buffer outside the lock */
-       pbuf->start = sc->base_addr + ((start_fill % sc->credits)
-                                                       * PIO_BLOCK_SIZE);
-       pbuf->size = sc->credits * PIO_BLOCK_SIZE;
-       pbuf->end = sc->base_addr + pbuf->size;
-       pbuf->block_count = blocks;
+       pbuf->start = sc->base_addr + fill_wrap * PIO_BLOCK_SIZE;
+       pbuf->end = sc->base_addr + sc->size;
        pbuf->qw_written = 0;
        pbuf->carry_bytes = 0;
        pbuf->carry.val64 = 0;
@@ -1573,6 +1573,7 @@ static void sc_piobufavail(struct send_context *sc)
                qp = iowait_to_qp(wait);
                priv = qp->priv;
                list_del_init(&priv->s_iowait.list);
+               priv->s_iowait.lock = NULL;
                /* refcount held until actual wake up */
                qps[n++] = qp;
        }
@@ -2028,29 +2029,17 @@ freesc15:
 int init_credit_return(struct hfi1_devdata *dd)
 {
        int ret;
-       int num_numa;
        int i;
 
-       num_numa = num_online_nodes();
-       /* enforce the expectation that the numas are compact */
-       for (i = 0; i < num_numa; i++) {
-               if (!node_online(i)) {
-                       dd_dev_err(dd, "NUMA nodes are not compact\n");
-                       ret = -EINVAL;
-                       goto done;
-               }
-       }
-
        dd->cr_base = kcalloc(
-               num_numa,
+               node_affinity.num_possible_nodes,
                sizeof(struct credit_return_base),
                GFP_KERNEL);
        if (!dd->cr_base) {
-               dd_dev_err(dd, "Unable to allocate credit return base\n");
                ret = -ENOMEM;
                goto done;
        }
-       for (i = 0; i < num_numa; i++) {
+       for_each_node_with_cpus(i) {
                int bytes = TXE_NUM_CONTEXTS * sizeof(struct credit_return);
 
                set_dev_node(&dd->pcidev->dev, i);
@@ -2077,14 +2066,11 @@ done:
 
 void free_credit_return(struct hfi1_devdata *dd)
 {
-       int num_numa;
        int i;
 
        if (!dd->cr_base)
                return;
-
-       num_numa = num_online_nodes();
-       for (i = 0; i < num_numa; i++) {
+       for (i = 0; i < node_affinity.num_possible_nodes; i++) {
                if (dd->cr_base[i].va) {
                        dma_free_coherent(&dd->pcidev->dev,
                                          TXE_NUM_CONTEXTS *