Changeset 609243f4 in mainline for uspace/srv/net/net/packet_server.c


Ignore:
Timestamp:
2011-10-07T15:46:01Z (13 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e2c50e1
Parents:
f51b1d3
Message:

cherrypick general networking improvements from lp:~helenos-nicf/helenos/nicf (after sanitization)
remove obsolete networking drivers
this renders the networking non-functional for the time being

File:
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/net/packet_server.c

    rf51b1d3 r609243f4  
    11/*
    22 * Copyright (c) 2009 Lukas Mejdrech
     3 * Copyright (c) 2011 Radim Vansa
    34 * All rights reserved.
    45 *
     
    3536 */
    3637
    37 #include <packet_server.h>
    3838#include <align.h>
    3939#include <assert.h>
    4040#include <async.h>
    4141#include <errno.h>
     42#include <str_error.h>
     43#include <stdio.h>
    4244#include <fibril_synch.h>
    4345#include <unistd.h>
     
    4850#include <net/packet_header.h>
    4951
     52#include "packet_server.h"
     53
     54#define PACKET_SERVER_PROFILE 1
     55
     56/** Number of queues cacheing the unused packets */
    5057#define FREE_QUEUES_COUNT       7
     58/** Maximum number of packets in each queue */
     59#define FREE_QUEUE_MAX_LENGTH   16
    5160
    5261/** The default address length reserved for new packets. */
     
    5867/** The default suffix reserved for new packets. */
    5968#define DEFAULT_SUFFIX          64
     69
     70/** The queue with unused packets */
     71typedef struct packet_queue {
     72        packet_t *first;        /**< First packet in the queue */
     73        size_t packet_size; /**< Maximal size of the packets in this queue */
     74        int count;                      /**< Length of the queue */
     75} packet_queue_t;
    6076
    6177/** Packet server global data. */
     
    6480        fibril_mutex_t lock;
    6581        /** Free packet queues. */
    66         packet_t *free[FREE_QUEUES_COUNT];
    67        
    68         /**
    69          * Packet length upper bounds of the free packet queues. The maximal
    70          * lengths of packets in each queue in the ascending order. The last
    71          * queue is not limited.
    72          */
    73         size_t sizes[FREE_QUEUES_COUNT];
     82        packet_queue_t free_queues[FREE_QUEUES_COUNT];
    7483       
    7584        /** Total packets allocated. */
    76         unsigned int count;
     85        packet_id_t next_id;
    7786} ps_globals = {
    7887        .lock = FIBRIL_MUTEX_INITIALIZER(ps_globals.lock),
    79         .free = {
    80                 NULL,
    81                 NULL,
    82                 NULL,
    83                 NULL,
    84                 NULL,
    85                 NULL,
    86                 NULL
     88        .free_queues = {
     89                { NULL, PAGE_SIZE, 0},
     90                { NULL, PAGE_SIZE * 2, 0},
     91                { NULL, PAGE_SIZE * 4, 0},
     92                { NULL, PAGE_SIZE * 8, 0},
     93                { NULL, PAGE_SIZE * 16, 0},
     94                { NULL, PAGE_SIZE * 32, 0},
     95                { NULL, PAGE_SIZE * 64, 0},
    8796        },
    88         .sizes = {
    89                 PAGE_SIZE,
    90                 PAGE_SIZE * 2,
    91                 PAGE_SIZE * 4,
    92                 PAGE_SIZE * 8,
    93                 PAGE_SIZE * 16,
    94                 PAGE_SIZE * 32,
    95                 PAGE_SIZE * 64
    96         },
    97         .count = 0
     97        .next_id = 1
    9898};
    9999
     
    107107 * @param[in] max_suffix The maximal suffix length in bytes.
    108108 */
    109 static void
    110 packet_init(packet_t *packet, size_t addr_len, size_t max_prefix,
    111     size_t max_content, size_t max_suffix)
     109static void packet_init(packet_t *packet,
     110        size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix)
    112111{
    113112        /* Clear the packet content */
     
    120119        packet->previous = 0;
    121120        packet->next = 0;
     121        packet->offload_info = 0;
     122        packet->offload_mask = 0;
    122123        packet->addr_len = 0;
    123124        packet->src_addr = sizeof(packet_t);
     
    127128        packet->data_start = packet->dest_addr + addr_len + packet->max_prefix;
    128129        packet->data_end = packet->data_start;
     130}
     131
     132/**
     133 * Releases the memory allocated for the packet
     134 *
     135 * @param[in] packet Pointer to the memory where the packet was allocated
     136 */
     137static void packet_dealloc(packet_t *packet)
     138{
     139        pm_remove(packet);
     140        munmap(packet, packet->length);
    129141}
    130142
     
    141153 * @return              NULL if there is not enough memory left.
    142154 */
    143 static packet_t *
    144 packet_create(size_t length, size_t addr_len, size_t max_prefix,
    145     size_t max_content, size_t max_suffix)
     155static packet_t *packet_alloc(size_t length, size_t addr_len,
     156        size_t max_prefix, size_t max_content, size_t max_suffix)
    146157{
    147158        packet_t *packet;
    148159        int rc;
    149160
     161        /* Global lock is locked */
    150162        assert(fibril_mutex_is_locked(&ps_globals.lock));
    151 
    152         /* Already locked */
     163        /* The length is some multiple of PAGE_SIZE */
     164        assert(!(length & (PAGE_SIZE - 1)));
     165
    153166        packet = (packet_t *) mmap(NULL, length, PROTO_READ | PROTO_WRITE,
    154             MAP_SHARED | MAP_ANONYMOUS, 0, 0);
     167                MAP_SHARED | MAP_ANONYMOUS, 0, 0);
    155168        if (packet == MAP_FAILED)
    156169                return NULL;
    157 
    158         ps_globals.count++;
    159         packet->packet_id = ps_globals.count;
     170       
     171        /* Using 32bit packet_id the id could overflow */
     172        packet_id_t pid;
     173        do {
     174                pid = ps_globals.next_id;
     175                ps_globals.next_id++;
     176        } while (!pid || pm_find(pid));
     177        packet->packet_id = pid;
     178
    160179        packet->length = length;
    161180        packet_init(packet, addr_len, max_prefix, max_content, max_suffix);
     
    163182        rc = pm_add(packet);
    164183        if (rc != EOK) {
    165                 munmap(packet, packet->length);
     184                packet_dealloc(packet);
    166185                return NULL;
    167186        }
     
    184203 * @return              NULL if there is not enough memory left.
    185204 */
    186 static packet_t *
    187 packet_get_local(size_t addr_len, size_t max_prefix, size_t max_content,
    188     size_t max_suffix)
    189 {
    190         size_t length = ALIGN_UP(sizeof(packet_t) + 2 * addr_len +
    191             max_prefix + max_content + max_suffix, PAGE_SIZE);
    192        
     205static packet_t *packet_get_local(size_t addr_len,
     206        size_t max_prefix, size_t max_content, size_t max_suffix)
     207{
     208        size_t length = ALIGN_UP(sizeof(packet_t) + 2 * addr_len
     209                + max_prefix + max_content + max_suffix, PAGE_SIZE);
     210       
     211        if (length > PACKET_MAX_LENGTH)
     212                return NULL;
     213
    193214        fibril_mutex_lock(&ps_globals.lock);
    194215       
     
    197218       
    198219        for (index = 0; index < FREE_QUEUES_COUNT; index++) {
    199                 if ((length > ps_globals.sizes[index]) &&
    200                     (index < FREE_QUEUES_COUNT - 1))
     220                if ((length > ps_globals.free_queues[index].packet_size) &&
     221                        (index < FREE_QUEUES_COUNT - 1))
    201222                        continue;
    202223               
    203                 packet = ps_globals.free[index];
     224                packet = ps_globals.free_queues[index].first;
    204225                while (packet_is_valid(packet) && (packet->length < length))
    205226                        packet = pm_find(packet->next);
    206227               
    207228                if (packet_is_valid(packet)) {
    208                         if (packet == ps_globals.free[index])
    209                                 ps_globals.free[index] = pq_detach(packet);
    210                         else
     229                        ps_globals.free_queues[index].count--;
     230                        if (packet == ps_globals.free_queues[index].first) {
     231                                ps_globals.free_queues[index].first = pq_detach(packet);
     232                        } else {
    211233                                pq_detach(packet);
     234                        }
    212235                       
    213                         packet_init(packet, addr_len, max_prefix, max_content,
    214                             max_suffix);
     236                        packet_init(packet, addr_len, max_prefix, max_content, max_suffix);
    215237                        fibril_mutex_unlock(&ps_globals.lock);
    216238                       
     
    219241        }
    220242       
    221         packet = packet_create(length, addr_len, max_prefix, max_content,
    222             max_suffix);
     243        packet = packet_alloc(length, addr_len,
     244                max_prefix, max_content, max_suffix);
    223245       
    224246        fibril_mutex_unlock(&ps_globals.lock);
     
    240262
    241263        for (index = 0; (index < FREE_QUEUES_COUNT - 1) &&
    242             (packet->length > ps_globals.sizes[index]); index++) {
     264            (packet->length > ps_globals.free_queues[index].packet_size); index++) {
    243265                ;
    244266        }
    245267       
    246         result = pq_add(&ps_globals.free[index], packet, packet->length,
    247             packet->length);
     268        ps_globals.free_queues[index].count++;
     269        result = pq_add(&ps_globals.free_queues[index].first, packet,
     270                packet->length, packet->length);
    248271        assert(result == EOK);
    249272}
     
    328351        case NET_PACKET_CREATE_1:
    329352                packet = packet_get_local(DEFAULT_ADDR_LEN, DEFAULT_PREFIX,
    330                     IPC_GET_CONTENT(*call), DEFAULT_SUFFIX);
     353                        IPC_GET_CONTENT(*call), DEFAULT_SUFFIX);
    331354                if (!packet)
    332355                        return ENOMEM;
     
    338361        case NET_PACKET_CREATE_4:
    339362                packet = packet_get_local(
    340                     ((DEFAULT_ADDR_LEN < IPC_GET_ADDR_LEN(*call)) ?
     363                        ((DEFAULT_ADDR_LEN < IPC_GET_ADDR_LEN(*call)) ?
    341364                    IPC_GET_ADDR_LEN(*call) : DEFAULT_ADDR_LEN),
    342365                    DEFAULT_PREFIX + IPC_GET_PREFIX(*call),
     
    352375        case NET_PACKET_GET:
    353376                packet = pm_find(IPC_GET_ID(*call));
    354                 if (!packet_is_valid(packet))
     377                if (!packet_is_valid(packet)) {
    355378                        return ENOENT;
     379                }
    356380                return packet_reply(packet);
    357381       
     
    371395}
    372396
     397int packet_server_init()
     398{
     399        return EOK;
     400}
     401
    373402/** @}
    374403 */
Note: See TracChangeset for help on using the changeset viewer.