Commit 96390f62 authored by Nelson Escobar's avatar Nelson Escobar Committed by Doug Ledford

IB/usnic: Handle 0 counts in resource allocation

Signed-off-by: default avatarDave Goodell <dgoodell@cisco.com>
Reviewed-by: default avatarReese Faucette <rfaucett@cisco.com>
Reviewed-by: default avatarXuyang Wang <xuywang@cisco.com>
Signed-off-by: default avatarNelson Escobar <neescoba@cisco.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent dc92d146
...@@ -237,7 +237,7 @@ usnic_vnic_get_resources(struct usnic_vnic *vnic, enum usnic_vnic_res_type type, ...@@ -237,7 +237,7 @@ usnic_vnic_get_resources(struct usnic_vnic *vnic, enum usnic_vnic_res_type type,
struct usnic_vnic_res *res; struct usnic_vnic_res *res;
int i; int i;
if (usnic_vnic_res_free_cnt(vnic, type) < cnt || cnt < 1 || !owner) if (usnic_vnic_res_free_cnt(vnic, type) < cnt || cnt < 0 || !owner)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
ret = kzalloc(sizeof(*ret), GFP_ATOMIC); ret = kzalloc(sizeof(*ret), GFP_ATOMIC);
...@@ -247,26 +247,28 @@ usnic_vnic_get_resources(struct usnic_vnic *vnic, enum usnic_vnic_res_type type, ...@@ -247,26 +247,28 @@ usnic_vnic_get_resources(struct usnic_vnic *vnic, enum usnic_vnic_res_type type,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
ret->res = kzalloc(sizeof(*(ret->res))*cnt, GFP_ATOMIC); if (cnt > 0) {
if (!ret->res) { ret->res = kcalloc(cnt, sizeof(*(ret->res)), GFP_ATOMIC);
usnic_err("Failed to allocate resources for %s. Out of memory\n", if (!ret->res) {
usnic_vnic_pci_name(vnic)); usnic_err("Failed to allocate resources for %s. Out of memory\n",
kfree(ret); usnic_vnic_pci_name(vnic));
return ERR_PTR(-ENOMEM); kfree(ret);
} return ERR_PTR(-ENOMEM);
}
spin_lock(&vnic->res_lock); spin_lock(&vnic->res_lock);
src = &vnic->chunks[type]; src = &vnic->chunks[type];
for (i = 0; i < src->cnt && ret->cnt < cnt; i++) { for (i = 0; i < src->cnt && ret->cnt < cnt; i++) {
res = src->res[i]; res = src->res[i];
if (!res->owner) { if (!res->owner) {
src->free_cnt--; src->free_cnt--;
res->owner = owner; res->owner = owner;
ret->res[ret->cnt++] = res; ret->res[ret->cnt++] = res;
}
} }
}
spin_unlock(&vnic->res_lock); spin_unlock(&vnic->res_lock);
}
ret->type = type; ret->type = type;
ret->vnic = vnic; ret->vnic = vnic;
WARN_ON(ret->cnt != cnt); WARN_ON(ret->cnt != cnt);
...@@ -281,14 +283,16 @@ void usnic_vnic_put_resources(struct usnic_vnic_res_chunk *chunk) ...@@ -281,14 +283,16 @@ void usnic_vnic_put_resources(struct usnic_vnic_res_chunk *chunk)
int i; int i;
struct usnic_vnic *vnic = chunk->vnic; struct usnic_vnic *vnic = chunk->vnic;
spin_lock(&vnic->res_lock); if (chunk->cnt > 0) {
while ((i = --chunk->cnt) >= 0) { spin_lock(&vnic->res_lock);
res = chunk->res[i]; while ((i = --chunk->cnt) >= 0) {
chunk->res[i] = NULL; res = chunk->res[i];
res->owner = NULL; chunk->res[i] = NULL;
vnic->chunks[res->type].free_cnt++; res->owner = NULL;
vnic->chunks[res->type].free_cnt++;
}
spin_unlock(&vnic->res_lock);
} }
spin_unlock(&vnic->res_lock);
kfree(chunk->res); kfree(chunk->res);
kfree(chunk); kfree(chunk);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment