From e49b2154fee48d847ac20600dbd9888567c36b0e Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Mon, 29 Jul 2024 19:46:20 -0400 Subject: [PATCH] ethernet: Get rid of the read/write buffers for scattered I/O. This (mostly) reverts commit 3ea7c99119a6ae7305a1579d7294e9b1b46810e5. We no longer need this code after introducing the calls to send net_buffers to drivers directly. Change-Id: I31a2fdbbbe8203c53dbcc1e3b1fab2492c8651bd Reviewed-on: https://review.haiku-os.org/c/haiku/+/7914 Reviewed-by: waddlesplash --- .../network/devices/ethernet/ethernet.cpp | 101 +++++------------- 1 file changed, 25 insertions(+), 76 deletions(-) diff --git a/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp b/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp index 7ab40f2bfe..834cea4f10 100644 --- a/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp +++ b/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp @@ -31,18 +31,9 @@ struct ethernet_device : net_device, DoublyLinkedListLinkImpl { - ~ethernet_device() - { - free(read_buffer); - free(write_buffer); - } - int fd; uint32 frame_size; bool supports_net_buffer; - - void* read_buffer, *write_buffer; - mutex read_buffer_lock, write_buffer_lock; }; static const bigtime_t kLinkCheckInterval = 1000000; @@ -165,9 +156,6 @@ ethernet_init(const char *name, net_device **_device) device->media = IFM_ACTIVE | IFM_ETHER; device->header_length = ETHER_HEADER_LENGTH; device->fd = -1; - device->read_buffer = device->write_buffer = NULL; - device->read_buffer_lock = MUTEX_INITIALIZER("ethernet read_buffer"), - device->write_buffer_lock = MUTEX_INITIALIZER("ethernet write_buffer"); *_device = device; return B_OK; @@ -232,19 +220,6 @@ ethernet_up(net_device *_device) sCheckList.Add(device); } - if (device->frame_size > ETHER_MAX_FRAME_SIZE) { - free(device->read_buffer); - free(device->write_buffer); - - device->read_buffer = malloc(device->frame_size); - device->write_buffer = malloc(device->frame_size); - - if (device->read_buffer == NULL || device->write_buffer == NULL) { - errno = B_NO_MEMORY; - goto err; - } - } - device->address.length = ETHER_ADDRESS_LENGTH; device->mtu = device->frame_size - device->header_length; return B_OK; @@ -303,38 +278,25 @@ ethernet_send_data(net_device *_device, net_buffer *buffer) net_buffer *allocated = NULL; net_buffer *original = buffer; - MutexLocker bufferLocker; - struct iovec iovec; if (gBufferModule->count_iovecs(buffer) > 1) { - if (device->write_buffer != NULL) { - bufferLocker.SetTo(device->write_buffer_lock, false); + // Create a new buffer containing the data. + buffer = gBufferModule->duplicate(original); + if (buffer == NULL) + return ENOBUFS; - status_t status = gBufferModule->read(buffer, 0, - device->write_buffer, buffer->size); - if (status != B_OK) - return status; - iovec.iov_base = device->write_buffer; - iovec.iov_len = buffer->size; - } else { - // Fall back to creating a new buffer. - allocated = gBufferModule->duplicate(original); - if (allocated == NULL) - return ENOBUFS; + allocated = buffer; - buffer = allocated; - - if (gBufferModule->count_iovecs(allocated) > 1) { - dprintf("ethernet_send_data: no write buffer, cannot perform scatter I/O\n"); - gBufferModule->free(allocated); - return EMSGSIZE; - } - - gBufferModule->get_iovecs(buffer, &iovec, 1); + if (gBufferModule->count_iovecs(buffer) > 1) { + dprintf("ethernet: net_buffer I/O is not supported by underlying device\n"); + gBufferModule->free(buffer); + device->stats.send.errors++; + return B_NOT_SUPPORTED; } - } else { - gBufferModule->get_iovecs(buffer, &iovec, 1); } + struct iovec iovec; + gBufferModule->get_iovecs(buffer, &iovec, 1); + //dump_block((const char *)iovec.iov_base, buffer->size, " "); ssize_t bytesWritten = write(device->fd, iovec.iov_base, iovec.iov_len); //dprintf("sent: %ld\n", bytesWritten); @@ -366,45 +328,32 @@ ethernet_receive_data(net_device *_device, net_buffer **_buffer) return 0; } - // TODO: better header space + // read/write only works for standard ethernet frames. For larger frames, + // the driver should support send/receive of net_buffers directly, above. + net_buffer *buffer = gBufferModule->create(256); if (buffer == NULL) return ENOBUFS; - MutexLocker bufferLocker; - struct iovec iovec; ssize_t bytesRead; - status_t status; - if (device->read_buffer != NULL) { - bufferLocker.SetTo(device->read_buffer_lock, false); + void *data; - iovec.iov_base = device->read_buffer; - iovec.iov_len = device->frame_size; - } else { - void *data; - status = gBufferModule->append_size(buffer, device->frame_size, &data); - if (status == B_OK && data == NULL) { - dprintf("ethernet_receive_data: no read buffer, cannot perform scattered I/O!\n"); - status = B_NOT_SUPPORTED; - } - if (status < B_OK) - goto err; - - iovec.iov_base = data; - iovec.iov_len = device->frame_size; + status_t status = gBufferModule->append_size(buffer, device->frame_size, &data); + if (status == B_OK && data == NULL) { + dprintf("ethernet: net_buffer I/O is not supported by underlying device\n"); + status = B_NOT_SUPPORTED; } + if (status < B_OK) + goto err; - bytesRead = read(device->fd, iovec.iov_base, iovec.iov_len); + bytesRead = read(device->fd, data, device->frame_size); if (bytesRead < 0) { status = errno; goto err; } //dump_block((const char *)data, bytesRead, "rcv: "); - if (iovec.iov_base == device->read_buffer) - status = gBufferModule->append(buffer, iovec.iov_base, bytesRead); - else - status = gBufferModule->trim(buffer, bytesRead); + status = gBufferModule->trim(buffer, bytesRead); if (status < B_OK) { atomic_add((int32*)&device->stats.receive.dropped, 1); goto err;