LTP GCOV extension - code coverage report
Current view: directory - net/tipc - msg_buf.c
Test: tipc.info
Date: 2003-08-07 Instrumented lines: 94
Code covered: 71.3 % Executed lines: 67

       1                 : /* 
       2                 :  * TIPC Linux kernel implementation
       3                 :  * Copyright (c) 2001-2003 Ericsson Research Canada
       4                 :  * Copyright (c) 2003 OSDL, Inc.
       5                 :  *
       6                 :  * This file is based on the source code done by Jon Maloy
       7                 :  * (jon.maloy@ericsson.com) for TIPC version 0.96, available from
       8                 :  * http://tipc.sourceforge.net
       9                 :  ***************************************************************************
      10                 :  * This program is free software; you can redistribute it and/or modify
      11                 :  * it under the terms of the GNU General Public License as published by
      12                 :  * the Free Software Foundation; either version 2 of the License, or
      13                 :  * (at your option) any later version.
      14                 :  *   
      15                 :  * This program is distributed in the hope that it will be useful,
      16                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      17                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18                 :  * GNU General Public License for more details.
      19                 :  *  
      20                 :  * You should have received a copy of the GNU General Public License
      21                 :  * along with this program; if not, write to the Free Software
      22                 :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      23                 :  ***************************************************************************
      24                 :  * Alphabetical list of people who have worked on this file:
      25                 :  *      - Mark Haverkamp        (markh@osdl.org)
      26                 :  *      - Mika Kukkonen         (mika@osdl.org)
      27                 :  *      - Rusty Lynch           (rusty@linux.intel.com)
      28                 :  */
      29                 : 
      30                 : #include "debug.h"
      31                 : #include "msg_buf.h"
      32                 : 
      33                 : #define KMALLOC_MAX_SIZE (128 * 1024)
      34                 : 
      35                 : typedef struct mblock {
      36                 :         uint pages_order;
      37                 :         char data[4];
      38                 : } mblock;
      39                 : 
      40                 : #define SMALL_POOL_MSG_SIZE 340u
      41                 : #define MEDIUM_POOL_MSG_SIZE 1530u
      42                 : 
      43                 : struct sk_buff *smallPoolHead = 0;
      44                 : struct sk_buff *mediumPoolHead = 0;
      45                 : 
      46                 : struct sk_buff *
      47                 : acquireBuffers(uint size, uint num, struct sk_buff **pool)
      48           68523 : {
      49           68523 :         struct sk_buff *crs = NULL;
      50           68523 :         uint i;
      51           68523 :         uint sz = (size + BUF_HEADROOM + 15) & ~15; /* Eth header + alignment */
      52                 : 
      53           68523 :         if (!pool)
      54                 :                 assert(num == 1);
      55          137163 :         for (i = 0; i < num; i++) {
      56           68640 :                 crs = (struct sk_buff *) alloc_skb(sz, GFP_ATOMIC);
      57                 :                 assert(crs);
      58           68640 :                 crs->protocol = __constant_htons(0x807);
      59           68640 :                 skb_reserve(crs, BUF_HEADROOM);
      60           68640 :                 crs->nh.raw = crs->data;  /* Please the device layer */
      61           68640 :                 UD(crs)->data = crs->data;
      62           68640 :                 UD(crs)->pool = pool;
      63           68640 :                 UD(crs)->next = (pool ? *pool : (struct sk_buff *) 0);
      64           68640 :                 if (pool)
      65             120 :                         *pool = crs;
      66                 :         }
      67           68523 :         if (pool)
      68               3 :                 *pool = UD(crs)->next;
      69           68523 :         UD(crs)->next = 0;
      70           68523 :         return crs;
      71                 : }
      72                 : 
      73                 : struct sk_buff *
      74                 : buf_acquire(uint size)
      75          479979 : {
      76          479979 :         struct sk_buff *b;
      77                 : 
      78          479979 :         if (size <= SMALL_POOL_MSG_SIZE) {
      79             231 :                 b = smallPoolHead;
      80             231 :                 if (b) {
      81             230 :                         smallPoolHead = UD(b)->next;
      82             230 :                         return b;
      83                 :                 }
      84               1 :                 return acquireBuffers(SMALL_POOL_MSG_SIZE, 40, &smallPoolHead);
      85          479748 :         } else if (size <= MEDIUM_POOL_MSG_SIZE) {
      86          411228 :                 b = mediumPoolHead;
      87          411228 :                 if (b) {
      88          411226 :                         mediumPoolHead = UD(b)->next;
      89          411226 :                         return b;
      90                 :                 }
      91               2 :                 return acquireBuffers(MEDIUM_POOL_MSG_SIZE, 40,
      92                 :                                       &mediumPoolHead);
      93                 :         }
      94           68520 :         return acquireBuffers(size, 1, 0);
      95                 : }
      96                 : 
      97                 : char *
      98                 : os_malloc(uint size)
      99              27 : {
     100              27 :         mblock *m;
     101              27 :         uint allocate = size + sizeof (int);
     102                 : 
     103              27 :         if (allocate <= KMALLOC_MAX_SIZE) {
     104              27 :                 m = kmalloc(allocate, GFP_ATOMIC);
     105              27 :                 if (!m) {
     106                 :                         assert(!"TIPC: kmalloc(GFP_ATOMIC) failed");
     107                 :                 }
     108              27 :                 m->pages_order = 0;
     109                 :         } else {
     110               0 :                 uint order = 1;
     111                 : 
     112               0 :                 while ((PAGE_SIZE << order) < allocate)
     113               0 :                         order++;
     114               0 :                 m = (mblock *) __get_free_pages(GFP_ATOMIC, order);
     115               0 :                 if (!m) {
     116                 :                         assert(!"TIPC: __get_free_pages(GFP_ATOMIOC) failed");
     117                 :                 }
     118               0 :                 m->pages_order = order;
     119                 :         }
     120              27 :         return (char *) &m->data;
     121                 : }
     122                 : 
     123                 : void
     124                 : os_free(char *m)
     125               8 : {
     126               8 :         mblock *b;
     127               8 :         b = (mblock *) (m - sizeof (int));
     128                 :         assert(b);
     129                 :         assert(((PAGE_SIZE << b->pages_order) / PAGE_SIZE) < num_physpages);
     130               8 :         if (b->pages_order)
     131               0 :                 free_pages((unsigned long) b, b->pages_order);
     132                 :         else
     133               8 :                 kfree(b);
     134                 : }
     135                 : 
     136                 : /* ///////////////////////////////////////////////////////////////// */
     137                 : /* Memory management:                                                */
     138                 : /* These calls do not need to be particularly efficient,since they   */
     139                 : /* will be called infrequenctly. Only multiple pages are requested.  */
     140                 : 
     141                 : typedef struct MemoryBlock {
     142                 :         struct MemoryBlock *next;
     143                 :         struct MemoryBlock *prev;
     144                 :         char mem[4];
     145                 : } MemoryBlock;
     146                 : 
     147                 : struct MemoryBlock *memRoot = 0;
     148                 : 
     149                 : char *
     150                 : mem_alloc(uint size)
     151              27 : {
     152              27 :         struct MemoryBlock *block;
     153              27 :         uint sz = size + (2 * sizeof (MemoryBlock *));
     154                 : 
     155              27 :         block = (MemoryBlock *) os_malloc(sz);
     156              27 :         if (!block) {
     157               0 :                 warn("TIPC: Failed to allocate %i bytes\n", sz);
     158               0 :                 return NULL;
     159                 :         }
     160              27 :         block->prev = 0;
     161              27 :         block->next = memRoot;
     162              27 :         if (block->next)
     163              26 :                 block->next->prev = block;
     164              27 :         memRoot = block;
     165              27 :         return block->mem;
     166                 : }
     167                 : 
     168                 : void
     169                 : mem_free(char *b)
     170               8 : {
     171               8 :         struct MemoryBlock *block;
     172                 : 
     173               8 :         block = (MemoryBlock *) (b - 2 * sizeof (MemoryBlock *));
     174               8 :         if (block->next)
     175               8 :                 block->next->prev = block->prev;
     176               8 :         if (block->prev)
     177               4 :                 block->prev->next = block->next;
     178                 :         else
     179               4 :                 memRoot = block->next;
     180               8 :         os_free((char *) block);
     181                 : }
     182                 : 
     183                 : /* 
     184                 :  * Clean up TIPC memory 
     185                 :  */
     186                 : void
     187                 : tipc_release_msg_buf(void)
     188               0 : {
     189               0 :         MemoryBlock *block;
     190               0 :         struct sk_buff *obuf;
     191                 : 
     192                 :         /* 
     193                 :          * Release sk_buffs from buf_acquire()
     194                 :          */
     195               0 :         obuf = smallPoolHead;
     196               0 :         while (obuf) {
     197               0 :                 struct sk_buff *next = UD(obuf)->next;
     198                 : 
     199               0 :                 kfree_skb(obuf);
     200               0 :                 obuf = next;
     201                 :         }
     202               0 :         obuf = mediumPoolHead;
     203               0 :         while (obuf) {
     204               0 :                 struct sk_buff *next = UD(obuf)->next;
     205                 : 
     206               0 :                 kfree_skb(obuf);
     207               0 :                 obuf = next;
     208                 :         }
     209                 : 
     210                 :         /* 
     211                 :          * Release memory from mem_alloc()
     212                 :          */
     213               0 :         block = memRoot;
     214               0 :         while (block) {
     215               0 :                 MemoryBlock *nx = block->next;
     216                 : 
     217                 :                 dbg("Releasing memory block\n");
     218               0 :                 os_free((char *) block);
     219               0 :                 block = nx;
     220                 :         }
     221                 : }

Generated by: LTP GCOV extension version 1.1