On Mon, Feb 10, 2014 at 11:15 AM, Pravin Shelar <pshe...@nicira.com> wrote:
> On Thu, Feb 6, 2014 at 3:13 PM, Jarno Rajahalme <jrajaha...@nicira.com> wrote:
>> @@ -80,96 +76,126 @@ void ovs_flow_stats_update(struct sw_flow *flow, struct 
>> sk_buff *skb)
>>                 tcp_flags = TCP_FLAGS_BE16(tcp_hdr(skb));
>>         }
>>
>> -       spin_lock(&stats->lock);
>> +       /* Check if already have node-specific stats. */
>> +       if (likely(stats))
>> +               spin_lock(&stats->lock);
>> +       else {
>> +               stats = flow->stats[0]; /* Pre-allocated. */
>> +               spin_lock(&stats->lock);
>> +
>> +               /* If the current NUMA-node is the only writer on the
>> +                * pre-allocated stats keep using them.
>> +                * A previous locker may have already allocated the stats,
>> +                * so we need to check again.  If the node-specific stats
>> +                * were already allocated, we update the pre-allocated stats
>> +                * as we have already locked them. */
>> +               if (likely(stats->last_writer != node && stats->last_writer 
>> >= 0
>> +                          && !flow->stats[node])) {
>> +                       /* Try to allocate node-specific stats. */
>> +                       struct flow_stats *new_stats;
>> +
>> +                       new_stats = kmem_cache_alloc_node(flow_stats_cache,
>> +                                                         GFP_THISNODE |
>> +                                                         __GFP_NOMEMALLOC,
>> +                                                         node);
>> +                       if (likely(new_stats)) {
>> +                               new_stats->used = jiffies;
>> +                               new_stats->packet_count = 1;
>> +                               new_stats->byte_count = skb->len;
>> +                               new_stats->tcp_flags = tcp_flags;
>> +                               new_stats->last_writer = node;
>> +                               spin_lock_init(&new_stats->lock);
>> +
>> +                               flow->stats[node] = new_stats;
>> +                               goto unlock; /* Unlock the pre-allocated 
>> stats. */
>
> One more thing I noticed is that we need memory barrier for numa-stats
> array. Since other process could be reading starts from different cpu.

It would be good if we could use some higher level construct that
contains memory barriers (like a lock). Raw memory barriers are
notoriously difficult to reason about.
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to