Subject: [RESUME] R3000 swapping problems

From: Florian Lohoff <[email-masked]>
Date: Sun, 28 Jan 2001 17:24:01 +0100

Hi,
after a weekend research i am a bit stuck in my understanding of the
R3000 swapping problems 

When changing

Index: include/asm-mips/pgtable.h
===================================================================
RCS file: /cvs/linux/include/asm-mips/pgtable.h,v
retrieving revision 1.48
diff -u -r1.48 pgtable.h
--- include/asm-mips/pgtable.h	2000/12/03 15:30:52	1.48
+++ include/asm-mips/pgtable.h	2001/01/28 16:08:17
@@ -457,8 +457,8 @@
 				unsigned long address, pte_t pte);
 
 #define SWP_TYPE(x)		(((x).val >> 1) & 0x3f)
-#define SWP_OFFSET(x)		((x).val >> 8)
-#define SWP_ENTRY(type,offset)	((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
+#define SWP_OFFSET(x)		((x).val >> 10)
+#define SWP_ENTRY(type,offset)	((swp_entry_t) { ((type) << 1) | ((offset) << 10) })
 #define pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
 #define swp_entry_to_pte(x)	((pte_t) { (x).val })

The R3k machine (Decstation 5000/120) does survive swapping. The 
idea is that the bits 9 & 10 on the R3k are

#define _PAGE_VALID                 (1<<9)
#define _PAGE_SILENT_READ           (1<<9)  /* synonym                 */
#define _PAGE_DIRTY                 (1<<10) /* The MIPS dirty bit      */
#define _PAGE_SILENT_WRITE          (1<<10)

Whereas this on R4k is 

#define _PAGE_VALID                 (1<<7)
#define _PAGE_SILENT_READ           (1<<7)  /* synonym                 */
#define _PAGE_DIRTY                 (1<<8)  /* The MIPS dirty bit      */
#define _PAGE_SILENT_WRITE          (1<<8)

OTOH when following the code paths the pte gets completely replaced
with the swap entry and not bitmasked/and/ored with the original 
pte or the ptes flags. So i find no dependencie to the SWP_ macros.

Swapin is in mm/memory.c:do_swap_page

   1039         pte = mk_pte(page, vma->vm_page_prot);
   1040 
   1041         /*
   1042          * Freeze the "shared"ness of the page, ie page_count + swap_count.
   1043          * Must lock page before transferring our swap count to already
   1044          * obtained page count.
   1045          */
   1046         lock_page(page);
   1047         swap_free(entry);
   1048         if (write_access && !is_page_shared(page))
   1049                 pte = pte_mkwrite(pte_mkdirty(pte));
   1050         UnlockPage(page);
   1051 
   1052         set_pte(page_table, pte);
   1053 
   1054         /* No need to invalidate - it was non-present before */
   1055         update_mmu_cache(vma, address, pte);
   1056         return 1;       /* Minor fault */

The swapout code is in mm/vmscan.c:try_to_swap_out

    144         entry = get_swap_page();
    145         if (!entry.val)
    146                 goto out_unlock_restore; /* No swap space left */
    147 
    148         /* Add it to the swap cache and mark it dirty */
    149         add_to_swap_cache(page, entry);
    150         set_page_dirty(page);
    151         goto set_swap_pte;

     98 set_swap_pte:
     99                 swap_duplicate(entry);
    100                 set_pte(page_table, swp_entry_to_pte(entry));
    101 drop_pte:
    102                 UnlockPage(page);
    103                 mm->rss--;
    104                 deactivate_page(page);
    105                 page_cache_release(page);
    106 out_failed:
    107                 return 0;
    108         }

When adding debug code there i can see the flags getting restored
correctly on swapping in.

Flo
-- 
Florian Lohoff                  [email-masked]             +49-5201-669912
     Why is it called "common sense" when nobody seems to have any?