diff options
Diffstat (limited to 'drivers/infiniband/core/cache.c')
| -rw-r--r-- | drivers/infiniband/core/cache.c | 14 | 
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index c2e257d97eff..1a2984c28b95 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c @@ -178,6 +178,7 @@ static int write_gid(struct ib_device *ib_dev, u8 port,  {  	int ret = 0;  	struct net_device *old_net_dev; +	enum ib_gid_type old_gid_type;  	/* in rdma_cap_roce_gid_table, this funciton should be protected by a  	 * sleep-able lock. @@ -199,6 +200,7 @@ static int write_gid(struct ib_device *ib_dev, u8 port,  	}  	old_net_dev = table->data_vec[ix].attr.ndev; +	old_gid_type = table->data_vec[ix].attr.gid_type;  	if (old_net_dev && old_net_dev != attr->ndev)  		dev_put(old_net_dev);  	/* if modify_gid failed, just delete the old gid */ @@ -207,10 +209,14 @@ static int write_gid(struct ib_device *ib_dev, u8 port,  		attr = &zattr;  		table->data_vec[ix].context = NULL;  	} -	if (default_gid) -		table->data_vec[ix].props |= GID_TABLE_ENTRY_DEFAULT; +  	memcpy(&table->data_vec[ix].gid, gid, sizeof(*gid));  	memcpy(&table->data_vec[ix].attr, attr, sizeof(*attr)); +	if (default_gid) { +		table->data_vec[ix].props |= GID_TABLE_ENTRY_DEFAULT; +		if (action == GID_TABLE_WRITE_ACTION_DEL) +			table->data_vec[ix].attr.gid_type = old_gid_type; +	}  	if (table->data_vec[ix].attr.ndev &&  	    table->data_vec[ix].attr.ndev != old_net_dev)  		dev_hold(table->data_vec[ix].attr.ndev); @@ -405,7 +411,9 @@ int ib_cache_gid_del_all_netdev_gids(struct ib_device *ib_dev, u8 port,  	for (ix = 0; ix < table->sz; ix++)  		if (table->data_vec[ix].attr.ndev == ndev) -			if (!del_gid(ib_dev, port, table, ix, false)) +			if (!del_gid(ib_dev, port, table, ix, +				     !!(table->data_vec[ix].props & +					GID_TABLE_ENTRY_DEFAULT)))  				deleted = true;  	write_unlock_irq(&table->rwlock);  |