RDS: flush fmrs before allocating new ones
authorChris Mason <chris.mason@oracle.com>
Tue, 20 Jul 2010 00:06:46 +0000 (17:06 -0700)
committerAndy Grover <andy.grover@oracle.com>
Thu, 9 Sep 2010 01:16:42 +0000 (18:16 -0700)
Flushing FMRs is somewhat expensive, and is currently kicked off when
the interrupt handler notices that we are getting low.  The result of
this is that FMR flushing only happens from the interrupt cpus.

This spreads the load more effectively by triggering flushes just before
we allocate a new FMR.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
net/rds/ib_rdma.c

index 3efdddc39d49ba64fe894d815f198343fb8526f6..0017964f2fcf028ab1b8baa6a8b33e3678e6de53 100644 (file)
@@ -38,6 +38,8 @@
 #include "ib.h"
 #include "xlist.h"
 
+struct workqueue_struct *rds_ib_fmr_wq;
+
 static DEFINE_PER_CPU(unsigned long, clean_list_grace);
 #define CLEAN_LIST_BUSY_BIT 0
 
@@ -304,6 +306,9 @@ static struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev)
        struct rds_ib_mr *ibmr = NULL;
        int err = 0, iter = 0;
 
+       if (atomic_read(&pool->dirty_count) >= pool->max_items / 10)
+               queue_delayed_work(rds_ib_fmr_wq, &pool->flush_worker, 10);
+
        while (1) {
                ibmr = rds_ib_reuse_fmr(pool);
                if (ibmr)
@@ -691,8 +696,6 @@ out_nolock:
        return ret;
 }
 
-struct workqueue_struct *rds_ib_fmr_wq;
-
 int rds_ib_fmr_init(void)
 {
        rds_ib_fmr_wq = create_workqueue("rds_fmr_flushd");