{"push_id":550067089,"size":1,"distinct_size":1,"ref":"refs/heads/lollipop","head":"75dcb360be8f82105ca957da55f71949a1876f52","before":"2d9375abcea90a7e9b09d05f5f5e316c6b022763","commits":[{"sha":"75dcb360be8f82105ca957da55f71949a1876f52","author":{"email":"e4b2d9917bc51c00939020277d9154b44ab7b287@marvell.com","name":"Jane Li"},"message":"cpufreq: Fix timer/workqueue corruption by protecting reading governor_enabled\n\nWhen a CPU is hot removed we'll cancel all the delayed work items via\ngov_cancel_work(). Sometimes the delayed work function determines that\nit should adjust the delay for all other CPUs that the policy is\nmanaging. If this scenario occurs, the canceling CPU will cancel its own\nwork but queue up the other CPUs works to run.\n\nCommit 3617f2 (cpufreq: Fix timer/workqueue corruption due to double\nqueueing) has tried to fix this, but reading governor_enabled is not\nprotected by cpufreq_governor_lock. Even though od_dbs_timer() checks\ngovernor_enabled before gov_queue_work(), this scenario may occur. For\nexample:\n\n CPU0                                        CPU1\n ----                                        ----\n cpu_down()\n  ...                                        <work runs>\n  __cpufreq_remove_dev()                     od_dbs_timer()\n   __cpufreq_governor()                       policy->governor_enabled\n    policy->governor_enabled = false;\n    cpufreq_governor_dbs()\n     case CPUFREQ_GOV_STOP:\n      gov_cancel_work(dbs_data, policy);\n       cpu0 work is canceled\n        timer is canceled\n        cpu1 work is canceled\n        <waits for cpu1>\n                                              gov_queue_work(*, *, true);\n                                               cpu0 work queued\n                                               cpu1 work queued\n                                               cpu2 work queued\n                                               ...\n        cpu1 work is canceled\n        cpu2 work is canceled\n        ...\n\nAt the end of the GOV_STOP case cpu0 still has a work queued to\nrun although the code is expecting all of the works to be\ncanceled. __cpufreq_remove_dev() will then proceed to\nre-initialize all the other CPUs works except for the CPU that is\ngoing down. The CPUFREQ_GOV_START case in cpufreq_governor_dbs()\nwill trample over the queued work and debugobjects will spit out\na warning:\n\nWARNING: at lib/debugobjects.c:260 debug_print_object+0x94/0xbc()\nODEBUG: init active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x14\nModules linked in:\nCPU: 1 PID: 1205 Comm: sh Tainted: G        W    3.10.0 #200\n[<c01144f0>] (unwind_backtrace+0x0/0xf8) from [<c0111d98>] (show_stack+0x10/0x14)\n[<c0111d98>] (show_stack+0x10/0x14) from [<c01272cc>] (warn_slowpath_common+0x4c/0x68)\n[<c01272cc>] (warn_slowpath_common+0x4c/0x68) from [<c012737c>] (warn_slowpath_fmt+0x30/0x40)\n[<c012737c>] (warn_slowpath_fmt+0x30/0x40) from [<c034c640>] (debug_print_object+0x94/0xbc)\n[<c034c640>] (debug_print_object+0x94/0xbc) from [<c034c7f8>] (__debug_object_init+0xc8/0x3c0)\n[<c034c7f8>] (__debug_object_init+0xc8/0x3c0) from [<c01360e0>] (init_timer_key+0x20/0x104)\n[<c01360e0>] (init_timer_key+0x20/0x104) from [<c04872ac>] (cpufreq_governor_dbs+0x1dc/0x68c)\n[<c04872ac>] (cpufreq_governor_dbs+0x1dc/0x68c) from [<c04833a8>] (__cpufreq_governor+0x80/0x1b0)\n[<c04833a8>] (__cpufreq_governor+0x80/0x1b0) from [<c0483704>] (__cpufreq_remove_dev.isra.12+0x22c/0x380)\n[<c0483704>] (__cpufreq_remove_dev.isra.12+0x22c/0x380) from [<c0692f38>] (cpufreq_cpu_callback+0x48/0x5c)\n[<c0692f38>] (cpufreq_cpu_callback+0x48/0x5c) from [<c014fb40>] (notifier_call_chain+0x44/0x84)\n[<c014fb40>] (notifier_call_chain+0x44/0x84) from [<c012ae44>] (__cpu_notify+0x2c/0x48)\n[<c012ae44>] (__cpu_notify+0x2c/0x48) from [<c068dd40>] (_cpu_down+0x80/0x258)\n[<c068dd40>] (_cpu_down+0x80/0x258) from [<c068df40>] (cpu_down+0x28/0x3c)\n[<c068df40>] (cpu_down+0x28/0x3c) from [<c068e4c0>] (store_online+0x30/0x74)\n[<c068e4c0>] (store_online+0x30/0x74) from [<c03a7308>] (dev_attr_store+0x18/0x24)\n[<c03a7308>] (dev_attr_store+0x18/0x24) from [<c0256fe0>] (sysfs_write_file+0x100/0x180)\n[<c0256fe0>] (sysfs_write_file+0x100/0x180) from [<c01fec9c>] (vfs_write+0xbc/0x184)\n[<c01fec9c>] (vfs_write+0xbc/0x184) from [<c01ff034>] (SyS_write+0x40/0x68)\n[<c01ff034>] (SyS_write+0x40/0x68) from [<c010e200>] (ret_fast_syscall+0x0/0x48)\n\nIn gov_queue_work(), lock cpufreq_governor_lock before gov_queue_work,\nand unlock it after __gov_queue_work(). In this way, governor_enabled\nis guaranteed not changed in gov_queue_work().\n\nChange-Id: I9783d65aa78f9ca5e5cd83c386c50f67e1bffae1\nSigned-off-by: Jane Li <jiel@marvell.com>\nAcked-by: Viresh Kumar <viresh.kumar@linaro.org>\nReviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>\nSigned-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>\nSigned-off-by: franciscofranco <franciscofranco.1990@gmail.com>","distinct":true,"url":"https://api.github.com/repos/DirtyUnicorns/android_kernel_moto_shamu/commits/75dcb360be8f82105ca957da55f71949a1876f52"}]}