Changeset 896ad9f in mainline


Ignore:
Timestamp:
2009-01-31T13:12:14Z (15 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
53634f9
Parents:
7c98874
Message:

use pseudorandom generator to avoid even the longest path of livelock collisions

Location:
kernel/arch/ppc32
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ppc32/include/mm/tlb.h

    r7c98874 r896ad9f  
    6060
    6161extern void pht_refill(int n, istate_t *istate);
    62 extern bool pht_real_refill(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
     62extern bool pht_refill_real(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
    6363extern void pht_init(void);
    6464
  • kernel/arch/ppc32/src/exception.S

    r7c98874 r896ad9f  
    226226        mr r4, sp
    227227        addi r4, r4, 8
    228         bl pht_real_refill
     228        bl pht_refill_real
    229229       
    230230        cmpwi r3, 0
     
    238238        mr r4, sp
    239239        addi r4, r4, 8
    240         bl pht_real_refill
     240        bl pht_refill_real
    241241       
    242242        cmpwi r3, 0
     
    282282
    283283iret_real:
    284        
    285284        lwz r0, 8(sp)
    286285        lwz r2, 12(sp)
  • kernel/arch/ppc32/src/mm/tlb.c

    r7c98874 r896ad9f  
    4141#include <print.h>
    4242#include <symtab.h>
     43
     44
     45static unsigned int seed = 10;
     46static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
    4347
    4448
     
    126130
    127131
     132/** Pseudorandom generator
     133 *
     134 * A pretty standard linear congruential pseudorandom
     135 * number generator (m = 2^32).
     136 *
     137 */
     138#define RANDI(seed) \
     139        ({ \
     140                (seed) = 1103515245 * (seed) + 12345; \
     141                (seed); \
     142        })
     143
     144
    128145static void pht_insert(const uintptr_t vaddr, const pte_t *pte)
    129146{
     
    181198               
    182199                if (!found)
    183                         i = page % 8;
    184         }
    185        
    186        
     200                        i = RANDI(seed) % 8;
     201        }
    187202       
    188203        phte[base + i].v = 1;
     
    195210        phte[base + i].wimg = (pte->page_cache_disable ? WIMG_NO_CACHE : 0);
    196211        phte[base + i].pp = 2; // FIXME
    197 }
    198 
    199 
    200 static void pht_real_insert(const uintptr_t vaddr, const pfn_t pfn)
    201 {
    202         uint32_t page = (vaddr >> 12) & 0xffff;
    203         uint32_t api = (vaddr >> 22) & 0x3f;
    204        
    205         uint32_t vsid;
    206         asm volatile (
    207                 "mfsrin %0, %1\n"
    208                 : "=r" (vsid)
    209                 : "r" (vaddr)
    210         );
    211        
    212         uint32_t sdr1;
    213         asm volatile (
    214                 "mfsdr1 %0\n"
    215                 : "=r" (sdr1)
    216         );
    217         phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000);
    218        
    219         /* Primary hash (xor) */
    220         uint32_t h = 0;
    221         uint32_t hash = vsid ^ page;
    222         uint32_t base = (hash & 0x3ff) << 3;
    223         uint32_t i;
    224         bool found = false;
    225        
    226         /* Find unused or colliding PTE in PTEG */
    227         for (i = 0; i < 8; i++) {
    228                 if ((!phte_physical[base + i].v) ||
    229                     ((phte_physical[base + i].vsid == vsid)
    230                     && (phte_physical[base + i].api == api)
    231                     && (phte_physical[base + i].h == 0))) {
    232                         found = true;
    233                         break;
    234                 }
    235         }
    236        
    237         if (!found) {
    238                 /* Secondary hash (not) */
    239                 uint32_t base2 = (~hash & 0x3ff) << 3;
    240                
    241                 /* Find unused or colliding PTE in PTEG */
    242                 for (i = 0; i < 8; i++) {
    243                         if ((!phte_physical[base2 + i].v) ||
    244                             ((phte_physical[base2 + i].vsid == vsid)
    245                             && (phte_physical[base2 + i].api == api)
    246                             && (phte_physical[base2 + i].h == 1))) {
    247                                 found = true;
    248                                 base = base2;
    249                                 h = 1;
    250                                 break;
    251                         }
    252                 }
    253                
    254                 if (!found) {
    255                         i = page % 8;
    256                         base = base2;
    257                         h = 1;
    258                 }
    259         }
    260        
    261         phte_physical[base + i].v = 1;
    262         phte_physical[base + i].vsid = vsid;
    263         phte_physical[base + i].h = h;
    264         phte_physical[base + i].api = api;
    265         phte_physical[base + i].rpn = pfn;
    266         phte_physical[base + i].r = 0;
    267         phte_physical[base + i].c = 0;
    268         phte_physical[base + i].wimg = 0;
    269         phte_physical[base + i].pp = 2; // FIXME
    270212}
    271213
     
    337279 *
    338280 */
    339 bool pht_real_refill(int n, istate_t *istate)
     281bool pht_refill_real(int n, istate_t *istate)
    340282{
    341283        uintptr_t badvaddr;
     
    352294        );
    353295       
    354         if ((badvaddr >= PA2KA(0)) && (badvaddr < PA2KA(physmem))) {
    355                 pht_real_insert(badvaddr, KA2PA(badvaddr) >> 12);
    356                 return true;
    357         }
    358        
    359         return false;
     296        if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
     297                return false;
     298       
     299        uint32_t page = (badvaddr >> 12) & 0xffff;
     300        uint32_t api = (badvaddr >> 22) & 0x3f;
     301       
     302        uint32_t vsid;
     303        asm volatile (
     304                "mfsrin %0, %1\n"
     305                : "=r" (vsid)
     306                : "r" (badvaddr)
     307        );
     308       
     309        uint32_t sdr1;
     310        asm volatile (
     311                "mfsdr1 %0\n"
     312                : "=r" (sdr1)
     313        );
     314        phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000);
     315       
     316        /* Primary hash (xor) */
     317        uint32_t h = 0;
     318        uint32_t hash = vsid ^ page;
     319        uint32_t base = (hash & 0x3ff) << 3;
     320        uint32_t i;
     321        bool found = false;
     322       
     323        /* Find unused or colliding PTE in PTEG */
     324        for (i = 0; i < 8; i++) {
     325                if ((!phte_real[base + i].v) ||
     326                    ((phte_real[base + i].vsid == vsid)
     327                    && (phte_real[base + i].api == api)
     328                    && (phte_real[base + i].h == 0))) {
     329                        found = true;
     330                        break;
     331                }
     332        }
     333       
     334        if (!found) {
     335                /* Secondary hash (not) */
     336                uint32_t base2 = (~hash & 0x3ff) << 3;
     337               
     338                /* Find unused or colliding PTE in PTEG */
     339                for (i = 0; i < 8; i++) {
     340                        if ((!phte_real[base2 + i].v) ||
     341                            ((phte_real[base2 + i].vsid == vsid)
     342                            && (phte_real[base2 + i].api == api)
     343                            && (phte_real[base2 + i].h == 1))) {
     344                                found = true;
     345                                base = base2;
     346                                h = 1;
     347                                break;
     348                        }
     349                }
     350               
     351                if (!found) {
     352                        /* Use secondary hash to avoid collisions
     353                           with usual PHT refill handler. */
     354                        i = RANDI(seed_real) % 8;
     355                        base = base2;
     356                        h = 1;
     357                }
     358        }
     359       
     360        phte_real[base + i].v = 1;
     361        phte_real[base + i].vsid = vsid;
     362        phte_real[base + i].h = h;
     363        phte_real[base + i].api = api;
     364        phte_real[base + i].rpn = KA2PA(badvaddr) >> 12;
     365        phte_real[base + i].r = 0;
     366        phte_real[base + i].c = 0;
     367        phte_real[base + i].wimg = 0;
     368        phte_real[base + i].pp = 2; // FIXME
     369       
     370        return true;
    360371}
    361372
     
    439450                        : "r" (sr << 28)
    440451                );
    441                 printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr,
     452                printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr,
    442453                    sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4,
    443454                    ((vsid >> 30) & 1) ? " supervisor" : "",
Note: See TracChangeset for help on using the changeset viewer.