From: Wengang Wang Date: Thu, 7 Apr 2016 07:29:43 +0000 (+0800) Subject: RDS: Fix the atomicity for congestion map update X-Git-Tag: v4.1.12-92~175^2~3 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=7406144f537e6ac49a74a45549e20124404c035c;p=users%2Fjedix%2Flinux-maple.git RDS: Fix the atomicity for congestion map update Orabug: 23022620 (UEK4) QuickRef: 22118109 (UEK2) Two different threads with different rds sockets may be in rds_recv_rcvbuf_delta() via receive path. If their ports both map to the same word in the congestion map, then using non-atomic ops to update it could cause the map to be incorrect. Lets use atomics to avoid such an issue. Full credit to Wengang for finding the issue, analysing it and also pointing out to offending code with spin lock based fix. Signed-off-by: Wengang Wang Signed-off-by: Santosh Shilimkar --- diff --git a/net/rds/cong.c b/net/rds/cong.c index e71527776b68..2cd81c3502b7 100644 --- a/net/rds/cong.c +++ b/net/rds/cong.c @@ -306,7 +306,7 @@ void rds_cong_set_bit(struct rds_cong_map *map, __be16 port) i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS; off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS; - __set_bit_le(off, (void *)map->m_page_addrs[i]); + set_bit_le(off, (void *)map->m_page_addrs[i]); } void rds_cong_clear_bit(struct rds_cong_map *map, __be16 port) @@ -320,7 +320,7 @@ void rds_cong_clear_bit(struct rds_cong_map *map, __be16 port) i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS; off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS; - __clear_bit_le(off, (void *)map->m_page_addrs[i]); + clear_bit_le(off, (void *)map->m_page_addrs[i]); } static int rds_cong_test_bit(struct rds_cong_map *map, __be16 port)