[XFRM]: fix incorrect xfrm_state_afinfo_lock use

xfrm_state_afinfo_lock can be read-locked from bh context, so take it
in a bh-safe manner in xfrm_state_register_afinfo() and
xfrm_state_unregister_afinfo(). Found by the lock validator.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Ingo Molnar 2006-04-28 15:30:03 -07:00 committed by David S. Miller
parent 83de47cd0c
commit f3111502c0

View file

@ -1061,7 +1061,7 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo)
return -EINVAL; return -EINVAL;
if (unlikely(afinfo->family >= NPROTO)) if (unlikely(afinfo->family >= NPROTO))
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
write_lock(&xfrm_state_afinfo_lock); write_lock_bh(&xfrm_state_afinfo_lock);
if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL)) if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL))
err = -ENOBUFS; err = -ENOBUFS;
else { else {
@ -1069,7 +1069,7 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo)
afinfo->state_byspi = xfrm_state_byspi; afinfo->state_byspi = xfrm_state_byspi;
xfrm_state_afinfo[afinfo->family] = afinfo; xfrm_state_afinfo[afinfo->family] = afinfo;
} }
write_unlock(&xfrm_state_afinfo_lock); write_unlock_bh(&xfrm_state_afinfo_lock);
return err; return err;
} }
EXPORT_SYMBOL(xfrm_state_register_afinfo); EXPORT_SYMBOL(xfrm_state_register_afinfo);
@ -1081,7 +1081,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
return -EINVAL; return -EINVAL;
if (unlikely(afinfo->family >= NPROTO)) if (unlikely(afinfo->family >= NPROTO))
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
write_lock(&xfrm_state_afinfo_lock); write_lock_bh(&xfrm_state_afinfo_lock);
if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) { if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) {
if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo)) if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo))
err = -EINVAL; err = -EINVAL;
@ -1091,7 +1091,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
afinfo->state_bydst = NULL; afinfo->state_bydst = NULL;
} }
} }
write_unlock(&xfrm_state_afinfo_lock); write_unlock_bh(&xfrm_state_afinfo_lock);
return err; return err;
} }
EXPORT_SYMBOL(xfrm_state_unregister_afinfo); EXPORT_SYMBOL(xfrm_state_unregister_afinfo);