Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dissection d'un smartphone Android et anatomie du réseau mobile

Dissection d'un smartphone Android et anatomie du réseau mobile

Bien souvent perchés au sommet d'une pile d'API, nous perdons parfois de vue les composants qui permettent à nos applications de fonctionner. Vous êtes vous déjà demandé pourquoi il fallait utiliser les wakelocks avec parcimonie ? Ou pourquoi il est conseillé de grouper vos requêtes réseaux ? ...

Durant cette présentation chirurgicale, nous verrons ce qui se cache derrière des acronymes comme DVFS, RRC ou des noms de code comme Big.Little, Viking Killer. Cela nous donnera ainsi l'occasion de lever le voile sur différentes recommandations qui trouvent leurs origines dans l'architecture matérielle de votre terminal et du réseau.

Db950a4adf54b7a13cd3c70fdcd7e334?s=128

Pierre Crépieux

April 07, 2017
Tweet

Transcript

  1. Dissection d'un smartphone Android et anatomie du réseau mobile Pierre

    Crépieux (Orange) 1 #DevoxxFR
  2. Agenda 2 . 1

  3. 2 . 2

  4. 2 . 3

  5. D'étranges symptômes 2 . 4

  6. D'étranges symptômes 2 . 5

  7. D'étranges symptômes 2 . 6

  8. D'étranges symptômes 2 . 7

  9. Les développeurs sont parfois touchés par deux troubles (moi y

    compris ...) Electronite Radiolergie 2 . 8
  10. Electronite Obstination à négliger les composants électroniques présents dans le

    terminal mobile. Peut être lié à une carence ou parfois à un traumatisme engendré par les cours d'électronique. Credits: https://bl.ocks.org/jinroh/7524988 2 . 9
  11. Radiolergie Réaction d'incompréhension sévère face à l'architecture du réseau mobile.

    Peut également être lié à une carence ou parfois à une fatigue occulaire engendrée par la tentative d'une lecture exhaustive des specifications. 2 . 10
  12. Dissection 3 . 1

  13. Dissection en direct 3 . 2

  14. Architecture matérielle 3 . 3

  15. Architecture logicielle 3 . 4

  16. Architecture logicielle 3 . 5

  17. DVFS 4 . 1

  18. Pourquoi Les applications sollicitent différents profiles de performances: Web Jeux

    Musique Garantir de bonnes performances a un coût: 2649MHz => ~500mA Impacte fortement la batterie 4 . 2
  19. CPUfreq Pswitch = α x C x V2 x f

    α: l'activité (commutations) C: capacité des transistors V: tension d'alimentation f: fréquence d'horloge Clock scaling allows you to change the clock speed of the CPUs on the fly. This is a nice method to save battery power, because the lower the clock speed, the less power the CPU consumes. 4 . 3
  20. governor CPUfreq s'appuie sur un "governor" associé à un driver

    pour modifier la fréquence du CPU $ cat /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor interactive $ cat /sys/devices/system/cpu/cpu5/cpufreq/scaling_available_frequencies 384000 480000 633600 768000 864000 960000 1248000 1344000 1440000 1536000 1632000 1689600 1824000 $ cat /sys/devices/system/cpu/cpu5/cpufreq/scaling_driver msm $ cat /sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_cur_freq 633600 $ cat /sys/devices/system/cpu/cpu5/cpufreq/scaling_available_governors interactive ondemand userspace powersave performance $ cat /sys/devices/system/cpu/cpu5/cpufreq/scaling_cur_freq 633600 $ cat /sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_max_freq 1824000 $ cat /sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_min_freq 384000 4 . 4
  21. governor CPUfreq s'appuie sur un "governor" associé à un driver

    pour modifier la fréquence du CPU $ cat /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor $ cat /sys/devices/system/cpu/cpu5/cpufreq/scaling_available_frequencies $ cat /sys/devices/system/cpu/cpu5/cpufreq/scaling_driver msm $ cat /sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_cur_freq 633600 $ cat /sys/devices/system/cpu/cpu5/cpufreq/scaling_available_governors interactive ondemand userspace powersave performance $ cat /sys/devices/system/cpu/cpu5/cpufreq/scaling_cur_freq 633600 $ cat /sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_max_freq 1824000 $ cat /sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_min_freq 384000 interactive 384000 480000 633600 768000 864000 960000 1248000 1344000 1440000 1536000 1632000 1689600 1824000 <= P-States 4 . 5
  22. governor Il en existe plusieurs types: Performance Powersave Userspace On-demand

    Interactive Schedutil 4 . 6
  23. cpuidle A l'image des P-States pour lesquels le niveau de

    performance du CPU va décroissant, les C-States permettent au CPU de ne rien faire "efficacement". ↑ P-0 Fréquence max P-n Fréquence min ↓ C-0 idle C-1 stoppe l'horloge principale C-2 stoppe les horloges internes C-3 la plupart des composants sont désactivés 4 . 7
  24. scheduler Scheduler cpuidle cpufreq rq T T P f L

    CPU1 CPU2 (BoFs) Power-Aware Scheduling - Morten Rasmussen, ARM, Ltd. 4 . 8
  25. Big.Little 1 1 1 1 2 2 2 2 High

    Perf Cluster "Low" Perf Cluster 1 2 3 4 1 2 3 4 big cores "LITTLE" cores 4 . 9
  26. Big.Little MP 1 2 3 4 5 6 7 8

    GTS 4 . 10
  27. EAS GTS (Big.LITTLE MP) développé principalement par ARM avec parfois

    trop d'adhérence nécessite trop de modifications dans le noyau présent dans certains terminaux (samsung) EAS (Energy Aware Scheduler) initiative visant à remettre à plat la coopération entre les modules impliqués scheduler driven policy s'appuie sur un modèle de consommation d'énérgie présent dans le Pixel (google) 4 . 11
  28. source: ARM eas overview and integration guide 4 . 12

  29. cpus { A57_0: cpu@0 { compatible = "arm,cortex-a57","arm,armv8"; sched-energy-costs =

    <&CPU_COST_0 &CLUSTER_COST_0>; }; A57_1: cpu@1 { compatible = "arm,cortex-a57","arm,armv8"; sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>; }; A53_0: cpu@100 { compatible = "arm,cortex-a53","arm,armv8"; sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>; }; A53_1: cpu@101 { compatible = "arm,cortex-a53","arm,armv8"; sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>; }; energy-costs { CPU_COST_0: core-cost0 { busy-cost-data = < 417 168 744 359 1024 616 >; idle-cost-data = < 15 0 >; }; CPU_COST_1: core-cost1 { busy-cost-data = < 235 33 368 61 447 93 >; idle-cost-data = < 6 0 >; }; CLUSTER_COST_0: cluster-cost0 { busy-cost-data = < 417 24 744 43 1024 64 >; idle-cost-data = < 65 24 >; }; CLUSTER_COST_1: cluster-cost1 { busy-cost-data = < 235 26 368 39 447 57 >; idle-cost-data = < 56 17 >; }; }; 4 . 13
  30. Support pre EAS bullhead:/ # cat init.bullhead.rc on boot #

    update foreground cpuset now that processors are up foreground gets all CPUs except CPU 3 # CPU 3 is reserved for the top app write /dev/cpuset/foreground/cpus 0-2,4-5 write /dev/cpuset/foreground/boost/cpus 4-5 write /dev/cpuset/background/cpus 0 write /dev/cpuset/system-background/cpus 0-2 write /dev/cpuset/top-app/cpus 0-5 [aosp/frameworks/base/core/jni/android_util_Process.cpp] /** * Stores the CPUs assigned to the cpuset corresponding to the SchedPolicy in the passed in cpu_set. */ static void get_cpuset_cores_for_policy(SchedPolicy policy, cpu_set_t *cpu_set) { FILE *file; const char *filename; CPU_ZERO(cpu_set); switch (policy) { filename = "/dev/cpuset/background/cpus"; break; case SP_BACKGROUND: [aosp/frameworks/base/core/java/android/os/Process.java] /** * Background thread group - All threads in this group are scheduled with a reduced share of the CPU. * Value is same as constant of enum SchedPolicy. */ public static final int THREAD_GROUP_BG_NONINTERACTIVE = 0; SP_BACKGROUND 4 . 14
  31. [aosp/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java] private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,

    long nowElapsed) { ... int processGroup; switch (app.curSchedGroup) { case ProcessList.SCHED_GROUP_BACKGROUND: processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; break; case ProcessList.SCHED_GROUP_TOP_APP: case ProcessList.SCHED_GROUP_TOP_APP_BOUND: processGroup = Process.THREAD_GROUP_TOP_APP; break; } try { Process.setProcessGroup(app.pid, processGroup); [aosp/frameworks/base/core/jni/android_util_Process.cpp] void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp) { #ifdef ENABLE_CPUSETS // set both cpuset and cgroup for general threads err = set_cpuset_policy(t_pid, sp); if (err != NO_ERROR) { signalExceptionForGroupError(env, -err, t_pid); break; } #endif err = set_sched_policy(t_pid, sp); if (err != NO_ERROR) { signalExceptionForGroupError(env, -err, t_pid); break; } 4 . 15
  32. [/system/core/libcutils/sched_policy.c] int set_cpuset_policy(int tid, SchedPolicy policy) { // in the

    absence of cpusets, use the old sched policy #ifndef USE_CPUSETS return set_sched_policy(tid, policy); #else if (tid == 0) { tid = gettid(); } policy = _policy(policy); pthread_once(&the_once, __initialize); int fd = -1; int boost_fd = -1; switch (policy) { case SP_BACKGROUND: boost_fd = bg_schedboost_fd; break; case SP_FOREGROUND: case SP_AUDIO_APP: case SP_AUDIO_SYS: } if (add_tid_to_cgroup(tid, fd) != 0) { if (errno != ESRCH && errno != ENOENT) return -errno; } fd = bg_cpuset_fd; int set_sched_policy(int tid, SchedPolicy policy) { if (__sys_supports_schedgroups) { int fd = -1; int boost_fd = -1; switch (policy) { case SP_BACKGROUND: boost_fd = bg_schedboost_fd; break; case SP_FOREGROUND: case SP_AUDIO_APP: case SP_AUDIO_SYS: fd = fg_cgroup_fd; boost_fd = fg_schedboost_fd; break; case SP_TOP_APP: fd = fg_cgroup_fd; boost_fd = ta_schedboost_fd; break; default: fd = -1; boost_fd = -1; break; } if (add_tid_to_cgroup(tid, fd) != 0) { if (errno != ESRCH && errno != ENOENT) return -errno; } fd = bg_cgroup_fd; 4 . 16
  33. Viking Killer 5 . 1

  34. Contexte Android a une gestion un peu particulière des process

    Sur un smartphone: Le lancement d'une application doit être quasi instantané La quantité de mémoire est contrainte 5 . 2
  35. low memory killer Module noyau créé spécifiquement pour Android Tue

    les process en cas de manque d'espace mémoire Permet au framework de préserver des process via oom_adj Intervient avant l'OOM killer du noyau / low memory notif du kernel bullhead:/ # cat /proc/`pidof com.google.android.youtube`/oom_adj 12 #This is a process only hosting activities that are not visible bullhead:/ # cat /proc/`pidof com.google.android.googlequicksearchbox`/oom_adj 4 #It is in the background, but we want to try to avoid killing it. bullhead:/ # cat /proc/`pidof com.google.android.youtube`/oom_adj 0 #This is the process running the current foreground app. bullhead:/ # cat /proc/`pidof /system/bin/rild`/oom_adj -17 #Special code for native processes that are not being managed by the system 5 . 3
  36. [aosp/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java] private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,

    long nowElapsed) { ... } private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, boolean doingAll, long now) { ... if (app == TOP_APP) { // The last app on the list is the foreground app. adj = ProcessList.FOREGROUND_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_TOP_APP; app.adjType = "top-activity"; foregroundActivities = true; procState = PROCESS_STATE_CUR_TOP; ... 5 . 4
  37. Wakelock 6 . 1

  38. Optimiser l'autonomie Lorsqu'un appareil est démarré: en général, il reste

    allumé et parfois passe en veille avec Android, il doit rester éteint et parfois s'allumer "1s of active, takes away ~2min of standby" , Google I/O 2014 - Introduction to Project Volta 6 . 2
  39. opportunistic suspend Android: a mis en place une politique "agressive"

    de mise en veille en introduisant la notion de "suspend blocker" (wakelock) dans "son" noyaux linux aggrémenté d'une API permettant au userland d'y accéder dès lors qu'aucun wakelock n'est pris, le téléphone passe en veille. PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, tag); wl.acquire(); wl.release(); 6 . 3
  40. Synchro avec Linux un historique long et parfois tumultueux earlysuspend

    => PowerManagerService + autosleep (3.5) suspend blocker (wakelock) => wakeup source commit 012ce32a330ade8b3dd6f050f938414b8fc3b5bf [log] [tgz] author Arve Hjønnevåg Fri Mar 16 17:44:42 2012 -0700 committer Ruchi Kandoi Tue Feb 03 16:47:54 2015 -0800 tree 969a34a39d33ac57508c70268a10054949be3217 parent a4616e0e759f5da7384c9c999a18f8eb5b7967b0 [diff] [blame] PM / Sleep: Add wake lock api wrapper on top of wakeup sources Change-Id: Icaad02fe1e8856fdc2e4215f380594a5dde8e002 Signed-off-by: Arve Hjønnevåg ... struct wake_lock { struct wakeup_source ws; }; ... 6 . 4
  41. RRC 7 . 1

  42. Screen-Off Traffic Characterization and Optimization in 3G/4G Networks, University of

    Michigan, AT&T Based on analyzing real smartphone traffic collected from 20 users over five months, we find that off-screen traffic accounts for 58.5% of the total radio energy consumption although their traffic volume contribution is much smaller. Such unexpected results are attributed to the unique cellular resource management policy that is not well understood by developers, leading to cellular- unfriendly mobile apps. 7 . 2
  43. Le réseau vu de l'utilisateur 7 . 3

  44. Le réseau vu du développeur 7 . 4

  45. Le réseau Internet HSS MME SGW PGW PCRF 7 .

    5
  46. Experience 7 . 6

  47. Experience 7 . 7

  48. Experience 7 . 8

  49. Experience 7 . 9

  50. Experience 7 . 10

  51. Architecture réseau Internet HSS MME HLR SGW PGW SGSN GGSN

    MSC RNC PCRF SMSC IP IP Telephony AS SIP SS7 ...simplifiée 7 . 11
  52. Machine d'états RRC en 3G :15 :15 :20 :20 :25

    :25 0 0 50 50 100 100 150 150 200 200 250 250 300 300 courant (mA) 7 . 12
  53. Machine d'états RRC en 3G 7 . 13

  54. 7 . 14

  55. 7 . 15

  56. Machine d'états RRC en 4G 7 . 16

  57. Machine d'états RRC en 4G :46 :46 :47 :47 :48

    :48 :49 :49 :50 :50 :51 :51 :52 :52 :53 :53 :54 :54 0 0 50 50 100 100 150 150 200 200 250 250 300 300 courant (mA) 7 . 17
  58. 7 . 18

  59. 7 . 19

  60. 3174-1494 = 1680 (28min) 7 . 20

  61. 7 . 21

  62. 7 . 22

  63. Recommandations 8

  64. Pour aller plus loin 9

  65. Questions ? 10