Page MenuHomeFreeBSD

use taskqueue_enqueue_fast when enqueue to taskqueue_fast
AbandonedPublic

Authored by howard0su_gmail.com on Jan 14 2016, 4:13 AM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Apr 11, 12:25 PM
Unknown Object (File)
Wed, Apr 10, 3:27 AM
Unknown Object (File)
Tue, Apr 9, 10:16 PM
Unknown Object (File)
Sun, Apr 7, 6:04 AM
Unknown Object (File)
Dec 31 2023, 11:50 PM
Unknown Object (File)
Dec 28 2023, 9:40 PM
Unknown Object (File)
Nov 11 2023, 7:22 AM
Unknown Object (File)
Nov 11 2023, 7:15 AM
Subscribers

Details

Reviewers
jfv
jhb
erj
gnn
sbruno
Group Reviewers
Intel Networking

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

howard0su_gmail.com retitled this revision from to use taskqueue_enqueue_fast when enqueue to taskqueue_fast.
howard0su_gmail.com updated this object.
howard0su_gmail.com edited the test plan for this revision. (Show Details)
howard0su_gmail.com added a reviewer: erj.
howard0su_gmail.com set the repository for this revision to rS FreeBSD src repository - subversion.

From the manpage:

The function taskqueue_enqueue_fast() should be used in place of
taskqueue_enqueue() when the enqueuing must happen from a fast interrupt
handler.  This method uses spin locks to avoid the possibility of
sleeping in the fast interrupt context.

I'm unsure if this is needed as interrupts are disabled about 3 lines above via em_disable_intr().

In addition, if this is needed then the que_task should be done via taskqueue_enqueue_fast() as well.

em_disable_intr(adapter);
taskqueue_enqueue(adapter->tq, &adapter->que_task);

/* Link status change */
if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
        adapter->hw.mac.get_link_status = 1;
        taskqueue_enqueue(taskqueue_fast, &adapter->link_task);
}

From the manpage:

The function taskqueue_enqueue_fast() should be used in place of
taskqueue_enqueue() when the enqueuing must happen from a fast interrupt
handler.  This method uses spin locks to avoid the possibility of
sleeping in the fast interrupt context.

I'm unsure if this is needed as interrupts are disabled about 3 lines above via em_disable_intr().

I think we need since there can be other consumer of this global queue.

In addition, if this is needed then the que_task should be done via taskqueue_enqueue_fast() as well.

This is different since adapter->tq is not a global queue.

em_disable_intr(adapter);
taskqueue_enqueue(adapter->tq, &adapter->que_task);

/* Link status change */
if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
        adapter->hw.mac.get_link_status = 1;
        taskqueue_enqueue(taskqueue_fast, &adapter->link_task);
}

This is what I read from man page:

To	use these queues, call taskqueue_enqueue() with	the value of the
global taskqueue variable for the queue you wish to use (taskqueue_swi,
taskqueue_swi_giant, or taskqueue_thread).	 Use taskqueue_enqueue_fast()
for the global taskqueue variable taskqueue_fast.

Going by the man page, yeah, it looks like you should use taskqueue_enqueue_fast() instead of taskqueue_enqueue() if you're using the global taskqueue_fast.

Does this change fix any problems that you've noticed, or is this more of a correctness fix?

In D4930#108388, @erj wrote:

Going by the man page, yeah, it looks like you should use taskqueue_enqueue_fast() instead of taskqueue_enqueue() if you're using the global taskqueue_fast.

Does this change fix any problems that you've noticed, or is this more of a correctness fix?

I noticed this when I was using cscope to read taskqueue related code. I don't even have a machine with e1000 network card. So this is purely correctness fix.

John: Is there any reason to *not* do this?

taskqueue_enqueue_fast() isn't needed anymore, and the manpage probably needs to be updated. See the implementation of taskqueue_enqueue_fast():

/* NB: for backwards compatibility */
int
taskqueue_enqueue_fast(struct taskqueue *queue, struct task *task)
{
        return taskqueue_enqueue(queue, task);
}

This was reworked back in 7.0-CURRENT:

https://svnweb.freebsd.org/base/head/sys/kern/subr_taskqueue.c?revision=154167&view=markup

At this point taskqueue_enqueue_fast() should just be removed entirely (and removed from the manpage).

In D4930#109015, @jhb wrote:

taskqueue_enqueue_fast() isn't needed anymore, and the manpage probably needs to be updated. See the implementation of taskqueue_enqueue_fast():

/* NB: for backwards compatibility */
int
taskqueue_enqueue_fast(struct taskqueue *queue, struct task *task)
{
        return taskqueue_enqueue(queue, task);
}

This was reworked back in 7.0-CURRENT:

https://svnweb.freebsd.org/base/head/sys/kern/subr_taskqueue.c?revision=154167&view=markup

At this point taskqueue_enqueue_fast() should just be removed entirely (and removed from the manpage).

Does that break KPI? I can propose the changes.

I am wrong. the fix doesn't make sense.