upgrade to linux 2.6.10-1.12_FC2
[linux-2.6.git] / arch / ia64 / kernel / unwind.c
index 69e095a..050ae05 100644 (file)
@@ -1269,7 +1269,6 @@ script_new (unsigned long ip)
 {
        struct unw_script *script, *prev, *tmp;
        unw_hash_index_t index;
-       unsigned long flags;
        unsigned short head;
 
        STAT(++unw.stat.script.news);
@@ -1278,13 +1277,9 @@ script_new (unsigned long ip)
         * Can't (easily) use cmpxchg() here because of ABA problem
         * that is intrinsic in cmpxchg()...
         */
-       spin_lock_irqsave(&unw.lock, flags);
-       {
-               head = unw.lru_head;
-               script = unw.cache + head;
-               unw.lru_head = script->lru_chain;
-       }
-       spin_unlock(&unw.lock);
+       head = unw.lru_head;
+       script = unw.cache + head;
+       unw.lru_head = script->lru_chain;
 
        /*
         * We'd deadlock here if we interrupted a thread that is holding a read lock on
@@ -1295,43 +1290,39 @@ script_new (unsigned long ip)
        if (!write_trylock(&script->lock))
                return NULL;
 
-       spin_lock(&unw.lock);
-       {
-               /* re-insert script at the tail of the LRU chain: */
-               unw.cache[unw.lru_tail].lru_chain = head;
-               unw.lru_tail = head;
-
-               /* remove the old script from the hash table (if it's there): */
-               if (script->ip) {
-                       index = hash(script->ip);
-                       tmp = unw.cache + unw.hash[index];
-                       prev = NULL;
-                       while (1) {
-                               if (tmp == script) {
-                                       if (prev)
-                                               prev->coll_chain = tmp->coll_chain;
-                                       else
-                                               unw.hash[index] = tmp->coll_chain;
-                                       break;
-                               } else
-                                       prev = tmp;
-                               if (tmp->coll_chain >= UNW_CACHE_SIZE)
-                               /* old script wasn't in the hash-table */
-                                       break;
-                               tmp = unw.cache + tmp->coll_chain;
-                       }
+       /* re-insert script at the tail of the LRU chain: */
+       unw.cache[unw.lru_tail].lru_chain = head;
+       unw.lru_tail = head;
+
+       /* remove the old script from the hash table (if it's there): */
+       if (script->ip) {
+               index = hash(script->ip);
+               tmp = unw.cache + unw.hash[index];
+               prev = NULL;
+               while (1) {
+                       if (tmp == script) {
+                               if (prev)
+                                       prev->coll_chain = tmp->coll_chain;
+                               else
+                                       unw.hash[index] = tmp->coll_chain;
+                               break;
+                       } else
+                               prev = tmp;
+                       if (tmp->coll_chain >= UNW_CACHE_SIZE)
+                       /* old script wasn't in the hash-table */
+                               break;
+                       tmp = unw.cache + tmp->coll_chain;
                }
+       }
 
-               /* enter new script in the hash table */
-               index = hash(ip);
-               script->coll_chain = unw.hash[index];
-               unw.hash[index] = script - unw.cache;
+       /* enter new script in the hash table */
+       index = hash(ip);
+       script->coll_chain = unw.hash[index];
+       unw.hash[index] = script - unw.cache;
 
-               script->ip = ip;        /* set new IP while we're holding the locks */
+       script->ip = ip;        /* set new IP while we're holding the locks */
 
-               STAT(if (script->coll_chain < UNW_CACHE_SIZE) ++unw.stat.script.collisions);
-       }
-       spin_unlock_irqrestore(&unw.lock, flags);
+       STAT(if (script->coll_chain < UNW_CACHE_SIZE) ++unw.stat.script.collisions);
 
        script->flags = 0;
        script->hint = 0;
@@ -1830,6 +1821,7 @@ find_save_locs (struct unw_frame_info *info)
 {
        int have_write_lock = 0;
        struct unw_script *scr;
+       unsigned long flags = 0;
 
        if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf)) || info->ip < TASK_SIZE) {
                /* don't let obviously bad addresses pollute the cache */
@@ -1841,8 +1833,10 @@ find_save_locs (struct unw_frame_info *info)
 
        scr = script_lookup(info);
        if (!scr) {
+               spin_lock_irqsave(&unw.lock, flags);
                scr = build_script(info);
                if (!scr) {
+                       spin_unlock_irqrestore(&unw.lock, flags);
                        UNW_DPRINT(0,
                                   "unwind.%s: failed to locate/build unwind script for ip %lx\n",
                                   __FUNCTION__, info->ip);
@@ -1855,9 +1849,10 @@ find_save_locs (struct unw_frame_info *info)
 
        run_script(scr, info);
 
-       if (have_write_lock)
+       if (have_write_lock) {
                write_unlock(&scr->lock);
-       else
+               spin_unlock_irqrestore(&unw.lock, flags);
+       } else
                read_unlock(&scr->lock);
        return 0;
 }