staging/rdma/hfi1: Change send_schedule counter to a per cpu counter
authorVennila Megavannan <vennila.megavannan@intel.com>
Wed, 3 Feb 2016 22:34:07 +0000 (14:34 -0800)
committerDoug Ledford <dledford@redhat.com>
Fri, 11 Mar 2016 01:37:53 +0000 (20:37 -0500)
A patch to fix fairness issues in QP scheduling requires
n_send_schedule counter to be converted to a per cpu counter to reduce
cache misses.

Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Vennila Megavannan <vennila.megavannan@intel.com>
Signed-off-by: Jubin John <jubin.john@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/staging/rdma/hfi1/chip.c
drivers/staging/rdma/hfi1/hfi.h
drivers/staging/rdma/hfi1/init.c
drivers/staging/rdma/hfi1/ruc.c
drivers/staging/rdma/hfi1/verbs.h

index 6045c9154a1fc756075e15f5e09b99f9dfff9c2e..13b92a3d3d8bf98797950e5bcc7a3a830c696927 100644 (file)
@@ -1609,7 +1609,8 @@ static u64 access_sw_send_schedule(const struct cntr_entry *entry,
 {
        struct hfi1_devdata *dd = (struct hfi1_devdata *)context;
 
-       return dd->verbs_dev.n_send_schedule;
+       return read_write_cpu(dd, &dd->z_send_schedule, dd->send_schedule, vl,
+                             mode, data);
 }
 
 /* Software counters for the error status bits within MISC_ERR_STATUS */
index 571e7b10cd11cbc10babd5c75726ff390dbdb9f2..112f7902c623b9dc9d457398e90da1ebde316ef3 100644 (file)
@@ -898,10 +898,11 @@ struct hfi1_devdata {
        /* reset value */
        u64 z_int_counter;
        u64 z_rcv_limit;
+       u64 z_send_schedule;
        /* percpu int_counter */
        u64 __percpu *int_counter;
        u64 __percpu *rcv_limit;
-
+       u64 __percpu *send_schedule;
        /* number of receive contexts in use by the driver */
        u32 num_rcv_contexts;
        /* number of pio send contexts in use by the driver */
@@ -1884,6 +1885,7 @@ static inline void hfi1_reset_cpu_counters(struct hfi1_devdata *dd)
 
        dd->z_int_counter = get_all_cpu_total(dd->int_counter);
        dd->z_rcv_limit = get_all_cpu_total(dd->rcv_limit);
+       dd->z_send_schedule = get_all_cpu_total(dd->send_schedule);
 
        ppd = (struct hfi1_pportdata *)(dd + 1);
        for (i = 0; i < dd->num_pports; i++, ppd++) {
index 629e92aa4f0a9d42648bf95a358732134d3bfcd4..6ddf3c8bcc2e63d973ed8668e386284006fce81c 100644 (file)
@@ -985,6 +985,7 @@ void hfi1_free_devdata(struct hfi1_devdata *dd)
        free_percpu(dd->int_counter);
        free_percpu(dd->rcv_limit);
        hfi1_dev_affinity_free(dd);
+       free_percpu(dd->send_schedule);
        ib_dealloc_device(&dd->verbs_dev.rdi.ibdev);
 }
 
@@ -1063,6 +1064,14 @@ struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra)
                goto bail;
        }
 
+       dd->send_schedule = alloc_percpu(u64);
+       if (!dd->send_schedule) {
+               ret = -ENOMEM;
+               hfi1_early_err(&pdev->dev,
+                              "Could not allocate per-cpu int_counter\n");
+               goto bail;
+       }
+
        if (!hfi1_cpulist_count) {
                u32 count = num_online_cpus();
 
index 6379df53fa72503072128aabf90286d1113aa290..ae28b85b847537521f33964d8ebbb2001ec9c51f 100644 (file)
@@ -875,7 +875,7 @@ void hfi1_do_send(struct rvt_qp *qp)
                /* allow other tasks to run */
                if (unlikely(time_after(jiffies, timeout))) {
                        cond_resched();
-                       ps.ppd->dd->verbs_dev.n_send_schedule++;
+                       this_cpu_inc(*ps.ppd->dd->send_schedule);
                        timeout = jiffies + SEND_RESCHED_TIMEOUT;
                }
        } while (make_req(qp));
index 1571ae390042a5ce3ee6c5afbf9958c759218e32..ac84dd70c6c7372bc883f0194d1dcd4e3c8e4f87 100644 (file)
@@ -270,7 +270,6 @@ struct hfi1_ibdev {
        u64 n_piowait;
        u64 n_txwait;
        u64 n_kmem_wait;
-       u64 n_send_schedule;
 
 #ifdef CONFIG_DEBUG_FS
        /* per HFI debugfs */