@@ -1152,29 +1152,35 @@ static int efi_netobj_init(struct efi_net_obj *netobj)
}
/* Allocate an aligned transmit buffer */
- transmit_buffer = calloc(1, PKTSIZE_ALIGN + PKTALIGN);
- if (!transmit_buffer)
- goto out_of_resources;
- transmit_buffer = (void *)ALIGN((uintptr_t)transmit_buffer, PKTALIGN);
- netobj->transmit_buffer = transmit_buffer;
+ if (!netobj->transmit_buffer) {
+ transmit_buffer = calloc(1, PKTSIZE_ALIGN + PKTALIGN);
+ if (!transmit_buffer)
+ goto out_of_resources;
+ transmit_buffer = (void *)ALIGN((uintptr_t)transmit_buffer, PKTALIGN);
+ netobj->transmit_buffer = transmit_buffer;
+ }
/* Allocate a number of receive buffers */
- receive_buffer = calloc(ETH_PACKETS_BATCH_RECV,
- sizeof(*receive_buffer));
- if (!receive_buffer)
- goto out_of_resources;
- for (i = 0; i < ETH_PACKETS_BATCH_RECV; i++) {
- receive_buffer[i] = malloc(PKTSIZE_ALIGN);
- if (!receive_buffer[i])
+ if (!netobj->receive_buffer) {
+ receive_buffer = calloc(ETH_PACKETS_BATCH_RECV,
+ sizeof(*receive_buffer));
+ if (!receive_buffer)
goto out_of_resources;
+ for (i = 0; i < ETH_PACKETS_BATCH_RECV; i++) {
+ receive_buffer[i] = malloc(PKTSIZE_ALIGN);
+ if (!receive_buffer[i])
+ goto out_of_resources;
+ }
+ netobj->receive_buffer = receive_buffer;
}
- netobj->receive_buffer = receive_buffer;
- receive_lengths = calloc(ETH_PACKETS_BATCH_RECV,
- sizeof(*receive_lengths));
- if (!receive_lengths)
- goto out_of_resources;
- netobj->receive_lengths = receive_lengths;
+ if (!netobj->receive_lengths) {
+ receive_lengths = calloc(ETH_PACKETS_BATCH_RECV,
+ sizeof(*receive_lengths));
+ if (!receive_lengths)
+ goto out_of_resources;
+ netobj->receive_lengths = receive_lengths;
+ }
/* Hook net up to the device list */
efi_add_handle(&netobj->header);
@@ -1291,12 +1297,6 @@ failure_to_add_protocol:
printf("ERROR: Failure to add protocol\n");
return -1;
out_of_resources:
- free(transmit_buffer);
- if (receive_buffer)
- for (i = 0; i < ETH_PACKETS_BATCH_RECV; i++)
- free(receive_buffer[i]);
- free(receive_buffer);
- free(receive_lengths);
printf("ERROR: Out of memory\n");
return -1;
}
@@ -1357,22 +1357,35 @@ int efi_net_register(void *ctx, struct event *event)
// Find a slot for this efi_net_obj
seq_num = -1;
+ // Try to recycle
for (i = 0; i < MAX_EFI_NET_OBJS; i++) {
- if (!net_objs[i]) {
+ if (net_objs[i] && !net_objs[i]->dev) {
seq_num = i;
break;
}
}
+ if (seq_num < 0) {
+ for (i = 0; i < MAX_EFI_NET_OBJS; i++) {
+ if (!net_objs[i]) {
+ seq_num = i;
+ break;
+ }
+ }
+ }
if (seq_num < 0)
return -1;
- netobj = calloc(1, sizeof(*netobj));
+ if (!net_objs[seq_num]) {
+ netobj = calloc(1, sizeof(*netobj));
+ net_objs[seq_num] = netobj;
+ } else {
+ netobj = net_objs[seq_num];
+ }
if (!netobj)
goto out_of_resources;
netobj->dev = dev;
netobj->efi_seq_num = seq_num;
- net_objs[seq_num] = netobj;
printf("efi_net registered device number %d\n", netobj->efi_seq_num);
return 0;
out_of_resources:
@@ -1419,17 +1432,10 @@ int efi_net_unregister(void *ctx, struct event *event)
if (!netobj)
return 0;
- // Remove from the list
- net_objs[i] = NULL;
+ // Mark as free in the list
+ netobj->dev = NULL;
if (efi_netobj_is_active(netobj)) {
- free(netobj->transmit_buffer);
- if (netobj->receive_buffer)
- for (i = 0; i < ETH_PACKETS_BATCH_RECV; i++)
- free(netobj->receive_buffer[i]);
- free(netobj->receive_buffer);
- free(netobj->receive_lengths);
-
ret = EFI_CALL(efi_close_event(netobj->wait_for_packet));
if (ret != EFI_SUCCESS)
return -1;
@@ -1450,9 +1456,6 @@ int efi_net_unregister(void *ctx, struct event *event)
efi_free_pool(interface);
}
- // Free the efi_net_obj
- free(netobj);
-
return 0;
}
When an efi_net_obj gets unregistered, save it and try to recycle it Signed-off-by: Adriano Cordova <adriano.cordova@canonical.com> --- lib/efi_loader/efi_net.c | 81 +++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 39 deletions(-)