Search Linux Wireless

Re: [PATCH v12 3/4] mac80211: MBSSID and EMA support in beacon handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

So I applied patches 1 and 2, but have some comments/questions here.

>  static struct sk_buff *
>  __ieee80211_beacon_get(struct ieee80211_hw *hw,
>  		       struct ieee80211_vif *vif,
>  		       struct ieee80211_mutable_offsets *offs,
> -		       bool is_template)
> +		       bool is_template,
> +		       int ema_index)
>  {
>  	struct ieee80211_local *local = hw_to_local(hw);
>  	struct beacon_data *beacon = NULL;
> @@ -4995,13 +5038,11 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
>  	struct ieee80211_chanctx_conf *chanctx_conf;
>  	int csa_off_base = 0;
>  
> 
> 
> 
> -	rcu_read_lock();

Why are you making this change that moves the RCU locking out? In two
out of three places, you now have to

	rcu_read_lock();
	__ieee80211_beacon_get(...);
	rcu_read_unlock();

Not sure I see the point?
> 
>  	if (!ieee80211_sdata_running(sdata) || !chanctx_conf)
> -		goto out;
> +		return NULL;

That also causes a lot of collateral changes that make it harder to read
than it needs to be.

Maybe split the locking change to a separate patch, if at all necessary?

(but see below)


> +	rcu_read_lock();
> ...
> +		ema = kmalloc(sizeof(*ema), GFP_KERNEL);

This is obviously wrong - you should add a few more debug options to
your test kernels :-)


> +		if (!ema) {
> +			ieee80211_beacon_free_ema_list(head);
> +			cnt = 0;
> +			goto out;

break would be enough, and you could save the 'out' label?

> +		}
> +
> +		ema->skb = __ieee80211_beacon_get(hw, vif, &ema->offs, true,
> +						  cnt);
> +		if (!ema->skb) {
> +			kfree(ema);
> +			break;
> +		}
> +		list_add_tail(&ema->list, head);
> +		cnt++;
> +	}
> +out:
> +	rcu_read_unlock();


This is also the only place that uses the rcu_read_lock()/unlock() not
directly around the __ieee80211_beacon_get(), but there's absolutely no
point in that?

I think what you intended here was correct, but it was done incorrectly.

Really what it seems you (should have) _wanted_ with the RCU locking
here is that the

	beacon = rcu_dereference(ap->beacon);

is only done *once*, so that you can really get a snapshot of *all*
those MBSSID beacons, even if ap->beacon changed.

However, that's not what you implemented. By moving the rcu_read_lock()
outside, you've achieved nothing, since you still do a dereference
inside, and it can change.

It seems to me that to do this correctly you have to actually split
__ieee80211_beacon_get() and do the dereference *outside* of it, then
pass the 'beacon' pointer into it. Then, you can here do the dereference
outside of the loop too (and in fact can do a much nicer for loop rather
than the infinite loop).

As it is, you've penalized the other cases (they now need to do the
rcu_read_lock() manually), but haven't actually gained anything
(functionally, at least, you save a few cycles by having the RCU stuff
outside the loop, but that doesn't really count).

johannes





[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux