22 Aug, 2008

1 commit

  • Since some qdiscs call qdisc_tree_decrease_qlen() (so qdisc_lookup())
    without rtnl_lock(), adding and deleting from a qdisc list needs
    additional locking. This patch adds global spinlock qdisc_list_lock
    and wrapper functions for modifying the list. It is considered as a
    temporary solution until hfsc_dequeue(), netem_dequeue() and
    tbf_dequeue() (or qdisc_tree_decrease_qlen()) are redone.

    With feedback from Herbert Xu and David S. Miller.

    Signed-off-by: Jarek Poplawski
    Acked-by: Herbert Xu
    Signed-off-by: David S. Miller

    Jarek Poplawski
     

21 Aug, 2008

1 commit

  • dev_deactivate() can skip rescheduling of a qdisc by qdisc_watchdog()
    or other timer calling netif_schedule() after dev_queue_deactivate().
    We prevent this checking aliveness before scheduling the timer. Since
    during deactivation the root qdisc is available only as qdisc_sleeping
    additional accessor qdisc_root_sleeping() is created.

    With feedback from Herbert Xu

    Signed-off-by: Jarek Poplawski
    Signed-off-by: David S. Miller

    Jarek Poplawski
     

19 Aug, 2008

5 commits


18 Aug, 2008

1 commit


12 Aug, 2008

1 commit


09 Aug, 2008

1 commit


08 Aug, 2008

1 commit


07 Aug, 2008

1 commit


30 Jul, 2008

1 commit

  • Bug report from Steven Jan Springl:

    Issuing the following command causes a kernel oops:
    tc qdisc add dev eth0 handle ffff: ingress

    The problem mostly stems from all of the special case handling of
    ingress qdiscs.

    So, to fix this, do the grafting operation the same way we do for TX
    qdiscs. Which means that dev_activate() and dev_deactivate() now do
    the "qdisc_sleeping qdisc" transitions on dev->rx_queue too.

    Future simplifications are possible now, mainly because it is
    impossible for dev_queue->{qdisc,qdisc_sleeping} to be NULL. There
    are NULL checks all over to handle the ingress qdisc special case
    that used to exist before this commit.

    Signed-off-by: David S. Miller

    David S. Miller
     

23 Jul, 2008

1 commit


20 Jul, 2008

1 commit


19 Jul, 2008

1 commit

  • Idea is from Patrick McHardy.

    Instead of managing the list of qdiscs on the device level, manage it
    in the root qdisc of a netdev_queue. This solves all kinds of
    visibility issues during qdisc destruction.

    The way to iterate over all qdiscs of a netdev_queue is to visit
    the netdev_queue->qdisc, and then traverse it's list.

    The only special case is to ignore builting qdiscs at the root when
    dumping or doing a qdisc_lookup(). That was not needed previously
    because builtin qdiscs were not added to the device's qdisc_list.

    Signed-off-by: David S. Miller

    David S. Miller
     

18 Jul, 2008

6 commits

  • Move the destruction of the old queue into qdisc_graft().

    When operating on a root qdisc (ie. "parent == NULL"), apply
    the operation to all queues. The caller has grabbed a single
    implicit reference for this graft, therefore when we apply the
    change to more than one queue we must grab additional qdisc
    references.

    Otherwise, we are operating on a class of a specific parent qdisc, and
    therefore no multiqueue handling is necessary.

    Signed-off-by: David S. Miller

    David S. Miller
     
  • Lock the root of the qdisc being operated upon.

    All explicit references to qdisc_tree_lock() are now gone.
    The only remaining uses are via the sch_tree_{lock,unlock}()
    and tcf_tree_{lock,unlock}() macros.

    Signed-off-by: David S. Miller

    David S. Miller
     
  • And give it it's own lock.

    Signed-off-by: David S. Miller

    David S. Miller
     
  • When we have shared qdiscs, packets come out of the qdiscs
    for multiple transmit queues.

    Therefore it doesn't make any sense to schedule the transmit
    queue when logically we cannot know ahead of time the TX
    queue of the SKB that the qdisc->dequeue() will give us.

    Just for sanity I added a BUG check to make sure we never
    get into a state where the noop_qdisc is scheduled.

    Signed-off-by: David S. Miller

    David S. Miller
     
  • When code wants to lock the qdisc tree state, the logic
    operation it's doing is locking the top-level qdisc that
    sits of the root of the netdev_queue.

    Add qdisc_root_lock() to represent this and convert the
    easiest cases.

    In order for this to work out in all cases, we have to
    hook up the noop_qdisc to a dummy netdev_queue.

    Signed-off-by: David S. Miller

    David S. Miller
     
  • alloc_netdev_mq() now allocates an array of netdev_queue
    structures for TX, based upon the queue_count argument.

    Furthermore, all accesses to the TX queues are now vectored
    through the netdev_get_tx_queue() and netdev_for_each_tx_queue()
    interfaces. This makes it easy to grep the tree for all
    things that want to get to a TX queue of a net device.

    Problem spots which are not really multiqueue aware yet, and
    only work with one queue, can easily be spotted by grepping
    for all netdev_get_tx_queue() calls that pass in a zero index.

    Signed-off-by: David S. Miller

    David S. Miller
     

09 Jul, 2008

9 commits


06 Jul, 2008

1 commit

  • Currently all qdiscs which allow to create classes uses a fixed sized hash
    table with size 16 to hash the classes. This causes a large bottleneck
    when using thousands of classes and unbound filters.

    Add helpers for dynamically sized class hashes to fix this. The following
    patches will convert the qdiscs to use them.

    Signed-off-by: Patrick McHardy
    Signed-off-by: David S. Miller

    Patrick McHardy
     

02 Jul, 2008

1 commit


18 Apr, 2008

1 commit


15 Apr, 2008

1 commit

  • TC_H_MAJ(parentid) for root classes is the same as for ingress, and if
    ingress qdisc is created qdisc_lookup() returns its pointer (without
    ingress NULL is returned). After this all qdisc_lookups give the same,
    and we get endless loop. (I don't know how this could hide for so long
    - it should trigger with every leaf class deleted if it's qdisc isn't
    empty.)

    After this fix qdisc_lookup() is omitted both for ingress and root
    parents, but looking for root is only wasting a little time here...
    Many thanks to Enrico Demarin for finding a test for catching this
    bug, which probably bothered quite a lot of admins.

    Reported-by: Enrico Demarin ,
    Signed-off-by: Jarek Poplawski
    Acked-by: Patrick McHardy
    Signed-off-by: David S. Miller

    Jarek Poplawski
     

26 Mar, 2008

1 commit


29 Jan, 2008

4 commits