pppd & n_gsm problem

Hello

i’d like to ask to questions related to serial communication.

  1. Is there any reason why DMA is disabled by default in beagle bone black serial_omap driver (CONFIG_SERIAL_8250_DMA=n) ?
    Is it safe to recompile it with CONFIG_SERIAL_8250_DMA=y?

  2. I encountered board freeze (most probably deadlock but I’m not sure) when using pppd and n_gsm to communicate with GSM modem over serial line.
    When I connected to the board from internet and issued some command wich output a lot of data, board got stuck but when output little data
    board behaved correctly. After digging into n_gsm driver I discovered that board gets stuck when 8250 driver calls gsmld_write_wakeu() indicating upper layer (n_gsm)

that is has room again for new data. n_gsm in return sends more data to 8250 driver directly in the gsmld_write_wakeup() , which is called from interrupt. I thought this could be the source of the deadlog but I didn’t discover anything wrong. However the problem got treated when I instead of directly sending data in gsmld_write_wakeup() scheduled tasklet and only inside it I sent the data.

Any hint what could be wrong with the original code? The behaviour was the same both in 4.19.94-ti-r37 and 4.14.49-ti-r54.

Tank you for any help
regards
Pavel

Instead of

static void gsmld_write_wakeup(struct tty_struct *tty)
{
struct gsm_mux *gsm = tty->disc_data;
unsigned long flags;

/* Queue poll */
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
spin_lock_irqsave(&gsm->tx_lock, flags);
gsm_data_kick(gsm);
if (gsm->tx_bytes < TX_THRESH_LO) {
gsm_dlci_data_sweep(gsm);
}
spin_unlock_irqrestore(&gsm->tx_lock, flags);
}

this

static void gsmld_write_wakeup(struct tty_struct *tty)
{
struct gsm_mux *gsm = tty->disc_data;

/* Queue poll */
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
tasklet_schedule(&gsm->wkup_tasklet);
}

static void wkup_tasklet_handler(unsigned long data)
{
struct gsm_mux *gsm = (struct gsm_mux *)data;
unsigned long flags;

spin_lock_irqsave(&gsm->tx_lock, flags);
gsm_data_kick(gsm);
if (gsm->tx_bytes < TX_THRESH_LO) {
gsm_dlci_data_sweep(gsm);
}
spin_unlock_irqrestore(&gsm->tx_lock, flags);
}

this is call stack trace from omap driver up to n_gsm driver resulting in freez

[ 361.652243] [] (gsmld_write_wakeup [n_gsm]) from [] (tty_wakeup+0x60/0x6c)
[ 361.652255] [] (tty_wakeup) from [] (tty_port_default_wakeup+0x24/0x30)
[ 361.652266] [] (tty_port_default_wakeup) from [] (tty_port_tty_wakeup+0x20/0x24)
[ 361.652277] [] (tty_port_tty_wakeup) from [] (uart_write_wakeup+0x24/0x2c)
[ 361.652288] [] (uart_write_wakeup) from [] (serial8250_tx_chars+0x104/0x208)
[ 361.652300] [] (serial8250_tx_chars) from [] (serial8250_handle_irq.part.11+0xd8/0xdc)
[ 361.652312] [] (serial8250_handle_irq.part.11) from [] (serial8250_handle_irq+0x28/0x2c)
[ 361.652323] [] (serial8250_handle_irq) from [] (omap8250_irq+0x3c/0x54)
[ 361.652336] [] (omap8250_irq) from [] (__handle_irq_event_percpu+0x84/0x2d0)
[ 361.652349] [] (__handle_irq_event_percpu) from [] (handle_irq_event_percpu+0x3c/0x90)
[ 361.652361] [] (handle_irq_event_percpu) from [] (handle_irq_event+0x48/0x6c)
[ 361.652373] [] (handle_irq_event) from [] (handle_level_irq+0xdc/0x158)
[ 361.652384] [] (handle_level_irq) from [] (generic_handle_irq+0x34/0x44)
[ 361.652396] [] (generic_handle_irq) from [] (__handle_domain_irq+0x8c/0xfc)
[ 361.652408] [] (__handle_domain_irq) from [] (omap_intc_handle_irq+0x44/0x9c)
[ 361.652419] [] (omap_intc_handle_irq) from [] (__irq_svc+0x6c/0xa8)