Message ID | 1444910463-5688-1-git-send-email-matanb@mellanox.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
On 10/15/2015 08:01 AM, Matan Barak wrote: > From: Doron Tsur <doront@mellanox.com> > > When ib_cache_gid_set_default_gid is called from several threads, > updating the table could make find_gid fail, therefore a negative > index will be retruned and an invalid table entry will be used. > Locking find_gid as well fixes this problem. > > Fixes: 03db3a2d81e6 ('IB/core: Add RoCE GID table management') > Signed-off-by: Doron Tsur <doront@mellanox.com> > Signed-off-by: Matan Barak <matanb@mellanox.com> > --- > > Hi Doug, > > This patch fixes a bug in RoCE GID table implementation. When several > instances executes ib_cache_gid_set_default_gid, we could try to update > the same default GID (at the same index) simultaneously. > Therefore, find_gid will fail finding this default GID and we'll hit the > WARN_ON condition. > > We hit this bug while testing this code under pressure of doing ifup/ifdown. > > Thanks, > Matan Safe enough, applied for rc. > > drivers/infiniband/core/cache.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c > index 8f66c67..87471ef 100644 > --- a/drivers/infiniband/core/cache.c > +++ b/drivers/infiniband/core/cache.c > @@ -508,12 +508,12 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port, > memset(&gid_attr, 0, sizeof(gid_attr)); > gid_attr.ndev = ndev; > > + mutex_lock(&table->lock); > ix = find_gid(table, NULL, NULL, true, GID_ATTR_FIND_MASK_DEFAULT); > > /* Coudn't find default GID location */ > WARN_ON(ix < 0); > > - mutex_lock(&table->lock); > if (!__ib_cache_gid_get(ib_dev, port, ix, > ¤t_gid, ¤t_gid_attr) && > mode == IB_CACHE_GID_DEFAULT_MODE_SET && >
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index 8f66c67..87471ef 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c @@ -508,12 +508,12 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port, memset(&gid_attr, 0, sizeof(gid_attr)); gid_attr.ndev = ndev; + mutex_lock(&table->lock); ix = find_gid(table, NULL, NULL, true, GID_ATTR_FIND_MASK_DEFAULT); /* Coudn't find default GID location */ WARN_ON(ix < 0); - mutex_lock(&table->lock); if (!__ib_cache_gid_get(ib_dev, port, ix, ¤t_gid, ¤t_gid_attr) && mode == IB_CACHE_GID_DEFAULT_MODE_SET &&