{"push_id":908152381,"size":3,"distinct_size":0,"ref":"refs/heads/caf/korg/linux-3.18.y","head":"b12403044336e7d567f309eb443aa9acf76380af","before":"8341455f7f2b36212f8cdded7725e93b17f5a8fc","commits":[{"sha":"80e5c4ddd2fcbf99edd31a7c1379b3907cfd4f38","author":{"email":"e642b69ed2fc111e09ffdc37feb733a52253340d@oracle.com","name":"Sasha Levin"},"message":"Revert \"tty: fix stall caused by missing memory barrier in drivers/tty/n_tty.c\"\n\nThis reverts commit af32cc7bde6304dac92e6a74fe4b2cc8120cb29a.\n\nThe commit was incorrectly backported and was causing hangs.\n\nReported-by: Corey Wright <undefined@pobox.com>\nSigned-off-by: Sasha Levin <sasha.levin@oracle.com>","distinct":false,"url":"https://api.github.com/repos/Jackeagle/kernel_msm-3.10/commits/80e5c4ddd2fcbf99edd31a7c1379b3907cfd4f38"},{"sha":"b008351f30d7d60b34e0469fc07a8f5b1ac098ad","author":{"email":"e7e66d380a5e88b84428b8fa40ab240d2921d8d3@ab.jp.nec.com","name":"Kosuke Tatsukawa"},"message":"tty: fix stall caused by missing memory barrier in drivers/tty/n_tty.c\n\n[ Upstream commit e81107d4c6bd098878af9796b24edc8d4a9524fd ]\n\nMy colleague ran into a program stall on a x86_64 server, where\nn_tty_read() was waiting for data even if there was data in the buffer\nin the pty.  kernel stack for the stuck process looks like below.\n #0 [ffff88303d107b58] __schedule at ffffffff815c4b20\n #1 [ffff88303d107bd0] schedule at ffffffff815c513e\n #2 [ffff88303d107bf0] schedule_timeout at ffffffff815c7818\n #3 [ffff88303d107ca0] wait_woken at ffffffff81096bd2\n #4 [ffff88303d107ce0] n_tty_read at ffffffff8136fa23\n #5 [ffff88303d107dd0] tty_read at ffffffff81368013\n #6 [ffff88303d107e20] __vfs_read at ffffffff811a3704\n #7 [ffff88303d107ec0] vfs_read at ffffffff811a3a57\n #8 [ffff88303d107f00] sys_read at ffffffff811a4306\n #9 [ffff88303d107f50] entry_SYSCALL_64_fastpath at ffffffff815c86d7\n\nThere seems to be two problems causing this issue.\n\nFirst, in drivers/tty/n_tty.c, __receive_buf() stores the data and\nupdates ldata->commit_head using smp_store_release() and then checks\nthe wait queue using waitqueue_active().  However, since there is no\nmemory barrier, __receive_buf() could return without calling\nwake_up_interactive_poll(), and at the same time, n_tty_read() could\nstart to wait in wait_woken() as in the following chart.\n\n        __receive_buf()                         n_tty_read()\n------------------------------------------------------------------------\nif (waitqueue_active(&tty->read_wait))\n/* Memory operations issued after the\n   RELEASE may be completed before the\n   RELEASE operation has completed */\n                                        add_wait_queue(&tty->read_wait, &wait);\n                                        ...\n                                        if (!input_available_p(tty, 0)) {\nsmp_store_release(&ldata->commit_head,\n                  ldata->read_head);\n                                        ...\n                                        timeout = wait_woken(&wait,\n                                          TASK_INTERRUPTIBLE, timeout);\n------------------------------------------------------------------------\n\nThe second problem is that n_tty_read() also lacks a memory barrier\ncall and could also cause __receive_buf() to return without calling\nwake_up_interactive_poll(), and n_tty_read() to wait in wait_woken()\nas in the chart below.\n\n        __receive_buf()                         n_tty_read()\n------------------------------------------------------------------------\n                                        spin_lock_irqsave(&q->lock, flags);\n                                        /* from add_wait_queue() */\n                                        ...\n                                        if (!input_available_p(tty, 0)) {\n                                        /* Memory operations issued after the\n                                           RELEASE may be completed before the\n                                           RELEASE operation has completed */\nsmp_store_release(&ldata->commit_head,\n                  ldata->read_head);\nif (waitqueue_active(&tty->read_wait))\n                                        __add_wait_queue(q, wait);\n                                        spin_unlock_irqrestore(&q->lock,flags);\n                                        /* from add_wait_queue() */\n                                        ...\n                                        timeout = wait_woken(&wait,\n                                          TASK_INTERRUPTIBLE, timeout);\n------------------------------------------------------------------------\n\nThere are also other places in drivers/tty/n_tty.c which have similar\ncalls to waitqueue_active(), so instead of adding many memory barrier\ncalls, this patch simply removes the call to waitqueue_active(),\nleaving just wake_up*() behind.\n\nThis fixes both problems because, even though the memory access before\nor after the spinlocks in both wake_up*() and add_wait_queue() can\nsneak into the critical section, it cannot go past it and the critical\nsection assures that they will be serialized (please see \"INTER-CPU\nACQUIRING BARRIER EFFECTS\" in Documentation/memory-barriers.txt for a\nbetter explanation).  Moreover, the resulting code is much simpler.\n\nLatency measurement using a ping-pong test over a pty doesn't show any\nvisible performance drop.\n\nSigned-off-by: Kosuke Tatsukawa <tatsu@ab.jp.nec.com>\nCc: stable@vger.kernel.org\nSigned-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>\nSigned-off-by: Sasha Levin <sasha.levin@oracle.com>","distinct":false,"url":"https://api.github.com/repos/Jackeagle/kernel_msm-3.10/commits/b008351f30d7d60b34e0469fc07a8f5b1ac098ad"},{"sha":"b12403044336e7d567f309eb443aa9acf76380af","author":{"email":"e642b69ed2fc111e09ffdc37feb733a52253340d@oracle.com","name":"Sasha Levin"},"message":"Linux 3.18.24\n\nSigned-off-by: Sasha Levin <sasha.levin@oracle.com>","distinct":false,"url":"https://api.github.com/repos/Jackeagle/kernel_msm-3.10/commits/b12403044336e7d567f309eb443aa9acf76380af"}]}