linux-bk/arch/m68k/atari/stram.c
<<
>>
Prefs
   1/*
   2 * arch/m68k/atari/stram.c: Functions for ST-RAM allocations
   3 *
   4 * Copyright 1994-97 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
   5 *
   6 * This file is subject to the terms and conditions of the GNU General Public
   7 * License.  See the file COPYING in the main directory of this archive
   8 * for more details.
   9 */
  10
  11#include <linux/config.h>
  12#include <linux/types.h>
  13#include <linux/kernel.h>
  14#include <linux/mm.h>
  15#include <linux/kdev_t.h>
  16#include <linux/major.h>
  17#include <linux/init.h>
  18#include <linux/swap.h>
  19#include <linux/slab.h>
  20#include <linux/vmalloc.h>
  21#include <linux/pagemap.h>
  22#include <linux/shm.h>
  23#include <linux/bootmem.h>
  24#include <linux/mount.h>
  25#include <linux/blkdev.h>
  26
  27#include <asm/setup.h>
  28#include <asm/machdep.h>
  29#include <asm/page.h>
  30#include <asm/pgtable.h>
  31#include <asm/atarihw.h>
  32#include <asm/atari_stram.h>
  33#include <asm/io.h>
  34#include <asm/semaphore.h>
  35
  36#include <linux/swapops.h>
  37
  38#undef DEBUG
  39
  40#ifdef DEBUG
  41#define DPRINTK(fmt,args...) printk( fmt, ##args )
  42#else
  43#define DPRINTK(fmt,args...)
  44#endif
  45
  46#if defined(CONFIG_PROC_FS) && defined(CONFIG_STRAM_PROC)
  47/* abbrev for the && above... */
  48#define DO_PROC
  49#include <linux/proc_fs.h>
  50#endif
  51
  52/* Pre-swapping comments:
  53 *
  54 * ++roman:
  55 *
  56 * New version of ST-Ram buffer allocation. Instead of using the
  57 * 1 MB - 4 KB that remain when the ST-Ram chunk starts at $1000
  58 * (1 MB granularity!), such buffers are reserved like this:
  59 *
  60 *  - If the kernel resides in ST-Ram anyway, we can take the buffer
  61 *    from behind the current kernel data space the normal way
  62 *    (incrementing start_mem).
  63 *
  64 *  - If the kernel is in TT-Ram, stram_init() initializes start and
  65 *    end of the available region. Buffers are allocated from there
  66 *    and mem_init() later marks the such used pages as reserved.
  67 *    Since each TT-Ram chunk is at least 4 MB in size, I hope there
  68 *    won't be an overrun of the ST-Ram region by normal kernel data
  69 *    space.
  70 *
  71 * For that, ST-Ram may only be allocated while kernel initialization
  72 * is going on, or exactly: before mem_init() is called. There is also
  73 * no provision now for freeing ST-Ram buffers. It seems that isn't
  74 * really needed.
  75 *
  76 */
  77
  78/*
  79 * New Nov 1997: Use ST-RAM as swap space!
  80 *
  81 * In the past, there were often problems with modules that require ST-RAM
  82 * buffers. Such drivers have to use __get_dma_pages(), which unfortunately
  83 * often isn't very successful in allocating more than 1 page :-( [1] The net
  84 * result was that most of the time you couldn't insmod such modules (ataflop,
  85 * ACSI, SCSI on Falcon, Atari internal framebuffer, not to speak of acsi_slm,
  86 * which needs a 1 MB buffer... :-).
  87 *
  88 * To overcome this limitation, ST-RAM can now be turned into a very
  89 * high-speed swap space. If a request for an ST-RAM buffer comes, the kernel
  90 * now tries to unswap some pages on that swap device to make some free (and
  91 * contiguous) space. This works much better in comparison to
  92 * __get_dma_pages(), since used swap pages can be selectively freed by either
  93 * moving them to somewhere else in swap space, or by reading them back into
  94 * system memory. Ok, there operation of unswapping isn't really cheap (for
  95 * each page, one has to go through the page tables of all processes), but it
  96 * doesn't happen that often (only when allocation ST-RAM, i.e. when loading a
  97 * module that needs ST-RAM). But it at least makes it possible to load such
  98 * modules!
  99 *
 100 * It could also be that overall system performance increases a bit due to
 101 * ST-RAM swapping, since slow ST-RAM isn't used anymore for holding data or
 102 * executing code in. It's then just a (very fast, compared to disk) back
 103 * storage for not-so-often needed data. (But this effect must be compared
 104 * with the loss of total memory...) Don't know if the effect is already
 105 * visible on a TT, where the speed difference between ST- and TT-RAM isn't
 106 * that dramatic, but it should on machines where TT-RAM is really much faster
 107 * (e.g. Afterburner).
 108 *
 109 *   [1]: __get_free_pages() does a fine job if you only want one page, but if
 110 * you want more (contiguous) pages, it can give you such a block only if
 111 * there's already a free one. The algorithm can't try to free buffers or swap
 112 * out something in order to make more free space, since all that page-freeing
 113 * mechanisms work "target-less", i.e. they just free something, but not in a
 114 * specific place. I.e., __get_free_pages() can't do anything to free
 115 * *adjacent* pages :-( This situation becomes even worse for DMA memory,
 116 * since the freeing algorithms are also blind to DMA capability of pages.
 117 */
 118
 119/* 1998-10-20: ++andreas
 120   unswap_by_move disabled because it does not handle swapped shm pages.
 121*/
 122
 123/* 2000-05-01: ++andreas
 124   Integrated with bootmem.  Remove all traces of unswap_by_move.
 125*/
 126
 127#ifdef CONFIG_STRAM_SWAP
 128#define ALIGN_IF_SWAP(x)        PAGE_ALIGN(x)
 129#else
 130#define ALIGN_IF_SWAP(x)        (x)
 131#endif
 132
 133/* get index of swap page at address 'addr' */
 134#define SWAP_NR(addr)           (((addr) - swap_start) >> PAGE_SHIFT)
 135
 136/* get address of swap page #'nr' */
 137#define SWAP_ADDR(nr)           (swap_start + ((nr) << PAGE_SHIFT))
 138
 139/* get number of pages for 'n' bytes (already page-aligned) */
 140#define N_PAGES(n)                      ((n) >> PAGE_SHIFT)
 141
 142/* The following two numbers define the maximum fraction of ST-RAM in total
 143 * memory, below that the kernel would automatically use ST-RAM as swap
 144 * space. This decision can be overridden with stram_swap= */
 145#define MAX_STRAM_FRACTION_NOM          1
 146#define MAX_STRAM_FRACTION_DENOM        3
 147
 148/* Start and end (virtual) of ST-RAM */
 149static void *stram_start, *stram_end;
 150
 151/* set after memory_init() executed and allocations via start_mem aren't
 152 * possible anymore */
 153static int mem_init_done;
 154
 155/* set if kernel is in ST-RAM */
 156static int kernel_in_stram;
 157
 158typedef struct stram_block {
 159        struct stram_block *next;
 160        void *start;
 161        unsigned long size;
 162        unsigned flags;
 163        const char *owner;
 164} BLOCK;
 165
 166/* values for flags field */
 167#define BLOCK_FREE              0x01    /* free structure in the BLOCKs pool */
 168#define BLOCK_KMALLOCED 0x02    /* structure allocated by kmalloc() */
 169#define BLOCK_GFP               0x08    /* block allocated with __get_dma_pages() */
 170#define BLOCK_INSWAP    0x10    /* block allocated in swap space */
 171
 172/* list of allocated blocks */
 173static BLOCK *alloc_list;
 174
 175/* We can't always use kmalloc() to allocate BLOCK structures, since
 176 * stram_alloc() can be called rather early. So we need some pool of
 177 * statically allocated structures. 20 of them is more than enough, so in most
 178 * cases we never should need to call kmalloc(). */
 179#define N_STATIC_BLOCKS 20
 180static BLOCK static_blocks[N_STATIC_BLOCKS];
 181
 182#ifdef CONFIG_STRAM_SWAP
 183/* max. number of bytes to use for swapping
 184 *  0 = no ST-RAM swapping
 185 * -1 = do swapping (to whole ST-RAM) if it's less than MAX_STRAM_FRACTION of
 186 *      total memory
 187 */
 188static int max_swap_size = -1;
 189
 190/* start and end of swapping area */
 191static void *swap_start, *swap_end;
 192
 193/* The ST-RAM's swap info structure */
 194static struct swap_info_struct *stram_swap_info;
 195
 196/* The ST-RAM's swap type */
 197static int stram_swap_type;
 198
 199/* Semaphore for get_stram_region.  */
 200static DECLARE_MUTEX(stram_swap_sem);
 201
 202/* major and minor device number of the ST-RAM device; for the major, we use
 203 * the same as Amiga z2ram, which is really similar and impossible on Atari,
 204 * and for the minor a relatively odd number to avoid the user creating and
 205 * using that device. */
 206#define STRAM_MAJOR             Z2RAM_MAJOR
 207#define STRAM_MINOR             13
 208
 209/* Some impossible pointer value */
 210#define MAGIC_FILE_P    (struct file *)0xffffdead
 211
 212#ifdef DO_PROC
 213static unsigned stat_swap_read;
 214static unsigned stat_swap_write;
 215static unsigned stat_swap_force;
 216#endif /* DO_PROC */
 217
 218#endif /* CONFIG_STRAM_SWAP */
 219
 220/***************************** Prototypes *****************************/
 221
 222#ifdef CONFIG_STRAM_SWAP
 223static int swap_init(void *start_mem, void *swap_data);
 224static void *get_stram_region( unsigned long n_pages );
 225static void free_stram_region( unsigned long offset, unsigned long n_pages
 226                               );
 227static int in_some_region(void *addr);
 228static unsigned long find_free_region( unsigned long n_pages, unsigned long
 229                                       *total_free, unsigned long
 230                                       *region_free );
 231static void do_stram_request(request_queue_t *);
 232static int stram_open( struct inode *inode, struct file *filp );
 233static int stram_release( struct inode *inode, struct file *filp );
 234static void reserve_region(void *start, void *end);
 235#endif
 236static BLOCK *add_region( void *addr, unsigned long size );
 237static BLOCK *find_region( void *addr );
 238static int remove_region( BLOCK *block );
 239
 240/************************* End of Prototypes **************************/
 241
 242
 243/* ------------------------------------------------------------------------ */
 244/*                                                         Public Interface                                                             */
 245/* ------------------------------------------------------------------------ */
 246
 247/*
 248 * This init function is called very early by atari/config.c
 249 * It initializes some internal variables needed for stram_alloc()
 250 */
 251void __init atari_stram_init(void)
 252{
 253        int i;
 254
 255        /* initialize static blocks */
 256        for( i = 0; i < N_STATIC_BLOCKS; ++i )
 257                static_blocks[i].flags = BLOCK_FREE;
 258
 259        /* determine whether kernel code resides in ST-RAM (then ST-RAM is the
 260         * first memory block at virtual 0x0) */
 261        stram_start = phys_to_virt(0);
 262        kernel_in_stram = (stram_start == 0);
 263
 264        for( i = 0; i < m68k_num_memory; ++i ) {
 265                if (m68k_memory[i].addr == 0) {
 266                        /* skip first 2kB or page (supervisor-only!) */
 267                        stram_end = stram_start + m68k_memory[i].size;
 268                        return;
 269                }
 270        }
 271        /* Should never come here! (There is always ST-Ram!) */
 272        panic( "atari_stram_init: no ST-RAM found!" );
 273}
 274
 275
 276/*
 277 * This function is called from setup_arch() to reserve the pages needed for
 278 * ST-RAM management.
 279 */
 280void __init atari_stram_reserve_pages(void *start_mem)
 281{
 282#ifdef CONFIG_STRAM_SWAP
 283        /* if max_swap_size is negative (i.e. no stram_swap= option given),
 284         * determine at run time whether to use ST-RAM swapping */
 285        if (max_swap_size < 0)
 286                /* Use swapping if ST-RAM doesn't make up more than MAX_STRAM_FRACTION
 287                 * of total memory. In that case, the max. size is set to 16 MB,
 288                 * because ST-RAM can never be bigger than that.
 289                 * Also, never use swapping on a Hades, there's no separate ST-RAM in
 290                 * that machine. */
 291                max_swap_size =
 292                        (!MACH_IS_HADES &&
 293                         (N_PAGES(stram_end-stram_start)*MAX_STRAM_FRACTION_DENOM <=
 294                          ((unsigned long)high_memory>>PAGE_SHIFT)*MAX_STRAM_FRACTION_NOM)) ? 16*1024*1024 : 0;
 295        DPRINTK( "atari_stram_reserve_pages: max_swap_size = %d\n", max_swap_size );
 296#endif
 297
 298        /* always reserve first page of ST-RAM, the first 2 kB are
 299         * supervisor-only! */
 300        if (!kernel_in_stram)
 301                reserve_bootmem (0, PAGE_SIZE);
 302
 303#ifdef CONFIG_STRAM_SWAP
 304        {
 305                void *swap_data;
 306
 307                start_mem = (void *) PAGE_ALIGN ((unsigned long) start_mem);
 308                /* determine first page to use as swap: if the kernel is
 309                   in TT-RAM, this is the first page of (usable) ST-RAM;
 310                   otherwise just use the end of kernel data (= start_mem) */
 311                swap_start = !kernel_in_stram ? stram_start + PAGE_SIZE : start_mem;
 312                /* decrement by one page, rest of kernel assumes that first swap page
 313                 * is always reserved and maybe doesn't handle swp_entry == 0
 314                 * correctly */
 315                swap_start -= PAGE_SIZE;
 316                swap_end = stram_end;
 317                if (swap_end-swap_start > max_swap_size)
 318                        swap_end =  swap_start + max_swap_size;
 319                DPRINTK( "atari_stram_reserve_pages: swapping enabled; "
 320                                 "swap=%p-%p\n", swap_start, swap_end);
 321
 322                /* reserve some amount of memory for maintainance of
 323                 * swapping itself: one page for each 2048 (PAGE_SIZE/2)
 324                 * swap pages. (2 bytes for each page) */
 325                swap_data = start_mem;
 326                start_mem += ((SWAP_NR(swap_end) + PAGE_SIZE/2 - 1)
 327                              >> (PAGE_SHIFT-1)) << PAGE_SHIFT;
 328                /* correct swap_start if necessary */
 329                if (swap_start + PAGE_SIZE == swap_data)
 330                        swap_start = start_mem - PAGE_SIZE;
 331
 332                if (!swap_init( start_mem, swap_data )) {
 333                        printk( KERN_ERR "ST-RAM swap space initialization failed\n" );
 334                        max_swap_size = 0;
 335                        return;
 336                }
 337                /* reserve region for swapping meta-data */
 338                reserve_region(swap_data, start_mem);
 339                /* reserve swapping area itself */
 340                reserve_region(swap_start + PAGE_SIZE, swap_end);
 341
 342                /*
 343                 * If the whole ST-RAM is used for swapping, there are no allocatable
 344                 * dma pages left. But unfortunately, some shared parts of the kernel
 345                 * (particularly the SCSI mid-level) call __get_dma_pages()
 346                 * unconditionally :-( These calls then fail, and scsi.c even doesn't
 347                 * check for NULL return values and just crashes. The quick fix for
 348                 * this (instead of doing much clean up work in the SCSI code) is to
 349                 * pretend all pages are DMA-able by setting mach_max_dma_address to
 350                 * ULONG_MAX. This doesn't change any functionality so far, since
 351                 * get_dma_pages() shouldn't be used on Atari anyway anymore (better
 352                 * use atari_stram_alloc()), and the Atari SCSI drivers don't need DMA
 353                 * memory. But unfortunately there's now no kind of warning (even not
 354                 * a NULL return value) if you use get_dma_pages() nevertheless :-(
 355                 * You just will get non-DMA-able memory...
 356                 */
 357                mach_max_dma_address = 0xffffffff;
 358        }
 359#endif
 360}
 361
 362void atari_stram_mem_init_hook (void)
 363{
 364        mem_init_done = 1;
 365}
 366
 367
 368/*
 369 * This is main public interface: somehow allocate a ST-RAM block
 370 * There are three strategies:
 371 *
 372 *  - If we're before mem_init(), we have to make a static allocation. The
 373 *    region is taken in the kernel data area (if the kernel is in ST-RAM) or
 374 *    from the start of ST-RAM (if the kernel is in TT-RAM) and added to the
 375 *    rsvd_stram_* region. The ST-RAM is somewhere in the middle of kernel
 376 *    address space in the latter case.
 377 *
 378 *  - If mem_init() already has been called and ST-RAM swapping is enabled,
 379 *    try to get the memory from the (pseudo) swap-space, either free already
 380 *    or by moving some other pages out of the swap.
 381 *
 382 *  - If mem_init() already has been called, and ST-RAM swapping is not
 383 *    enabled, the only possibility is to try with __get_dma_pages(). This has
 384 *    the disadvantage that it's very hard to get more than 1 page, and it is
 385 *    likely to fail :-(
 386 *
 387 */
 388void *atari_stram_alloc(long size, const char *owner)
 389{
 390        void *addr = NULL;
 391        BLOCK *block;
 392        int flags;
 393
 394        DPRINTK("atari_stram_alloc(size=%08lx,owner=%s)\n", size, owner);
 395
 396        size = ALIGN_IF_SWAP(size);
 397        DPRINTK( "atari_stram_alloc: rounded size = %08lx\n", size );
 398#ifdef CONFIG_STRAM_SWAP
 399        if (max_swap_size) {
 400                /* If swapping is active: make some free space in the swap
 401                   "device". */
 402                DPRINTK( "atari_stram_alloc: after mem_init, swapping ok, "
 403                                 "calling get_region\n" );
 404                addr = get_stram_region( N_PAGES(size) );
 405                flags = BLOCK_INSWAP;
 406        }
 407        else
 408#endif
 409        if (!mem_init_done)
 410                return alloc_bootmem_low(size);
 411        else {
 412                /* After mem_init() and no swapping: can only resort to
 413                 * __get_dma_pages() */
 414                addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size));
 415                flags = BLOCK_GFP;
 416                DPRINTK( "atari_stram_alloc: after mem_init, swapping off, "
 417                                 "get_pages=%p\n", addr );
 418        }
 419
 420        if (addr) {
 421                if (!(block = add_region( addr, size ))) {
 422                        /* out of memory for BLOCK structure :-( */
 423                        DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- "
 424                                         "freeing again\n" );
 425#ifdef CONFIG_STRAM_SWAP
 426                        if (flags == BLOCK_INSWAP)
 427                                free_stram_region( SWAP_NR(addr), N_PAGES(size) );
 428                        else
 429#endif
 430                                free_pages((unsigned long)addr, get_order(size));
 431                        return( NULL );
 432                }
 433                block->owner = owner;
 434                block->flags |= flags;
 435        }
 436        return( addr );
 437}
 438
 439void atari_stram_free( void *addr )
 440
 441{
 442        BLOCK *block;
 443
 444        DPRINTK( "atari_stram_free(addr=%p)\n", addr );
 445
 446        if (!(block = find_region( addr ))) {
 447                printk( KERN_ERR "Attempt to free non-allocated ST-RAM block at %p "
 448                                "from %p\n", addr, __builtin_return_address(0) );
 449                return;
 450        }
 451        DPRINTK( "atari_stram_free: found block (%p): size=%08lx, owner=%s, "
 452                         "flags=%02x\n", block, block->size, block->owner, block->flags );
 453
 454#ifdef CONFIG_STRAM_SWAP
 455        if (!max_swap_size) {
 456#endif
 457                if (block->flags & BLOCK_GFP) {
 458                        DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
 459                                get_order(block->size));
 460                        free_pages((unsigned long)addr, get_order(block->size));
 461                }
 462                else
 463                        goto fail;
 464#ifdef CONFIG_STRAM_SWAP
 465        }
 466        else if (block->flags & BLOCK_INSWAP) {
 467                DPRINTK( "atari_stram_free: is swap-alloced\n" );
 468                free_stram_region( SWAP_NR(block->start), N_PAGES(block->size) );
 469        }
 470        else
 471                goto fail;
 472#endif
 473        remove_region( block );
 474        return;
 475
 476  fail:
 477        printk( KERN_ERR "atari_stram_free: cannot free block at %p "
 478                        "(called from %p)\n", addr, __builtin_return_address(0) );
 479}
 480
 481
 482#ifdef CONFIG_STRAM_SWAP
 483
 484
 485/* ------------------------------------------------------------------------ */
 486/*                                                 Main Swapping Functions                                                      */
 487/* ------------------------------------------------------------------------ */
 488
 489
 490/*
 491 * Initialize ST-RAM swap device
 492 * (lots copied and modified from sys_swapon() in mm/swapfile.c)
 493 */
 494static int __init swap_init(void *start_mem, void *swap_data)
 495{
 496        static struct dentry fake_dentry;
 497        static struct vfsmount fake_vfsmnt;
 498        struct swap_info_struct *p;
 499        struct inode swap_inode;
 500        unsigned int type;
 501        void *addr;
 502        int i, j, k, prev;
 503
 504        DPRINTK("swap_init(start_mem=%p, swap_data=%p)\n",
 505                start_mem, swap_data);
 506
 507        /* need at least one page for swapping to (and this also isn't very
 508         * much... :-) */
 509        if (swap_end - swap_start < 2*PAGE_SIZE) {
 510                printk( KERN_WARNING "stram_swap_init: swap space too small\n" );
 511                return( 0 );
 512        }
 513
 514        /* find free slot in swap_info */
 515        for( p = swap_info, type = 0; type < nr_swapfiles; type++, p++ )
 516                if (!(p->flags & SWP_USED))
 517                        break;
 518        if (type >= MAX_SWAPFILES) {
 519                printk( KERN_WARNING "stram_swap_init: max. number of "
 520                                "swap devices exhausted\n" );
 521                return( 0 );
 522        }
 523        if (type >= nr_swapfiles)
 524                nr_swapfiles = type+1;
 525
 526        stram_swap_info = p;
 527        stram_swap_type = type;
 528
 529        /* fake some dir cache entries to give us some name in /dev/swaps */
 530        fake_dentry.d_parent = &fake_dentry;
 531        fake_dentry.d_name.name = "stram (internal)";
 532        fake_dentry.d_name.len = 16;
 533        fake_vfsmnt.mnt_parent = &fake_vfsmnt;
 534
 535        p->flags        = SWP_USED;
 536        p->swap_file    = &fake_dentry;
 537        p->swap_vfsmnt  = &fake_vfsmnt;
 538        p->swap_map     = swap_data;
 539        p->cluster_nr   = 0;
 540        p->next         = -1;
 541        p->prio         = 0x7ff0;       /* a rather high priority, but not the higest
 542                                                                 * to give the user a chance to override */
 543
 544        /* call stram_open() directly, avoids at least the overhead in
 545         * constructing a dummy file structure... */
 546        swap_inode.i_rdev = MKDEV( STRAM_MAJOR, STRAM_MINOR );
 547        stram_open( &swap_inode, MAGIC_FILE_P );
 548        p->max = SWAP_NR(swap_end);
 549
 550        /* initialize swap_map: set regions that are already allocated or belong
 551         * to kernel data space to SWAP_MAP_BAD, otherwise to free */
 552        j = 0; /* # of free pages */
 553        k = 0; /* # of already allocated pages (from pre-mem_init stram_alloc()) */
 554        p->lowest_bit = 0;
 555        p->highest_bit = 0;
 556        for( i = 1, addr = SWAP_ADDR(1); i < p->max;
 557                 i++, addr += PAGE_SIZE ) {
 558                if (in_some_region( addr )) {
 559                        p->swap_map[i] = SWAP_MAP_BAD;
 560                        ++k;
 561                }
 562                else if (kernel_in_stram && addr < start_mem ) {
 563                        p->swap_map[i] = SWAP_MAP_BAD;
 564                }
 565                else {
 566                        p->swap_map[i] = 0;
 567                        ++j;
 568                        if (!p->lowest_bit) p->lowest_bit = i;
 569                        p->highest_bit = i;
 570                }
 571        }
 572        /* first page always reserved (and doesn't really belong to swap space) */
 573        p->swap_map[0] = SWAP_MAP_BAD;
 574
 575        /* now swapping to this device ok */
 576        p->pages = j + k;
 577        swap_list_lock();
 578        nr_swap_pages += j;
 579        p->flags = SWP_WRITEOK;
 580
 581        /* insert swap space into swap_list */
 582        prev = -1;
 583        for (i = swap_list.head; i >= 0; i = swap_info[i].next) {
 584                if (p->prio >= swap_info[i].prio) {
 585                        break;
 586                }
 587                prev = i;
 588        }
 589        p->next = i;
 590        if (prev < 0) {
 591                swap_list.head = swap_list.next = p - swap_info;
 592        } else {
 593                swap_info[prev].next = p - swap_info;
 594        }
 595        swap_list_unlock();
 596
 597        printk( KERN_INFO "Using %dk (%d pages) of ST-RAM as swap space.\n",
 598                        p->pages << 2, p->pages );
 599        return( 1 );
 600}
 601
 602
 603/*
 604 * The swap entry has been read in advance, and we return 1 to indicate
 605 * that the page has been used or is no longer needed.
 606 *
 607 * Always set the resulting pte to be nowrite (the same as COW pages
 608 * after one process has exited).  We don't know just how many PTEs will
 609 * share this swap entry, so be cautious and let do_wp_page work out
 610 * what to do if a write is requested later.
 611 */
 612static inline void unswap_pte(struct vm_area_struct * vma, unsigned long
 613                              address, pte_t *dir, swp_entry_t entry,
 614                              struct page *page)
 615{
 616        pte_t pte = *dir;
 617
 618        if (pte_none(pte))
 619                return;
 620        if (pte_present(pte)) {
 621                /* If this entry is swap-cached, then page must already
 622                   hold the right address for any copies in physical
 623                   memory */
 624                if (pte_page(pte) != page)
 625                        return;
 626                /* We will be removing the swap cache in a moment, so... */
 627                set_pte(dir, pte_mkdirty(pte));
 628                return;
 629        }
 630        if (pte_val(pte) != entry.val)
 631                return;
 632
 633        DPRINTK("unswap_pte: replacing entry %08lx by new page %p",
 634                entry.val, page);
 635        set_pte(dir, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
 636        swap_free(entry);
 637        get_page(page);
 638        ++vma->vm_mm->rss;
 639}
 640
 641static inline void unswap_pmd(struct vm_area_struct * vma, pmd_t *dir,
 642                              unsigned long address, unsigned long size,
 643                              unsigned long offset, swp_entry_t entry,
 644                              struct page *page)
 645{
 646        pte_t * pte;
 647        unsigned long end;
 648
 649        if (pmd_none(*dir))
 650                return;
 651        if (pmd_bad(*dir)) {
 652                pmd_ERROR(*dir);
 653                pmd_clear(dir);
 654                return;
 655        }
 656        pte = pte_offset_kernel(dir, address);
 657        offset += address & PMD_MASK;
 658        address &= ~PMD_MASK;
 659        end = address + size;
 660        if (end > PMD_SIZE)
 661                end = PMD_SIZE;
 662        do {
 663                unswap_pte(vma, offset+address-vma->vm_start, pte, entry, page);
 664                address += PAGE_SIZE;
 665                pte++;
 666        } while (address < end);
 667}
 668
 669static inline void unswap_pgd(struct vm_area_struct * vma, pgd_t *dir,
 670                              unsigned long address, unsigned long size,
 671                              swp_entry_t entry, struct page *page)
 672{
 673        pmd_t * pmd;
 674        unsigned long offset, end;
 675
 676        if (pgd_none(*dir))
 677                return;
 678        if (pgd_bad(*dir)) {
 679                pgd_ERROR(*dir);
 680                pgd_clear(dir);
 681                return;
 682        }
 683        pmd = pmd_offset(dir, address);
 684        offset = address & PGDIR_MASK;
 685        address &= ~PGDIR_MASK;
 686        end = address + size;
 687        if (end > PGDIR_SIZE)
 688                end = PGDIR_SIZE;
 689        do {
 690                unswap_pmd(vma, pmd, address, end - address, offset, entry,
 691                           page);
 692                address = (address + PMD_SIZE) & PMD_MASK;
 693                pmd++;
 694        } while (address < end);
 695}
 696
 697static void unswap_vma(struct vm_area_struct * vma, pgd_t *pgdir,
 698                       swp_entry_t entry, struct page *page)
 699{
 700        unsigned long start = vma->vm_start, end = vma->vm_end;
 701
 702        do {
 703                unswap_pgd(vma, pgdir, start, end - start, entry, page);
 704                start = (start + PGDIR_SIZE) & PGDIR_MASK;
 705                pgdir++;
 706        } while (start < end);
 707}
 708
 709static void unswap_process(struct mm_struct * mm, swp_entry_t entry,
 710                           struct page *page)
 711{
 712        struct vm_area_struct* vma;
 713
 714        /*
 715         * Go through process' page directory.
 716         */
 717        if (!mm)
 718                return;
 719        for (vma = mm->mmap; vma; vma = vma->vm_next) {
 720                pgd_t * pgd = pgd_offset(mm, vma->vm_start);
 721                unswap_vma(vma, pgd, entry, page);
 722        }
 723}
 724
 725
 726static int unswap_by_read(unsigned short *map, unsigned long max,
 727                          unsigned long start, unsigned long n_pages)
 728{
 729        struct task_struct *p;
 730        struct page *page;
 731        swp_entry_t entry;
 732        unsigned long i;
 733
 734        DPRINTK( "unswapping %lu..%lu by reading in\n",
 735                         start, start+n_pages-1 );
 736
 737        for( i = start; i < start+n_pages; ++i ) {
 738                if (map[i] == SWAP_MAP_BAD) {
 739                        printk( KERN_ERR "get_stram_region: page %lu already "
 740                                        "reserved??\n", i );
 741                        continue;
 742                }
 743
 744                if (map[i]) {
 745                        entry = swp_entry(stram_swap_type, i);
 746                        DPRINTK("unswap: map[i=%lu]=%u nr_swap=%ld\n",
 747                                i, map[i], nr_swap_pages);
 748
 749                        swap_device_lock(stram_swap_info);
 750                        map[i]++;
 751                        swap_device_unlock(stram_swap_info);
 752                        /* Get a page for the entry, using the existing
 753                           swap cache page if there is one.  Otherwise,
 754                           get a clean page and read the swap into it. */
 755                        page = read_swap_cache_async(entry, NULL, 0);
 756                        if (!page) {
 757                                swap_free(entry);
 758                                return -ENOMEM;
 759                        }
 760                        read_lock(&tasklist_lock);
 761                        for_each_process(p)
 762                                unswap_process(p->mm, entry, page);
 763                        read_unlock(&tasklist_lock);
 764                        shmem_unuse(entry, page);
 765                        /* Now get rid of the extra reference to the
 766                           temporary page we've been using. */
 767                        if (PageSwapCache(page))
 768                                delete_from_swap_cache(page);
 769                        __free_page(page);
 770        #ifdef DO_PROC
 771                        stat_swap_force++;
 772        #endif
 773                }
 774
 775                DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%ld\n",
 776                                 i, map[i], nr_swap_pages );
 777                swap_list_lock();
 778                swap_device_lock(stram_swap_info);
 779                map[i] = SWAP_MAP_BAD;
 780                if (stram_swap_info->lowest_bit == i)
 781                        stram_swap_info->lowest_bit++;
 782                if (stram_swap_info->highest_bit == i)
 783                        stram_swap_info->highest_bit--;
 784                --nr_swap_pages;
 785                swap_device_unlock(stram_swap_info);
 786                swap_list_unlock();
 787        }
 788
 789        return 0;
 790}
 791
 792/*
 793 * reserve a region in ST-RAM swap space for an allocation
 794 */
 795static void *get_stram_region( unsigned long n_pages )
 796{
 797        unsigned short *map = stram_swap_info->swap_map;
 798        unsigned long max = stram_swap_info->max;
 799        unsigned long start, total_free, region_free;
 800        int err;
 801        void *ret = NULL;
 802
 803        DPRINTK( "get_stram_region(n_pages=%lu)\n", n_pages );
 804
 805        down(&stram_swap_sem);
 806
 807        /* disallow writing to the swap device now */
 808        stram_swap_info->flags = SWP_USED;
 809
 810        /* find a region of n_pages pages in the swap space including as much free
 811         * pages as possible (and excluding any already-reserved pages). */
 812        if (!(start = find_free_region( n_pages, &total_free, &region_free )))
 813                goto end;
 814        DPRINTK( "get_stram_region: region starts at %lu, has %lu free pages\n",
 815                         start, region_free );
 816
 817        err = unswap_by_read(map, max, start, n_pages);
 818        if (err)
 819                goto end;
 820
 821        ret = SWAP_ADDR(start);
 822  end:
 823        /* allow using swap device again */
 824        stram_swap_info->flags = SWP_WRITEOK;
 825        up(&stram_swap_sem);
 826        DPRINTK( "get_stram_region: returning %p\n", ret );
 827        return( ret );
 828}
 829
 830
 831/*
 832 * free a reserved region in ST-RAM swap space
 833 */
 834static void free_stram_region( unsigned long offset, unsigned long n_pages )
 835{
 836        unsigned short *map = stram_swap_info->swap_map;
 837
 838        DPRINTK( "free_stram_region(offset=%lu,n_pages=%lu)\n", offset, n_pages );
 839
 840        if (offset < 1 || offset + n_pages > stram_swap_info->max) {
 841                printk( KERN_ERR "free_stram_region: Trying to free non-ST-RAM\n" );
 842                return;
 843        }
 844
 845        swap_list_lock();
 846        swap_device_lock(stram_swap_info);
 847        /* un-reserve the freed pages */
 848        for( ; n_pages > 0; ++offset, --n_pages ) {
 849                if (map[offset] != SWAP_MAP_BAD)
 850                        printk( KERN_ERR "free_stram_region: Swap page %lu was not "
 851                                        "reserved\n", offset );
 852                map[offset] = 0;
 853        }
 854
 855        /* update swapping meta-data */
 856        if (offset < stram_swap_info->lowest_bit)
 857                stram_swap_info->lowest_bit = offset;
 858        if (offset+n_pages-1 > stram_swap_info->highest_bit)
 859                stram_swap_info->highest_bit = offset+n_pages-1;
 860        if (stram_swap_info->prio > swap_info[swap_list.next].prio)
 861                swap_list.next = swap_list.head;
 862        nr_swap_pages += n_pages;
 863        swap_device_unlock(stram_swap_info);
 864        swap_list_unlock();
 865}
 866
 867
 868/* ------------------------------------------------------------------------ */
 869/*                                              Utility Functions for Swapping                                          */
 870/* ------------------------------------------------------------------------ */
 871
 872
 873/* is addr in some of the allocated regions? */
 874static int in_some_region(void *addr)
 875{
 876        BLOCK *p;
 877
 878        for( p = alloc_list; p; p = p->next ) {
 879                if (p->start <= addr && addr < p->start + p->size)
 880                        return( 1 );
 881        }
 882        return( 0 );
 883}
 884
 885
 886static unsigned long find_free_region(unsigned long n_pages,
 887                                      unsigned long *total_free,
 888                                      unsigned long *region_free)
 889{
 890        unsigned short *map = stram_swap_info->swap_map;
 891        unsigned long max = stram_swap_info->max;
 892        unsigned long head, tail, max_start;
 893        long nfree, max_free;
 894
 895        /* first scan the swap space for a suitable place for the allocation */
 896        head = 1;
 897        max_start = 0;
 898        max_free = -1;
 899        *total_free = 0;
 900
 901  start_over:
 902        /* increment tail until final window size reached, and count free pages */
 903        nfree = 0;
 904        for( tail = head; tail-head < n_pages && tail < max; ++tail ) {
 905                if (map[tail] == SWAP_MAP_BAD) {
 906                        head = tail+1;
 907                        goto start_over;
 908                }
 909                if (!map[tail]) {
 910                        ++nfree;
 911                        ++*total_free;
 912                }
 913        }
 914        if (tail-head < n_pages)
 915                goto out;
 916        if (nfree > max_free) {
 917                max_start = head;
 918                max_free  = nfree;
 919                if (max_free >= n_pages)
 920                        /* don't need more free pages... :-) */
 921                        goto out;
 922        }
 923
 924        /* now shift the window and look for the area where as much pages as
 925         * possible are free */
 926        while( tail < max ) {
 927                nfree -= (map[head++] == 0);
 928                if (map[tail] == SWAP_MAP_BAD) {
 929                        head = tail+1;
 930                        goto start_over;
 931                }
 932                if (!map[tail]) {
 933                        ++nfree;
 934                        ++*total_free;
 935                }
 936                ++tail;
 937                if (nfree > max_free) {
 938                        max_start = head;
 939                        max_free  = nfree;
 940                        if (max_free >= n_pages)
 941                                /* don't need more free pages... :-) */
 942                                goto out;
 943                }
 944        }
 945
 946  out:
 947        if (max_free < 0) {
 948                printk( KERN_NOTICE "get_stram_region: ST-RAM too full or fragmented "
 949                                "-- can't allocate %lu pages\n", n_pages );
 950                return( 0 );
 951        }
 952
 953        *region_free = max_free;
 954        return( max_start );
 955}
 956
 957
 958/* setup parameters from command line */
 959void __init stram_swap_setup(char *str, int *ints)
 960{
 961        if (ints[0] >= 1)
 962                max_swap_size = ((ints[1] < 0 ? 0 : ints[1]) * 1024) & PAGE_MASK;
 963}
 964
 965
 966/* ------------------------------------------------------------------------ */
 967/*                                                              ST-RAM device                                                           */
 968/* ------------------------------------------------------------------------ */
 969
 970static int refcnt;
 971
 972static void do_stram_request(request_queue_t *q)
 973{
 974        struct request *req;
 975
 976        while ((req = elv_next_request(q)) != NULL) {
 977                void *start = swap_start + (req->sector << 9);
 978                unsigned long len = req->current_nr_sectors << 9;
 979                if ((start + len) > swap_end) {
 980                        printk( KERN_ERR "stram: bad access beyond end of device: "
 981                                        "block=%ld, count=%d\n",
 982                                        req->sector,
 983                                        req->current_nr_sectors );
 984                        end_request(req, 0);
 985                        continue;
 986                }
 987
 988                if (req->cmd == READ) {
 989                        memcpy(req->buffer, start, len);
 990#ifdef DO_PROC
 991                        stat_swap_read += N_PAGES(len);
 992#endif
 993                }
 994                else {
 995                        memcpy(start, req->buffer, len);
 996#ifdef DO_PROC
 997                        stat_swap_write += N_PAGES(len);
 998#endif
 999                }
1000                end_request(req, 1);
1001        }
1002}
1003
1004
1005static int stram_open( struct inode *inode, struct file *filp )
1006{
1007        if (filp != MAGIC_FILE_P) {
1008                printk( KERN_NOTICE "Only kernel can open ST-RAM device\n" );
1009                return( -EPERM );
1010        }
1011        if (refcnt)
1012                return( -EBUSY );
1013        ++refcnt;
1014        return( 0 );
1015}
1016
1017static int stram_release( struct inode *inode, struct file *filp )
1018{
1019        if (filp != MAGIC_FILE_P) {
1020                printk( KERN_NOTICE "Only kernel can close ST-RAM device\n" );
1021                return( -EPERM );
1022        }
1023        if (refcnt > 0)
1024                --refcnt;
1025        return( 0 );
1026}
1027
1028
1029static struct block_device_operations stram_fops = {
1030        .open =         stram_open,
1031        .release =      stram_release,
1032};
1033
1034static struct gendisk *stram_disk;
1035static struct request_queue *stram_queue;
1036static spinlock_t stram_lock = SPIN_LOCK_UNLOCKED;
1037
1038int __init stram_device_init(void)
1039{
1040        if (!MACH_IS_ATARI)
1041                /* no point in initializing this, I hope */
1042                return -ENXIO;
1043
1044        if (!max_swap_size)
1045                /* swapping not enabled */
1046                return -ENXIO;
1047        stram_disk = alloc_disk(1);
1048        if (!stram_disk)
1049                return -ENOMEM;
1050
1051        if (register_blkdev(STRAM_MAJOR, "stram")) {
1052                put_disk(stram_disk);
1053                return -ENXIO;
1054        }
1055
1056        stram_queue = blk_init_queue(do_stram_request, &stram_lock);
1057        if (!stram_queue) {
1058                unregister_blkdev(STRAM_MAJOR, "stram");
1059                put_disk(stram_disk);
1060                return -ENOMEM;
1061        }
1062
1063        stram_disk->major = STRAM_MAJOR;
1064        stram_disk->first_minor = STRAM_MINOR;
1065        stram_disk->fops = &stram_fops;
1066        stram_disk->queue = stram_queue;
1067        sprintf(stram_disk->disk_name, "stram");
1068        set_capacity(stram_disk, (swap_end - swap_start)/512);
1069        add_disk(stram_disk);
1070        return 0;
1071}
1072
1073
1074
1075/* ------------------------------------------------------------------------ */
1076/*                                                      Misc Utility Functions                                                  */
1077/* ------------------------------------------------------------------------ */
1078
1079/* reserve a range of pages */
1080static void reserve_region(void *start, void *end)
1081{
1082        reserve_bootmem (virt_to_phys(start), end - start);
1083}
1084
1085#endif /* CONFIG_STRAM_SWAP */
1086
1087
1088/* ------------------------------------------------------------------------ */
1089/*                                                        Region Management                                                             */
1090/* ------------------------------------------------------------------------ */
1091
1092
1093/* insert a region into the alloced list (sorted) */
1094static BLOCK *add_region( void *addr, unsigned long size )
1095{
1096        BLOCK **p, *n = NULL;
1097        int i;
1098
1099        for( i = 0; i < N_STATIC_BLOCKS; ++i ) {
1100                if (static_blocks[i].flags & BLOCK_FREE) {
1101                        n = &static_blocks[i];
1102                        n->flags = 0;
1103                        break;
1104                }
1105        }
1106        if (!n && mem_init_done) {
1107                /* if statics block pool exhausted and we can call kmalloc() already
1108                 * (after mem_init()), try that */
1109                n = kmalloc( sizeof(BLOCK), GFP_KERNEL );
1110                if (n)
1111                        n->flags = BLOCK_KMALLOCED;
1112        }
1113        if (!n) {
1114                printk( KERN_ERR "Out of memory for ST-RAM descriptor blocks\n" );
1115                return( NULL );
1116        }
1117        n->start = addr;
1118        n->size  = size;
1119
1120        for( p = &alloc_list; *p; p = &((*p)->next) )
1121                if ((*p)->start > addr) break;
1122        n->next = *p;
1123        *p = n;
1124
1125        return( n );
1126}
1127
1128
1129/* find a region (by start addr) in the alloced list */
1130static BLOCK *find_region( void *addr )
1131{
1132        BLOCK *p;
1133
1134        for( p = alloc_list; p; p = p->next ) {
1135                if (p->start == addr)
1136                        return( p );
1137                if (p->start > addr)
1138                        break;
1139        }
1140        return( NULL );
1141}
1142
1143
1144/* remove a block from the alloced list */
1145static int remove_region( BLOCK *block )
1146{
1147        BLOCK **p;
1148
1149        for( p = &alloc_list; *p; p = &((*p)->next) )
1150                if (*p == block) break;
1151        if (!*p)
1152                return( 0 );
1153
1154        *p = block->next;
1155        if (block->flags & BLOCK_KMALLOCED)
1156                kfree( block );
1157        else
1158                block->flags |= BLOCK_FREE;
1159        return( 1 );
1160}
1161
1162
1163
1164/* ------------------------------------------------------------------------ */
1165/*                                               /proc statistics file stuff                                            */
1166/* ------------------------------------------------------------------------ */
1167
1168#ifdef DO_PROC
1169
1170#define PRINT_PROC(fmt,args...) len += sprintf( buf+len, fmt, ##args )
1171
1172int get_stram_list( char *buf )
1173{
1174        int len = 0;
1175        BLOCK *p;
1176#ifdef CONFIG_STRAM_SWAP
1177        int i;
1178        unsigned short *map = stram_swap_info->swap_map;
1179        unsigned long max = stram_swap_info->max;
1180        unsigned free = 0, used = 0, rsvd = 0;
1181#endif
1182
1183#ifdef CONFIG_STRAM_SWAP
1184        if (max_swap_size) {
1185                for( i = 1; i < max; ++i ) {
1186                        if (!map[i])
1187                                ++free;
1188                        else if (map[i] == SWAP_MAP_BAD)
1189                                ++rsvd;
1190                        else
1191                                ++used;
1192                }
1193                PRINT_PROC(
1194                        "Total ST-RAM:      %8u kB\n"
1195                        "Total ST-RAM swap: %8lu kB\n"
1196                        "Free swap:         %8u kB\n"
1197                        "Used swap:         %8u kB\n"
1198                        "Allocated swap:    %8u kB\n"
1199                        "Swap Reads:        %8u\n"
1200                        "Swap Writes:       %8u\n"
1201                        "Swap Forced Reads: %8u\n",
1202                        (stram_end - stram_start) >> 10,
1203                        (max-1) << (PAGE_SHIFT-10),
1204                        free << (PAGE_SHIFT-10),
1205                        used << (PAGE_SHIFT-10),
1206                        rsvd << (PAGE_SHIFT-10),
1207                        stat_swap_read,
1208                        stat_swap_write,
1209                        stat_swap_force );
1210        }
1211        else {
1212#endif
1213                PRINT_PROC( "ST-RAM swapping disabled\n" );
1214                PRINT_PROC("Total ST-RAM:      %8u kB\n",
1215                           (stram_end - stram_start) >> 10);
1216#ifdef CONFIG_STRAM_SWAP
1217        }
1218#endif
1219
1220        PRINT_PROC( "Allocated regions:\n" );
1221        for( p = alloc_list; p; p = p->next ) {
1222                if (len + 50 >= PAGE_SIZE)
1223                        break;
1224                PRINT_PROC("0x%08lx-0x%08lx: %s (",
1225                           virt_to_phys(p->start),
1226                           virt_to_phys(p->start+p->size-1),
1227                           p->owner);
1228                if (p->flags & BLOCK_GFP)
1229                        PRINT_PROC( "page-alloced)\n" );
1230                else if (p->flags & BLOCK_INSWAP)
1231                        PRINT_PROC( "in swap)\n" );
1232                else
1233                        PRINT_PROC( "??)\n" );
1234        }
1235
1236        return( len );
1237}
1238
1239#endif
1240
1241
1242/*
1243 * Local variables:
1244 *  c-indent-level: 4
1245 *  tab-width: 4
1246 * End:
1247 */
1248
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.