]> rtime.felk.cvut.cz Git - zynq/linux.git/blobdiff - net/core/gen_stats.c
Apply preempt_rt patch-4.9-rt1.patch.xz
[zynq/linux.git] / net / core / gen_stats.c
index be873e4e312572516a2ab47cdac6053efd3459af..bc3b17b78c94cfe8a50f9db6a9d6e0a355930635 100644 (file)
@@ -32,10 +32,11 @@ gnet_stats_copy(struct gnet_dump *d, int type, void *buf, int size, int padattr)
        return 0;
 
 nla_put_failure:
+       if (d->lock)
+               spin_unlock_bh(d->lock);
        kfree(d->xstats);
        d->xstats = NULL;
        d->xstats_len = 0;
-       spin_unlock_bh(d->lock);
        return -1;
 }
 
@@ -66,15 +67,16 @@ gnet_stats_start_copy_compat(struct sk_buff *skb, int type, int tc_stats_type,
 {
        memset(d, 0, sizeof(*d));
 
-       spin_lock_bh(lock);
-       d->lock = lock;
        if (type)
                d->tail = (struct nlattr *)skb_tail_pointer(skb);
        d->skb = skb;
        d->compat_tc_stats = tc_stats_type;
        d->compat_xstats = xstats_type;
        d->padattr = padattr;
-
+       if (lock) {
+               d->lock = lock;
+               spin_lock_bh(lock);
+       }
        if (d->tail)
                return gnet_stats_copy(d, type, NULL, 0, padattr);
 
@@ -128,21 +130,29 @@ __gnet_stats_copy_basic_cpu(struct gnet_stats_basic_packed *bstats,
 }
 
 void
-__gnet_stats_copy_basic(struct gnet_stats_basic_packed *bstats,
+__gnet_stats_copy_basic(net_seqlock_t *running,
+                       struct gnet_stats_basic_packed *bstats,
                        struct gnet_stats_basic_cpu __percpu *cpu,
                        struct gnet_stats_basic_packed *b)
 {
+       unsigned int seq;
+
        if (cpu) {
                __gnet_stats_copy_basic_cpu(bstats, cpu);
-       } else {
+               return;
+       }
+       do {
+               if (running)
+                       seq = net_seq_begin(running);
                bstats->bytes = b->bytes;
                bstats->packets = b->packets;
-       }
+       } while (running && net_seq_retry(running, seq));
 }
 EXPORT_SYMBOL(__gnet_stats_copy_basic);
 
 /**
  * gnet_stats_copy_basic - copy basic statistics into statistic TLV
+ * @running: seqcount_t pointer
  * @d: dumping handle
  * @cpu: copy statistic per cpu
  * @b: basic statistics
@@ -154,13 +164,14 @@ EXPORT_SYMBOL(__gnet_stats_copy_basic);
  * if the room in the socket buffer was not sufficient.
  */
 int
-gnet_stats_copy_basic(struct gnet_dump *d,
+gnet_stats_copy_basic(net_seqlock_t *running,
+                     struct gnet_dump *d,
                      struct gnet_stats_basic_cpu __percpu *cpu,
                      struct gnet_stats_basic_packed *b)
 {
        struct gnet_stats_basic_packed bstats = {0};
 
-       __gnet_stats_copy_basic(&bstats, cpu, b);
+       __gnet_stats_copy_basic(running, &bstats, cpu, b);
 
        if (d->compat_tc_stats) {
                d->tc_stats.bytes = bstats.bytes;
@@ -330,8 +341,9 @@ gnet_stats_copy_app(struct gnet_dump *d, void *st, int len)
        return 0;
 
 err_out:
+       if (d->lock)
+               spin_unlock_bh(d->lock);
        d->xstats_len = 0;
-       spin_unlock_bh(d->lock);
        return -1;
 }
 EXPORT_SYMBOL(gnet_stats_copy_app);
@@ -365,10 +377,11 @@ gnet_stats_finish_copy(struct gnet_dump *d)
                        return -1;
        }
 
+       if (d->lock)
+               spin_unlock_bh(d->lock);
        kfree(d->xstats);
        d->xstats = NULL;
        d->xstats_len = 0;
-       spin_unlock_bh(d->lock);
        return 0;
 }
 EXPORT_SYMBOL(gnet_stats_finish_copy);