Search Linux Wireless

Re: [PATCHv4] wifi: mac80211: Mesh Fast xmit support

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

 



Hi,

Couple of small things, sorry I didn't see that before.
 
> +/**
> + * struct mesh_hdr_cache

need a short description, e.g.

struct mesh_hdr_cache - mesh header cache entry

> + *
> + * @enabled: Flag to denote if Header caching is enabled.
> + * @rhead: the rhashtable containing struct mesh_cache_entry, keyed by addr_key which
> + *	For a 6addr format which is currently supported in the cache, the key
> + *	is the external destination address or a5

I don't understand this - should the "which" (on the too long line) be
removed? Can you please rewrite this?

> + * @walk_head: linked list containing all mesh_cache_entry objects

Also both here refer to mesh_cache_entry which doesn't exist anywhere?
Did you mean 'struct mhdr_cache_entry'?

> + * @walk_lock: lock protecting walk_head
> + * @size: number of entries in the cache
> + */
> +struct mesh_hdr_cache {
> +	bool enabled;
> +	struct rhashtable rhead;
> +	struct hlist_head walk_head;
> +	spinlock_t walk_lock; /* protects cache entries */
> +	u16 size;

might be nicer to put 'bool enabled' last since otherwise you have a lot
of padding

> +struct mhdr_cache_entry {
> +	u8 addr_key[ETH_ALEN];

probably better to __aligned(2) even if of course this would matter only
if someone were to add some entries before it

> +	u8 hdr[MESH_HEADER_MAX_LEN];
> +	u16 machdr_len;
> +	u16 hdrlen;
> +	u8 pn_offs;
> +	u8 band;
> +	struct ieee80211_key __rcu *key;
> +	struct hlist_node walk_list;
> +	struct rhash_head rhash;
> +	struct mesh_path __rcu *mpath;
> +	struct mesh_path __rcu *mppath;
> +	unsigned long timestamp;
> +	struct rcu_head rcu;
> +	u32 path_change_count;
> +};
> +
>  /* Recent multicast cache */
>  /* RMC_BUCKETS must be a power of 2, maximum 256 */
>  #define RMC_BUCKETS		256
> @@ -299,6 +338,13 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
>  
>  bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
>  
> +struct mhdr_cache_entry *mesh_fill_cached_hdr(struct ieee80211_sub_if_data *sdata,
> +					      struct sk_buff *skb);

that's a fairly long line, you can break it better maybe:

struct mhdr_cache_entry *
mesh_fill_...

> +struct mhdr_cache_entry *mesh_fill_cached_hdr(struct ieee80211_sub_if_data *sdata,
> +					      struct sk_buff *skb)
> +{
> +	struct mesh_hdr_cache *cache;
> +	struct mhdr_cache_entry *entry;
> +	struct mesh_path *mpath, *mppath;
> +	struct ieee80211s_hdr *meshhdr;
> +	struct ieee80211_hdr *hdr;
> +	struct sta_info *new_nhop;
> +	struct ieee80211_key *key;
> +	struct ethhdr *eth;
> +	u8 sa[ETH_ALEN];
> +
> +	u8 tid;
> +
> +	cache = &sdata->u.mesh.hdr_cache;
> +
> +	if (!cache->enabled)
> +		return NULL;

If you check fast-xmit capability here, then I think you don't need the
'enabled' at all? The other use of it is to avoid double-release, but I
don't see how that would happen or be legal in the first place.

> +	if (!cache->enabled)
> +		return;
> 
> 

OK same here, but still?

Dunno. Maybe the extra byte is OK and cache locality is better that way
...

Though I've actually thought for a while now that we have so many
capability checks, we might benefit from making those static keys for
systems that only have a single wifi NIC (or multiple similar ones),
which is quite many I guess.

> +	if (key) {
> +		bool gen_iv, iv_spc;
> +
> +		gen_iv = key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV;
> +		iv_spc = key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE;
> +
> +		if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
> +			return;
> +
> +		if (key->flags & KEY_FLAG_TAINTED)
> +			return;
> +
> +		switch (key->conf.cipher) {
> +		case WLAN_CIPHER_SUITE_CCMP:
> +		case WLAN_CIPHER_SUITE_CCMP_256:
> +			if (gen_iv)
> +				pn_offs = hdrlen;
> +			if (gen_iv || iv_spc)
> +				crypto_len = IEEE80211_CCMP_HDR_LEN;
> +			break;
> +		default:
> +			/* Limiting supported ciphers for testing */

Nit: "limit"

But GCMP should be trivial, since it's the same? Feels strange to limit
to just CCMP.

> +			return;
> +		}
> +		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
> +	}
> +
> +	if ((hdrlen + crypto_len + mshhdr_len + sizeof(rfc1042_header)) >
> +		MESH_HEADER_MAX_LEN) {

strange line-break/indentation - maybe just indent the second line by
another tab or so to make it clear it's not part of the code.

> +	if (pn_offs) {
> +		/* ignore the invalid data getting copied to pn location since it will
> +		 * be overwritten during tx
> +		 */
> +		memcpy(mhdr->hdr, skb->data, mhdr->machdr_len);

Not sure I understand that comment?


> +
> +		/* copy remaining hdr */
> +		memcpy(mhdr->hdr + mhdr->machdr_len,
> +		       skb->data + mhdr->machdr_len - crypto_len,
> +		       mhdr->hdrlen - mhdr->machdr_len);
> +	} else {
> +		memcpy(mhdr->hdr, skb->data, mhdr->hdrlen);
> +	}
> +
> +	if (key) {
> +		hdr = (struct ieee80211_hdr *)mhdr->hdr;
> +		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
> +	}

Isn't "if (key)" equivalent to "if (pn_offs)" at this point, so you can
move it into the same if?

> @@ -2921,12 +2922,18 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
>  			mpp_path_add(sdata, proxied_addr, mpp_addr);
>  		} else {
>  			spin_lock_bh(&mppath->state_lock);
> -			if (!ether_addr_equal(mppath->mpp, mpp_addr))
> +			if (!ether_addr_equal(mppath->mpp, mpp_addr)) {
> +				update = true;
>  				memcpy(mppath->mpp, mpp_addr, ETH_ALEN);
> +			}
>  			mppath->exp_time = jiffies;
>  			spin_unlock_bh(&mppath->state_lock);
>  		}
>  		rcu_read_unlock();
> +
> +		/* Flush any hdr, if external device moved to a new gate */
> +		if (update)
> +			mesh_hdr_cache_flush(mppath, true);

This feels pretty expensive during RX, could/should it be done
asynchronously? Maybe it's not too bad since "is_mpp==true".

> +	/* availability of hdr entry ensures the mpath and sta are valid
> +	 * hence validation can be avoided.

What about key? :)

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