Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 29 May 2011 18:30:20 +0000 (11:30 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 29 May 2011 18:30:20 +0000 (11:30 -0700)
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6:
  [S390] mm: fix mmu_gather rework
  [S390] mm: fix storage key handling

arch/s390/include/asm/pgtable.h
arch/s390/mm/pgtable.c
include/linux/page-flags.h

index c4773a2ef3d3ab2f3c672ed70dcc6c7117855c4f..e4efacfe1b63a7ea936910e230f2e7a701729a76 100644 (file)
@@ -577,16 +577,16 @@ static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste)
 static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste)
 {
 #ifdef CONFIG_PGSTE
-       unsigned long pfn, bits;
+       unsigned long address, bits;
        unsigned char skey;
 
-       pfn = pte_val(*ptep) >> PAGE_SHIFT;
-       skey = page_get_storage_key(pfn);
+       address = pte_val(*ptep) & PAGE_MASK;
+       skey = page_get_storage_key(address);
        bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED);
        /* Clear page changed & referenced bit in the storage key */
        if (bits) {
                skey ^= bits;
-               page_set_storage_key(pfn, skey, 1);
+               page_set_storage_key(address, skey, 1);
        }
        /* Transfer page changed & referenced bit to guest bits in pgste */
        pgste_val(pgste) |= bits << 48;         /* RCP_GR_BIT & RCP_GC_BIT */
@@ -628,16 +628,16 @@ static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste)
 static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste)
 {
 #ifdef CONFIG_PGSTE
-       unsigned long pfn;
+       unsigned long address;
        unsigned long okey, nkey;
 
-       pfn = pte_val(*ptep) >> PAGE_SHIFT;
-       okey = nkey = page_get_storage_key(pfn);
+       address = pte_val(*ptep) & PAGE_MASK;
+       okey = nkey = page_get_storage_key(address);
        nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT);
        /* Set page access key and fetch protection bit from pgste */
        nkey |= (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56;
        if (okey != nkey)
-               page_set_storage_key(pfn, nkey, 1);
+               page_set_storage_key(address, nkey, 1);
 #endif
 }
 
index 14c6fae6fe6ba61e8ae0afbdfdd821464ae3a00b..b09763fe5da1a5385f1b77c17f5949c0ffdd592d 100644 (file)
@@ -71,12 +71,15 @@ static void rcu_table_freelist_callback(struct rcu_head *head)
 
 void rcu_table_freelist_finish(void)
 {
-       struct rcu_table_freelist *batch = __get_cpu_var(rcu_table_freelist);
+       struct rcu_table_freelist **batchp = &get_cpu_var(rcu_table_freelist);
+       struct rcu_table_freelist *batch = *batchp;
 
        if (!batch)
-               return;
+               goto out;
        call_rcu(&batch->rcu, rcu_table_freelist_callback);
-       __get_cpu_var(rcu_table_freelist) = NULL;
+       *batchp = NULL;
+out:
+       put_cpu_var(rcu_table_freelist);
 }
 
 static void smp_sync(void *arg)
@@ -141,20 +144,23 @@ void crst_table_free_rcu(struct mm_struct *mm, unsigned long *table)
 {
        struct rcu_table_freelist *batch;
 
+       preempt_disable();
        if (atomic_read(&mm->mm_users) < 2 &&
            cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) {
                crst_table_free(mm, table);
-               return;
+               goto out;
        }
        batch = rcu_table_freelist_get(mm);
        if (!batch) {
                smp_call_function(smp_sync, NULL, 1);
                crst_table_free(mm, table);
-               return;
+               goto out;
        }
        batch->table[--batch->crst_index] = table;
        if (batch->pgt_index >= batch->crst_index)
                rcu_table_freelist_finish();
+out:
+       preempt_enable();
 }
 
 #ifdef CONFIG_64BIT
@@ -323,16 +329,17 @@ void page_table_free_rcu(struct mm_struct *mm, unsigned long *table)
        struct page *page;
        unsigned long bits;
 
+       preempt_disable();
        if (atomic_read(&mm->mm_users) < 2 &&
            cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) {
                page_table_free(mm, table);
-               return;
+               goto out;
        }
        batch = rcu_table_freelist_get(mm);
        if (!batch) {
                smp_call_function(smp_sync, NULL, 1);
                page_table_free(mm, table);
-               return;
+               goto out;
        }
        bits = (mm->context.has_pgste) ? 3UL : 1UL;
        bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long);
@@ -345,6 +352,8 @@ void page_table_free_rcu(struct mm_struct *mm, unsigned long *table)
        batch->table[batch->pgt_index++] = table;
        if (batch->pgt_index >= batch->crst_index)
                rcu_table_freelist_finish();
+out:
+       preempt_enable();
 }
 
 /*
index 79a6700b716263a4f504627aa974f61e755bff9c..6081493db68ff65aadcf3316128d0130a6973f1d 100644 (file)
@@ -308,7 +308,7 @@ static inline void SetPageUptodate(struct page *page)
 {
 #ifdef CONFIG_S390
        if (!test_and_set_bit(PG_uptodate, &page->flags))
-               page_set_storage_key(page_to_pfn(page), PAGE_DEFAULT_KEY, 0);
+               page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, 0);
 #else
        /*
         * Memory barrier must be issued before setting the PG_uptodate bit,
This page took 0.030371 seconds and 5 git commands to generate.