Details

    • Type: Bug Bug
    • Status: In Progress
    • Severity: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Target Release Version/s: None
    • Component/s: dahdi (the module)
    • Labels:
      None
    • Mantis ID:
      13205
    • Regression:
      No

      Description

      Current dahdi master handling work in the following way:
      The first SPAN become a master
      If a new registered !!! SPAN is preferred , it is the new master
      If a span is unregistered - the new master is the first available span
      If master SPAN is in alarm state - the new master is the first non in alarm state SPAN

      So
      1. dahdi-dummy once loaded will be the master forever.
      2. even not-running SPAN can be a master
      3. master implementation is ugly...

                • ADDITIONAL INFORMATION ******

      Implemented: correct(symmetric) master arbitrage

      1. trying preffered master SPAN
      2. trying non-zero channel SPANS
      3. trying zero-channel SPANS (ztdummy,...)

      thus:
      1. dahdi-dynamic CAN be (and it works perfect) a master
      2. at any time, we can tell/expect - who is the master
      3. If (and only if) we have no master - dahdi-dummy will be our master

      1. ztdummy.c.patch
        0.4 kB
        Pavel Selivanov
      2. zaptel-base.c.patch
        4 kB
        Pavel Selivanov
      3. dahdi-base.c.patch
        3 kB
        Pavel Selivanov
      4. dahdi-base.c.patch
        3 kB
        Pavel Selivanov
      5. dahdi-base.c_syncprio.patch
        4 kB
        Michael Haigh
      6. dahdi_dynamic.c_syncprio.patch
        1 kB
        Michael Haigh
      7. dahdi_dummy.c.patch
        0.5 kB
        Pavel Selivanov
      8. dahdi_dummy.c_syncprio.patch
        0.5 kB
        Michael Haigh
      9. 2013.01.17-dahdi-base.c.patch
        3 kB
        Pavel Selivanov
      10. 0001-dahdi-wip-Fix-dynamic_loc-span-operation-with-DAHDI-.patch
        3 kB
        Shaun Ruffell
      No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

        Hide
        Pavel Selivanov added a comment -

        There are still some troubles with locating true MASTER in DAHDI 2.6.1.
        1. ::master not initialized (::master = NULL).
        2. even span with alarm can become a master, if old_master == NULL.
        3. Nobody call __dahdi_find_master_span in _dahdi_unassign_span.
        _dahdi_unassign_span have own find_master loop. What for ?
        4. dynamic spans still can not become a master span.
        WHY ?
        5. dummy span can not become a master span (it's good to have a backup span with good 1ms ticks, provided by HPET).
        WHY ?

        Provided patches can be used to fix this annoing bugs.
        It's done to have logic, compatible with current DAHDI logic (it will not break current installations).
        To make it clear, I've wrote a number of possible cases (possible installations).

        Terms:
        dummy - dummy SPAN. SPAN, provided by dahdi_dummy. Have 0 channels.
        card0.0 - fixed SPAN, card #0, port 0, span=...
        dynamic0 - dynamic SPAN, dynamic=...
        master - master SPAN.

        == case 0
        dummy
        card0.0 - clock source (sync from E1)
        card0.1 - backup clock source (sync from the same E1)
        dynamic0 - clock slave (sync from sync_tick, so, from E1)
        dynamic1 - clock slave (sync from sync_tick, so, from E1)

        • card0.0 = OK
          master = card0.0
        • card0.0 = RED
          master = card0.1
        • card0.0 = card0.1 = RED
          master = dummy (slave dynamic spans have cannot_provide_timing=1).

        == case 1
        card0.0 - clock source (sync from E1)
        card0.1 - backup clock source (sync from the same E1)
        dynamic.0 - clock slave (sync from sync_tick, so, from E1)
        dynamic.1 - clock slave (sync from sync_tick, so, from E1)

        • card0.0 = OK
          master = card0.0
        • card0.0 = RED
          master = card0.1
        • card0.0 = card0.1 = RED
          master = NULL (slave dynamic spans have cannot_provide_timing=1).
          _process_masterspan will be called by the timer 4 times every 4ms (true for x86. actually HZ/250)...

        == case 2
        dummy
        dynamic0 - clock source (sync from E1)
        dynamic1 - backup clock source (sync from the same E1)

        • dynamic0 = OK
          master = dynamic0 (master dynamic spans have cannot_provide_timing=0).
        • dynamic0 = RED
          master = dynamic1 (slave dynamic spans have cannot_provide_timing=1).
        • dynamic0 = dynamic1 = RED
          master = dummy

        == case 3
        dynamic0 - clock source (sync from E1)
        dynamic1 - backup clock source (sync from the same E1)

        • dynamic0 = OK
          master = dynamic0 (master dynamic spans have cannot_provide_timing=0).
        • dynamic0 = RED
          master = dynamic1 (slave dynamic spans have cannot_provide_timing=1).
        • dynamic0 = dynamic1 = RED
          master = NULL
          _process_masterspan will be called by the timer 4 times every 4ms (true for x86. actually HZ/250)...

        == case 4
        dummy
        dynamic0 - clock source (sync from E1)
        dynamic1 - clock slave (sync from dynamic master SPAN)

        • dynamic0 = OK
          master = dynamic0 (master dynamic spans have cannot_provide_timing=0).
        • dynamic0 = RED
          master = dummy (slave dynamic spans have cannot_provide_timing=1).

        == case 5
        dynamic0 - clock source (sync from E1)
        dynamic1 - clock slave (sync from dynamic master SPAN)

        • dynamic0 = OK
          master = dynamic0 (master dynamic spans have cannot_provide_timing=0).
        • dynamic0 = RED
          master = NULL (slave dynamic spans have cannot_provide_timing=1).
          _process_masterspan will be called by the timer 4 times every 4ms (true for x86. actually HZ/250)...

        = case 6
        dummy
        dynamic0 - clock slave (sync from DAHDI, via sync_tick)
        dynamic1 - clock slave (sync from DAHDI, via sync_tick)

        master = dummy

        = case 7
        dynamic0 - clock slave
        dynamic1 - clock slave

        master = NULL (slave dynamic spans have cannot_provide_timing=1).
        _process_masterspan will be called by the timer 4 times every 4ms (true for x86. actually HZ/250)...

        = case 8
        card0.0 - clock source (E1 slave)
        card1.0 - clock slave (card 1 should take sync tick from DAHDI, so, from card0).

        • card0.0 = OK
          master = card0.0
        • card0.0 = RED
          master = card1.0 (if card will not set cannot_provide_timing)
          master = NULL (if card will not set cannot_provide_timing).
          So, card1 driver must pass sync_tick(s, 1) to hardware, but ignore sync_tick(s, 0), to prevent self-tune itself.
        Show
        Pavel Selivanov added a comment - There are still some troubles with locating true MASTER in DAHDI 2.6.1. 1. ::master not initialized (::master = NULL). 2. even span with alarm can become a master, if old_master == NULL. 3. Nobody call __dahdi_find_master_span in _dahdi_unassign_span. _dahdi_unassign_span have own find_master loop. What for ? 4. dynamic spans still can not become a master span. WHY ? 5. dummy span can not become a master span (it's good to have a backup span with good 1ms ticks, provided by HPET). WHY ? Provided patches can be used to fix this annoing bugs. It's done to have logic, compatible with current DAHDI logic (it will not break current installations). To make it clear, I've wrote a number of possible cases (possible installations). Terms: dummy - dummy SPAN. SPAN, provided by dahdi_dummy. Have 0 channels. card0.0 - fixed SPAN, card #0, port 0, span=... dynamic0 - dynamic SPAN, dynamic=... master - master SPAN. == case 0 dummy card0.0 - clock source (sync from E1) card0.1 - backup clock source (sync from the same E1) dynamic0 - clock slave (sync from sync_tick, so, from E1) dynamic1 - clock slave (sync from sync_tick, so, from E1) card0.0 = OK master = card0.0 card0.0 = RED master = card0.1 card0.0 = card0.1 = RED master = dummy (slave dynamic spans have cannot_provide_timing=1). == case 1 card0.0 - clock source (sync from E1) card0.1 - backup clock source (sync from the same E1) dynamic.0 - clock slave (sync from sync_tick, so, from E1) dynamic.1 - clock slave (sync from sync_tick, so, from E1) card0.0 = OK master = card0.0 card0.0 = RED master = card0.1 card0.0 = card0.1 = RED master = NULL (slave dynamic spans have cannot_provide_timing=1). _process_masterspan will be called by the timer 4 times every 4ms (true for x86. actually HZ/250)... == case 2 dummy dynamic0 - clock source (sync from E1) dynamic1 - backup clock source (sync from the same E1) dynamic0 = OK master = dynamic0 (master dynamic spans have cannot_provide_timing=0). dynamic0 = RED master = dynamic1 (slave dynamic spans have cannot_provide_timing=1). dynamic0 = dynamic1 = RED master = dummy == case 3 dynamic0 - clock source (sync from E1) dynamic1 - backup clock source (sync from the same E1) dynamic0 = OK master = dynamic0 (master dynamic spans have cannot_provide_timing=0). dynamic0 = RED master = dynamic1 (slave dynamic spans have cannot_provide_timing=1). dynamic0 = dynamic1 = RED master = NULL _process_masterspan will be called by the timer 4 times every 4ms (true for x86. actually HZ/250)... == case 4 dummy dynamic0 - clock source (sync from E1) dynamic1 - clock slave (sync from dynamic master SPAN) dynamic0 = OK master = dynamic0 (master dynamic spans have cannot_provide_timing=0). dynamic0 = RED master = dummy (slave dynamic spans have cannot_provide_timing=1). == case 5 dynamic0 - clock source (sync from E1) dynamic1 - clock slave (sync from dynamic master SPAN) dynamic0 = OK master = dynamic0 (master dynamic spans have cannot_provide_timing=0). dynamic0 = RED master = NULL (slave dynamic spans have cannot_provide_timing=1). _process_masterspan will be called by the timer 4 times every 4ms (true for x86. actually HZ/250)... = case 6 dummy dynamic0 - clock slave (sync from DAHDI, via sync_tick) dynamic1 - clock slave (sync from DAHDI, via sync_tick) master = dummy = case 7 dynamic0 - clock slave dynamic1 - clock slave master = NULL (slave dynamic spans have cannot_provide_timing=1). _process_masterspan will be called by the timer 4 times every 4ms (true for x86. actually HZ/250)... = case 8 card0.0 - clock source (E1 slave) card1.0 - clock slave (card 1 should take sync tick from DAHDI, so, from card0). card0.0 = OK master = card0.0 card0.0 = RED master = card1.0 (if card will not set cannot_provide_timing) master = NULL (if card will not set cannot_provide_timing). So, card1 driver must pass sync_tick(s, 1) to hardware, but ignore sync_tick(s, 0), to prevent self-tune itself.
        Hide
        Pavel Selivanov added a comment -

        Patch file provided https://issues.asterisk.org/jira/secure/attachment/45926/dahdi-base.c.patch .
        Please, let me know if have any questions.

        Show
        Pavel Selivanov added a comment - Patch file provided https://issues.asterisk.org/jira/secure/attachment/45926/dahdi-base.c.patch . Please, let me know if have any questions.
        Hide
        Pavel Selivanov added a comment -

        patch over current git trunk.
        2013.01.17-dahdi-base.c.patch

        Show
        Pavel Selivanov added a comment - patch over current git trunk. 2013.01.17-dahdi-base.c.patch
        Hide
        Shaun Ruffell added a comment -

        There are still some troubles with locating true MASTER in DAHDI 2.6.1.
        1. ::master not initialized (::master = NULL).

        This is not a problem because it's declared static. Static global variables are by definition initialized to 0 or NULL.

        2. even span with alarm can become a master, if old_master == NULL.

        This is again not a problem with core timer. If there is only one span, we want that span to become the "master". If the span in alarm is not providing timing, the coretimer will kick in and tick the spans.

        3. Nobody call __dahdi_find_master_span in _dahdi_unassign_span.
        _dahdi_unassign_span have own find_master loop. What for ?

        I agree with you here. It would be better to have unassign span call something like __dahdi_find_master_span. Would need some tweaking though because it probably is the way it is to eliminate the window where master would unnecessarily be NULL when the master is unassigned. So probably need to change __dahdi_find_master_span() to require chan_lock to be held when call and not take that lock internally.

        4. dynamic spans still can not become a master span.
        WHY ?

        Why do you say that? dynamic local spans are the only one that cannot be the master span, since those are the only spans that set cannot_provide_timing in struct dahdi_span. Local spans cannot become the master since they have no way to "tick" on their own unlike all other spans. Granted, I've not set this up in awhile but I'm surprised that you say this.

        5. dummy span can not become a master span (it's good to have a backup span with good 1ms ticks, provided by HPET).
        WHY ?

        Because the dummy_span is a concept that is expired. If dynamic_eth spans need a 1ms timer running, it should set one up itself instead of relying on the sync_tick from the core_timer. For the vast majority of DAHDI users, they don't need a 1ms tick to mix audio that typically comes in 20ms chunks. It just adds unnecessary overhead.

        Show
        Shaun Ruffell added a comment - There are still some troubles with locating true MASTER in DAHDI 2.6.1. 1. ::master not initialized (::master = NULL). This is not a problem because it's declared static. Static global variables are by definition initialized to 0 or NULL. 2. even span with alarm can become a master, if old_master == NULL. This is again not a problem with core timer. If there is only one span, we want that span to become the "master". If the span in alarm is not providing timing, the coretimer will kick in and tick the spans. 3. Nobody call __dahdi_find_master_span in _dahdi_unassign_span. _dahdi_unassign_span have own find_master loop. What for ? I agree with you here. It would be better to have unassign span call something like __dahdi_find_master_span. Would need some tweaking though because it probably is the way it is to eliminate the window where master would unnecessarily be NULL when the master is unassigned. So probably need to change __dahdi_find_master_span() to require chan_lock to be held when call and not take that lock internally. 4. dynamic spans still can not become a master span. WHY ? Why do you say that? dynamic local spans are the only one that cannot be the master span, since those are the only spans that set cannot_provide_timing in struct dahdi_span. Local spans cannot become the master since they have no way to "tick" on their own unlike all other spans. Granted, I've not set this up in awhile but I'm surprised that you say this. 5. dummy span can not become a master span (it's good to have a backup span with good 1ms ticks, provided by HPET). WHY ? Because the dummy_span is a concept that is expired. If dynamic_eth spans need a 1ms timer running, it should set one up itself instead of relying on the sync_tick from the core_timer. For the vast majority of DAHDI users, they don't need a 1ms tick to mix audio that typically comes in 20ms chunks. It just adds unnecessary overhead.
        Hide
        Pavel Selivanov added a comment -

        This is not a problem because it's declared static. Static global variables are by definition initialized to 0 or NULL.

        Yep, sorry.

        This is again not a problem with core timer. If there is only one span, we want that span to become the "master". If the span in alarm is not providing timing, the coretimer will kick in and tick the spans.

        Yes, DAHDI will roll using core timer ticks. But it will not be reflected in procfs.
        cat /proc/dahdi/1 will display "(MASTER)", what is not truth.

        Why do you say that? dynamic local spans are the only one that cannot be the master span, since those are the only spans that set cannot_provide_timing in struct dahdi_span. Local spans cannot become the master since they have no way to "tick" on their own unlike all other spans. Granted, I've not set this up in awhile but I'm surprised that you say this.

        dynamic will fail test_bit(DAHDI_FLAGBIT_RUNNING, &s->flags), as nobody set this flag !
        It's fixed in patch for dynamic, probably I should write it there...
        https://issues.asterisk.org/jira/browse/DAHLIN-26 .

        Because the dummy_span is a concept that is expired. If dynamic_eth spans need a 1ms timer running, it should set one up itself instead of relying on the sync_tick from the core_timer. For the vast majority of DAHDI users, they don't need a 1ms tick to mix audio that typically comes in 20ms chunks. It just adds unnecessary overhead.

        It theory - I would agree, but in practice some bad use-cases:

        1. "static" span - from PSTN. dynamic span - to local PBX. PSTN - sync source for DAHDI, local PBX.
        span=1,1,0,cas,hdb3,crc4
        dynamic=eth,eth0/00:02:b3:35:43:9c,30,0
        If span is in alarm - dynamic will be ticked by core_timer.
        core timer will do 1000/HZ ticks (4 in my case) every HZ/1000 ms.
        On first tick, dynamic will run tasklet.
        ticks 2-4 will be lost, as tasklet will not even start.
        It will be rejected with "if (likely(!taskletpending))"

        2. "dynamic" span 1 - from PSTN. "dynamic" span 2- to local PBX. PSTN - sync source for DAHDI, local PBX.
        dynamic=eth,eth0/00:02:b3:35:43:9c,30,1
        dynamic=eth,eth0/00:02:b3:35:43:9d,30,0
        If dynamic 1 will lost link (RED alarm), will burn - dynamic 2 will be ticked by core_timer.

        So, it's good to have a backup sync source.
        Moreover, patched __dahdi_find_master_span even more compact, than the original one (nobody loose nothing).

        It's also possible to rework tasklet in dynamic (to run tasklet untill taskletsched != taskletrun, but deadlock protection).

        Thank you for a dialog, I appreciate it.

        Show
        Pavel Selivanov added a comment - This is not a problem because it's declared static. Static global variables are by definition initialized to 0 or NULL. Yep, sorry. This is again not a problem with core timer. If there is only one span, we want that span to become the "master". If the span in alarm is not providing timing, the coretimer will kick in and tick the spans. Yes, DAHDI will roll using core timer ticks. But it will not be reflected in procfs. cat /proc/dahdi/1 will display "(MASTER)", what is not truth. Why do you say that? dynamic local spans are the only one that cannot be the master span, since those are the only spans that set cannot_provide_timing in struct dahdi_span. Local spans cannot become the master since they have no way to "tick" on their own unlike all other spans. Granted, I've not set this up in awhile but I'm surprised that you say this. dynamic will fail test_bit(DAHDI_FLAGBIT_RUNNING, &s->flags), as nobody set this flag ! It's fixed in patch for dynamic, probably I should write it there... https://issues.asterisk.org/jira/browse/DAHLIN-26 . Because the dummy_span is a concept that is expired. If dynamic_eth spans need a 1ms timer running, it should set one up itself instead of relying on the sync_tick from the core_timer. For the vast majority of DAHDI users, they don't need a 1ms tick to mix audio that typically comes in 20ms chunks. It just adds unnecessary overhead. It theory - I would agree, but in practice some bad use-cases: 1. "static" span - from PSTN. dynamic span - to local PBX. PSTN - sync source for DAHDI, local PBX. span=1,1,0,cas,hdb3,crc4 dynamic=eth,eth0/00:02:b3:35:43:9c,30,0 If span is in alarm - dynamic will be ticked by core_timer. core timer will do 1000/HZ ticks (4 in my case) every HZ/1000 ms. On first tick, dynamic will run tasklet. ticks 2-4 will be lost, as tasklet will not even start. It will be rejected with "if (likely(!taskletpending))" 2. "dynamic" span 1 - from PSTN. "dynamic" span 2- to local PBX. PSTN - sync source for DAHDI, local PBX. dynamic=eth,eth0/00:02:b3:35:43:9c,30,1 dynamic=eth,eth0/00:02:b3:35:43:9d,30,0 If dynamic 1 will lost link (RED alarm), will burn - dynamic 2 will be ticked by core_timer. So, it's good to have a backup sync source. Moreover, patched __dahdi_find_master_span even more compact, than the original one (nobody loose nothing). It's also possible to rework tasklet in dynamic (to run tasklet untill taskletsched != taskletrun, but deadlock protection). Thank you for a dialog, I appreciate it.

          People

          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:

              Development