]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
rds: rds-stress show all zeros after few minutes
authorshamir rabinovitch <shamir.rabinovitch@oracle.com>
Wed, 16 Mar 2016 13:57:19 +0000 (09:57 -0400)
committerChuck Anderson <chuck.anderson@oracle.com>
Thu, 14 Apr 2016 01:38:32 +0000 (18:38 -0700)
Issue can be seen on platforms that use 8K and above page size
while rds fragment size is 4K. On those platforms single page is
shared between 2 or more rds fragments. Each fragment has it's own
offeset and rds cong map code need to take this offset to account.
Not taking this offset to account lead to reading the data fragment
as congestion map fragment and hang of the rds transmit due to far
cong map corruption.

Orabug: 23045970

Reviewed-by: Wengang Wang <wen.gang.wang@oracle.com>
Reviewed-by: Ajaykumar Hotchandani <ajaykumar.hotchandani@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Tested-by: Anand Bibhuti <anand.bibhuti@oracle.com>
Signed-off-by: shamir rabinovitch <shamir.rabinovitch@oracle.com>
net/rds/ib_recv.c
net/rds/iw_recv.c
net/rds/page.c

index cf6b63b0eac72e4c27f284a831bdfa555767006f..6eb1b3f795ec705147fdb0628df7665829b081c4 100644 (file)
@@ -1029,7 +1029,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn,
 
                addr = kmap_atomic(sg_page(&frag->f_sg));
 
-               src = addr + frag_off;
+               src = addr + frag->f_sg.offset + frag_off;
                dst = (void *)map->m_page_addrs[map_page] + map_off;
                for (k = 0; k < to_copy; k += 8) {
                        /* Record ports that became uncongested, ie
index ec21cc5b21eb38ece439f4ba09e06f1f6a67b192..7da890685c5571e6df552e689b198be58b5965e9 100644 (file)
@@ -586,7 +586,7 @@ static void rds_iw_cong_recv(struct rds_connection *conn,
 
                addr = kmap_atomic(frag->f_page);
 
-               src = addr + frag_off;
+               src = addr +  frag->f_offset + frag_off;
                dst = (void *)map->m_page_addrs[map_page] + map_off;
                for (k = 0; k < to_copy; k += 8) {
                        /* Record ports that became uncongested, ie
index c09f29655dfd3e46fbb600cb8cd8898998dc94e4..1dae848832918a5de712ecea6083e681194a5db4 100644 (file)
@@ -156,8 +156,9 @@ int rds_page_remainder_alloc(struct scatterlist *scat, unsigned long bytes,
                        if (rem->r_offset != 0)
                                rds_stats_inc(s_page_remainder_hit);
 
-                       rem->r_offset += bytes;
-                       if (rem->r_offset == PAGE_SIZE) {
+                       /* some hw (e.g. sparc) require aligned memory */
+                       rem->r_offset += ALIGN(bytes, 8);
+                       if (rem->r_offset >= PAGE_SIZE) {
                                __free_page(rem->r_page);
                                rem->r_page = NULL;
                        }