aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
authorCong Wang <amwang@redhat.com>2013-01-16 03:05:05 -0500
committerSteffen Klassert <steffen.klassert@secunet.com>2013-01-16 05:03:34 -0500
commit44abdc3047aecafc141dfbaf1ed4bcb77f5d1652 (patch)
treed50e8326017691dee504c529b3adbaa98d72fd7c /net/xfrm
parent0024dc5371b41abb30217bbcaa708d35f49fe273 (diff)
xfrm: replace rwlock on xfrm_state_afinfo with rcu
Similar to commit 418a99ac6ad487dc9c42e6b0e85f941af56330f2 (Replace rwlock on xfrm_policy_afinfo with rcu), the rwlock on xfrm_state_afinfo can be replaced by RCU too. Cc: Steffen Klassert <steffen.klassert@secunet.com> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: "David S. Miller" <davem@davemloft.net> Signed-off-by: Cong Wang <amwang@redhat.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_state.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 05db2362a231..64780a6f7b86 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -158,8 +158,8 @@ out_unlock:
158 mutex_unlock(&hash_resize_mutex); 158 mutex_unlock(&hash_resize_mutex);
159} 159}
160 160
161static DEFINE_RWLOCK(xfrm_state_afinfo_lock); 161static DEFINE_SPINLOCK(xfrm_state_afinfo_lock);
162static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO]; 162static struct xfrm_state_afinfo __rcu *xfrm_state_afinfo[NPROTO];
163 163
164static DEFINE_SPINLOCK(xfrm_state_gc_lock); 164static DEFINE_SPINLOCK(xfrm_state_gc_lock);
165 165
@@ -173,17 +173,16 @@ static struct xfrm_state_afinfo *xfrm_state_lock_afinfo(unsigned int family)
173 struct xfrm_state_afinfo *afinfo; 173 struct xfrm_state_afinfo *afinfo;
174 if (unlikely(family >= NPROTO)) 174 if (unlikely(family >= NPROTO))
175 return NULL; 175 return NULL;
176 write_lock_bh(&xfrm_state_afinfo_lock); 176 spin_lock_bh(&xfrm_state_afinfo_lock);
177 afinfo = xfrm_state_afinfo[family]; 177 afinfo = xfrm_state_afinfo[family];
178 if (unlikely(!afinfo)) 178 if (unlikely(!afinfo))
179 write_unlock_bh(&xfrm_state_afinfo_lock); 179 spin_unlock_bh(&xfrm_state_afinfo_lock);
180 return afinfo; 180 return afinfo;
181} 181}
182 182
183static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo) 183static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo)
184 __releases(xfrm_state_afinfo_lock)
185{ 184{
186 write_unlock_bh(&xfrm_state_afinfo_lock); 185 spin_unlock_bh(&xfrm_state_afinfo_lock);
187} 186}
188 187
189int xfrm_register_type(const struct xfrm_type *type, unsigned short family) 188int xfrm_register_type(const struct xfrm_type *type, unsigned short family)
@@ -1845,12 +1844,12 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo)
1845 return -EINVAL; 1844 return -EINVAL;
1846 if (unlikely(afinfo->family >= NPROTO)) 1845 if (unlikely(afinfo->family >= NPROTO))
1847 return -EAFNOSUPPORT; 1846 return -EAFNOSUPPORT;
1848 write_lock_bh(&xfrm_state_afinfo_lock); 1847 spin_lock_bh(&xfrm_state_afinfo_lock);
1849 if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL)) 1848 if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL))
1850 err = -ENOBUFS; 1849 err = -ENOBUFS;
1851 else 1850 else
1852 xfrm_state_afinfo[afinfo->family] = afinfo; 1851 rcu_assign_pointer(xfrm_state_afinfo[afinfo->family], afinfo);
1853 write_unlock_bh(&xfrm_state_afinfo_lock); 1852 spin_unlock_bh(&xfrm_state_afinfo_lock);
1854 return err; 1853 return err;
1855} 1854}
1856EXPORT_SYMBOL(xfrm_state_register_afinfo); 1855EXPORT_SYMBOL(xfrm_state_register_afinfo);
@@ -1862,14 +1861,15 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
1862 return -EINVAL; 1861 return -EINVAL;
1863 if (unlikely(afinfo->family >= NPROTO)) 1862 if (unlikely(afinfo->family >= NPROTO))
1864 return -EAFNOSUPPORT; 1863 return -EAFNOSUPPORT;
1865 write_lock_bh(&xfrm_state_afinfo_lock); 1864 spin_lock_bh(&xfrm_state_afinfo_lock);
1866 if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) { 1865 if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) {
1867 if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo)) 1866 if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo))
1868 err = -EINVAL; 1867 err = -EINVAL;
1869 else 1868 else
1870 xfrm_state_afinfo[afinfo->family] = NULL; 1869 RCU_INIT_POINTER(xfrm_state_afinfo[afinfo->family], NULL);
1871 } 1870 }
1872 write_unlock_bh(&xfrm_state_afinfo_lock); 1871 spin_unlock_bh(&xfrm_state_afinfo_lock);
1872 synchronize_rcu();
1873 return err; 1873 return err;
1874} 1874}
1875EXPORT_SYMBOL(xfrm_state_unregister_afinfo); 1875EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
@@ -1879,17 +1879,16 @@ static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
1879 struct xfrm_state_afinfo *afinfo; 1879 struct xfrm_state_afinfo *afinfo;
1880 if (unlikely(family >= NPROTO)) 1880 if (unlikely(family >= NPROTO))
1881 return NULL; 1881 return NULL;
1882 read_lock(&xfrm_state_afinfo_lock); 1882 rcu_read_lock();
1883 afinfo = xfrm_state_afinfo[family]; 1883 afinfo = rcu_dereference(xfrm_state_afinfo[family]);
1884 if (unlikely(!afinfo)) 1884 if (unlikely(!afinfo))
1885 read_unlock(&xfrm_state_afinfo_lock); 1885 rcu_read_unlock();
1886 return afinfo; 1886 return afinfo;
1887} 1887}
1888 1888
1889static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo) 1889static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
1890 __releases(xfrm_state_afinfo_lock)
1891{ 1890{
1892 read_unlock(&xfrm_state_afinfo_lock); 1891 rcu_read_unlock();
1893} 1892}
1894 1893
1895/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */ 1894/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */