sfc: Don't try to set filters with search depths we know won't work
authorBen Hutchings <bhutchings@solarflare.com>
Fri, 8 Oct 2010 17:36:10 +0000 (10:36 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 8 Oct 2010 17:36:10 +0000 (10:36 -0700)
The filter engine will time-out and ignore filters beyond
200-something hops.  We also need to avoid infinite loops in
efx_filter_search() when the table is full.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/sfc/filter.c

index abc884d..52cb608 100644 (file)
 #define FILTER_CTL_SRCH_FUDGE_WILD 3
 #define FILTER_CTL_SRCH_FUDGE_FULL 1
 
+/* Hard maximum hop limit.  Hardware will time-out beyond 200-something.
+ * We also need to avoid infinite loops in efx_filter_search() when the
+ * table is full.
+ */
+#define FILTER_CTL_SRCH_MAX 200
+
 struct efx_filter_table {
        u32             offset;         /* address of table relative to BAR */
        unsigned        size;           /* number of entries */
@@ -183,7 +189,8 @@ static int efx_filter_search(struct efx_filter_table *table,
        incr = efx_filter_increment(key);
 
        for (depth = 1, filter_idx = hash & (table->size - 1);
-            test_bit(filter_idx, table->used_bitmap);
+            depth <= FILTER_CTL_SRCH_MAX &&
+                    test_bit(filter_idx, table->used_bitmap);
             ++depth) {
                cmp = &table->spec[filter_idx];
                if (efx_filter_equal(spec, cmp))
@@ -192,6 +199,8 @@ static int efx_filter_search(struct efx_filter_table *table,
        }
        if (!for_insert)
                return -ENOENT;
+       if (depth > FILTER_CTL_SRCH_MAX)
+               return -EBUSY;
 found:
        *depth_required = depth;
        return filter_idx;