kernel panic - ip_vs_conn_hash(): request for already hashed

Roberto Nibali ratz at drugphish.ch
Wed Jun 28 23:08:17 BST 2006


Hello Horms,

> It sounds entirely likely that there is a race in there somewhere,
> though its probably going to be quite hard to find exactly why
> an entry is being hashed that is already hashed. I'll poke around

Where is it hashed? Isn't it dereferenced and removed from the cp?

> myself, but if anyone else wants to do likewise, please do.

I had a quick glance but wasn't enlightened. It's strange because I 
happen to use the exact same kernel on the exact same box for one of our 
customers as well. It does not trigger for me.

> In the mean time, a non-SMP kernel would be an excellent way to go.

For sure ;).

> Firstly, it may well eliminate the problem, or conversely show us that
> its not an SMP locking issue.

I wonder what he's testing right now? :). I might be interested in 
getting a report with frame pointers enabled. My first thought was a 
locking issue related to software interrupts. The list write locking is 
not IRQ safe, so I wondered if something along the lines of the 
following helped? (granted, the window of opportunity is small):

index 015c819..e4ad8f8 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -62,6 +62,9 @@ static atomic_t ip_vs_conn_no_cport_cnt
  /* random value for IPVS connection hash */
  static unsigned int ip_vs_conn_rnd;

+/* Save softIRQ flags */
+static unsigned long flags;
+
  /*
   *  Fine locking granularity for big connection hash table
   */
@@ -98,6 +101,16 @@ static inline void ct_write_unlock(unsig
         write_unlock(&__ip_vs_conntbl_lock_array[key&CT_LOCKARRAY_MASK].l);
  }

+static inline void ct_write_lock_irq(unsigned key)
+{
+ 
write_lock_irqsave(&__ip_vs_conntbl_lock_array[key&CT_LOCKARRAY_MASK].l, 
flags);
+}
+
+static inline void ct_write_unlock_irq(unsigned key)
+{
+ 
write_unlock_irqrestore(&__ip_vs_conntbl_lock_array[key&CT_LOCKARRAY_MASK].l, 
flags);
+}
+
  static inline void ct_read_lock_bh(unsigned key)
  {
         read_lock_bh(&__ip_vs_conntbl_lock_array[key&CT_LOCKARRAY_MASK].l);
@@ -142,7 +155,7 @@ static int ip_vs_conn_hash(struct ip_vs_
         /* Hash by protocol, client address and port */
         hash = ip_vs_conn_hashkey(cp->protocol, cp->caddr, cp->cport);

-       ct_write_lock(hash);
+       ct_write_lock_irq(hash);

         if (!(cp->flags & IP_VS_CONN_F_HASHED)) {
                 list_add(&cp->c_list, &ip_vs_conn_tab[hash]);
@@ -155,7 +168,7 @@ static int ip_vs_conn_hash(struct ip_vs_
                 ret = 0;
         }

-       ct_write_unlock(hash);
+       ct_write_unlock_irq(hash);

         return ret;
  }
@@ -172,7 +185,7 @@ static int ip_vs_conn_unhash(struct ip_v

         /* unhash it and decrease its reference counter */
         hash = ip_vs_conn_hashkey(cp->protocol, cp->caddr, cp->cport);
-       ct_write_lock(hash);
+       ct_write_lock_irq(hash);

         if (cp->flags & IP_VS_CONN_F_HASHED) {
                 list_del(&cp->c_list);
@@ -182,7 +195,7 @@ static int ip_vs_conn_unhash(struct ip_v
         } else
                 ret = 0;

-       ct_write_unlock(hash);
+       ct_write_unlock_irq(hash);

         return ret;
  }

> And secondly, if your box is primarly an
> Linux Directory, it will probably perform slightly better with non-SMP
> than SMP.

Cheers mate,
Roberto Nibali, ratz
-- 
echo 
'[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq' | dc

Search lvs-users Archives
Limit search to: Subject & Body Subject Author
Sort by: Reverse Sort

More information about the lvs-users mailing list