Signed-off-by: Adriano Cordova <adriano.cord...@canonical.com> --- lib/efi_loader/efi_net.c | 81 +++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 39 deletions(-)
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index 8c0a3f5243c..d84fa6c2bc6 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -1162,29 +1162,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); @@ -1301,12 +1307,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; } @@ -1367,22 +1367,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: @@ -1429,17 +1442,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; @@ -1462,9 +1468,6 @@ int efi_net_unregister(void *ctx, struct event *event) efi_free_pool(interface); } - // Free the efi_net_obj - free(netobj); - return 0; } -- 2.48.1