|
@@ -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,
|
|
return ERR_PTR(-ENOMEM);
|
|
return ERR_PTR(-ENOMEM);
|
|
}
|
|
}
|
|
|
|
|
|
- ret->res = kzalloc(sizeof(*(ret->res))*cnt, GFP_ATOMIC);
|
|
|
|
- if (!ret->res) {
|
|
|
|
- usnic_err("Failed to allocate resources for %s. Out of memory\n",
|
|
|
|
- usnic_vnic_pci_name(vnic));
|
|
|
|
- kfree(ret);
|
|
|
|
- return ERR_PTR(-ENOMEM);
|
|
|
|
- }
|
|
|
|
|
|
+ if (cnt > 0) {
|
|
|
|
+ ret->res = kcalloc(cnt, sizeof(*(ret->res)), GFP_ATOMIC);
|
|
|
|
+ if (!ret->res) {
|
|
|
|
+ usnic_err("Failed to allocate resources for %s. Out of memory\n",
|
|
|
|
+ usnic_vnic_pci_name(vnic));
|
|
|
|
+ kfree(ret);
|
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
|
+ }
|
|
|
|
|
|
- spin_lock(&vnic->res_lock);
|
|
|
|
- src = &vnic->chunks[type];
|
|
|
|
- for (i = 0; i < src->cnt && ret->cnt < cnt; i++) {
|
|
|
|
- res = src->res[i];
|
|
|
|
- if (!res->owner) {
|
|
|
|
- src->free_cnt--;
|
|
|
|
- res->owner = owner;
|
|
|
|
- ret->res[ret->cnt++] = res;
|
|
|
|
|
|
+ spin_lock(&vnic->res_lock);
|
|
|
|
+ src = &vnic->chunks[type];
|
|
|
|
+ for (i = 0; i < src->cnt && ret->cnt < cnt; i++) {
|
|
|
|
+ res = src->res[i];
|
|
|
|
+ if (!res->owner) {
|
|
|
|
+ src->free_cnt--;
|
|
|
|
+ res->owner = owner;
|
|
|
|
+ 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)
|
|
int i;
|
|
int i;
|
|
struct usnic_vnic *vnic = chunk->vnic;
|
|
struct usnic_vnic *vnic = chunk->vnic;
|
|
|
|
|
|
- spin_lock(&vnic->res_lock);
|
|
|
|
- while ((i = --chunk->cnt) >= 0) {
|
|
|
|
- res = chunk->res[i];
|
|
|
|
- chunk->res[i] = NULL;
|
|
|
|
- res->owner = NULL;
|
|
|
|
- vnic->chunks[res->type].free_cnt++;
|
|
|
|
|
|
+ if (chunk->cnt > 0) {
|
|
|
|
+ spin_lock(&vnic->res_lock);
|
|
|
|
+ while ((i = --chunk->cnt) >= 0) {
|
|
|
|
+ res = chunk->res[i];
|
|
|
|
+ chunk->res[i] = NULL;
|
|
|
|
+ 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);
|