Search Linux Wireless

Re: [PATCH] ath6kl: Add rx workqueue for SDIO

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

 



Raja Mani <rmani@xxxxxxxxxxxxxxxx> writes:

> In the current implementation, all RX packets (data and control)
> are fetched from the chip and processed in ISR handler context.
> ISR handler has to process fetched packets first before it goes
> ahead and fetch further packets from the chip. In high throughput
> scenario, doing everything (read and process) in one context is
> time consuming and it's not quicker way of reading RX packets from
> the chip.
>
> This patch lets ISR to read packets (data and control) from the chip
> and process control packets alone (EP0 pkts). All data packets are
> moved to another queue which is separately processed by another worker
> thread. So that, ISR doesn't have to wait to read further packets until
> fetched data packets are processed. With this change, significant
> improvement is seen both in TCP (around 10 Mpbs) and UDP (around 5 Mpbs)
> down-link case.
>
> Signed-off-by: Pandiyarajan Pitchaimuthu <c_ppitch@xxxxxxxxxxxxxxxx>
> Signed-off-by: Raja Mani <rmani@xxxxxxxxxxxxxxxx>

Sorry, I think I missed this in our internal review:

> +static void ath6kl_htc_rx_work(struct work_struct *work)
> +{
> +	struct htc_target *target;
> +	struct htc_packet *packet, *tmp_pkt;
> +	struct htc_endpoint *endpoint;
> +
> +	target = container_of(work, struct htc_target, rx_work);
> +
> +	spin_lock_bh(&target->rx_comp_lock);
> +	list_for_each_entry_safe(packet, tmp_pkt, &target->rx_bufq, list) {
> +		list_del(&packet->list);
> +
> +		spin_unlock_bh(&target->rx_comp_lock);
> +		endpoint = &target->endpoint[packet->endpoint];
> +
> +		ath6kl_dbg(ATH6KL_DBG_HTC,
> +			   "htc rx complete ep %d packet 0x%p\n",
> +			   endpoint->eid, packet);
> +
> +		endpoint->ep_cb.rx(endpoint->target, packet);
> +		spin_lock_bh(&target->rx_comp_lock);
> +	}
> +	spin_unlock_bh(&target->rx_comp_lock);

I think there's a (theoretical?) race here. You cannot consume rx_bufq
with a for loop and then release rx_comp_lock inside the loop. Nothing
prevents that rx_bufq is not modified while the lock is released. Ok, in
practise it won't be a problem as ISR is adding them to the end of list.

I think to fix the race the queue should be consumed something like
this (pseudo code):

lock()
while (!list_empty()) {
      entry = list_first_entry()
      unlock()

      do_stuff()

      lock()
}

Can someone else comment? Am I on right track?

I so wish sdio.c and htc would use struct sk_buff. It would have all the
infrastructure for this :/

BTW, for consistency please also rename rx_comp_lock to rx_bufq_lock.


-- 
Kalle Valo
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

  Powered by Linux