]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
RDS: IB: purge receive frag cache on connection shutdown
authorSantosh Shilimkar <santosh.shilimkar@oracle.com>
Mon, 21 Mar 2016 06:24:32 +0000 (23:24 -0700)
committerChuck Anderson <chuck.anderson@oracle.com>
Thu, 14 Apr 2016 00:58:38 +0000 (17:58 -0700)
RDS IB connections can be formed with different fragment size across
reconnect and hence the current frag cache needs to be purged to
avoid stale frag usages.

Orabug: 21894138
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
net/rds/ib.h
net/rds/ib_cm.c
net/rds/ib_recv.c

index e377bafc477c3a05429da6703b4feb43a27df14d..231e5de50828ce17373fa44b64f4771bd4c0e0db 100644 (file)
@@ -617,6 +617,7 @@ void rds_ib_recv_exit(void);
 int rds_ib_recv(struct rds_connection *conn);
 int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic);
 void rds_ib_recv_free_caches(struct rds_ib_connection *ic);
+void rds_ib_recv_purge_frag_cache(struct rds_ib_connection *ic);
 void rds_ib_recv_refill(struct rds_connection *conn, int prefill, gfp_t gfp);
 void rds_ib_inc_free(struct rds_incoming *inc);
 int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to);
index 59a07afb823665684dc95d7e4a385382ee635d11..a425a7690a870606acc33baa4db4f216c82bac64 100644 (file)
@@ -1304,6 +1304,9 @@ void rds_ib_conn_shutdown(struct rds_connection *conn)
 
        reinit_completion(&ic->i_last_wqe_complete);
 
+       /* Purge the ic->i_cache_frags */
+       rds_ib_recv_purge_frag_cache(ic);
+
        ic->i_active_side = 0;
 }
 
index aed1ecf7013485e0f0155318e0027b165b0031c7..cf6b63b0eac72e4c27f284a831bdfa555767006f 100644 (file)
@@ -195,6 +195,38 @@ void rds_ib_recv_free_caches(struct rds_ib_connection *ic)
        }
 }
 
+/* Called from rds_ib_conn_shutdown path on the way
+ * towards connection destroy or reconnect
+ */
+void rds_ib_recv_purge_frag_cache(struct rds_ib_connection *ic)
+{
+       struct rds_ib_cache_head *head;
+       struct rds_page_frag *frag, *frag_tmp;
+       LIST_HEAD(list);
+       int cpu;
+
+       rds_ib_cache_xfer_to_ready(&ic->i_cache_frags);
+       rds_ib_cache_splice_all_lists(&ic->i_cache_frags, &list);
+       atomic_set(&ic->i_cache_allocs, 0);
+
+       list_for_each_entry_safe(frag, frag_tmp, &list, f_cache_entry) {
+               list_del(&frag->f_cache_entry);
+               WARN_ON(!list_empty(&frag->f_item));
+               kmem_cache_free(rds_ib_frag_slab, frag);
+               rds_ib_stats_add(s_ib_recv_added_to_cache, ic->i_frag_sz);
+               rds_ib_stats_add(s_ib_recv_removed_from_cache, ic->i_frag_sz);
+       }
+
+       for_each_possible_cpu(cpu) {
+               head = per_cpu_ptr(ic->i_cache_frags.percpu, cpu);
+               head->first = NULL;
+               head->count = 0;
+       }
+
+       ic->i_cache_frags.xfer = NULL;
+       ic->i_cache_frags.ready = NULL;
+}
+
 /* fwd decl */
 static void rds_ib_recv_cache_put(struct list_head *new_item,
                                  struct rds_ib_refill_cache *cache);