SlideShare a Scribd company logo
Gluster d thread_synchronization_using_urcu_lca2016
2
GlusterD Thread Synchronization
using user space RCU
Atin Mukherjee
SSE-Red Hat
Gluster Maintainer
IRC : atinm on freenode
Twitter: @mukherjee_atin
Mail: amukherj@redhat.com
3
Agenda
● Introduction to Gluster & GlusterD
● Big lock in thread synchronization in GlusterD
● Issues with Big Lock approach
● Different locking primitives
● What is RCU
● Advantage of RCU over read-write lock
● RCU mechanisms – Insertion, Deletion, Reader
● URCU flavors
● URCU APIs
● URCU use cases
● Q&A
4
Gluster
● Open-source general purpose scale-out distributed
file system
● Aggregates storage exports over network
interconnect to provide a single unified namespace
● Layered on disk file systems that support extended
attributes
5
GlusterD
● Manages the cluster configuration for Gluster
● Responsible for
– Peer membership management
– Elastic volume management
– Configuration consistency
– Distributed command execution (orchestration)
– Service management (manages GlusterFS
daemons)
6
Thread synchronization in GlusterD
● GlusterD was initially designed as single threaded
● Single threaded → Multi threaded to satisfy usecases
like snapshot
● Big lock
– A coarse grained lock
– Only one transaction can work inside big lock
– Protects all the shared data structures
7
Issues with Big Lock
● Threads contend for even unrelated data
● Can end up in a deadlock
– RPC request's callback also needs big lock
● Shall we release big lock in between a transaction to
get rid of above deadlock? Yes we do, but….
● Here come's the problem - a small window of time
when the shared data structures are prone to updates
leading to inconsistencies
8
Different locking primitives
● Fine grained locks
– Mutex
– Read-write lock
– Spin lock
– Seq lock
– Read-Copy-Update (RCU)
9
What is RCU
● Synchronization mechanism
● Not new, added to Linux Kernel in 2002
● Allows reads to occur concurrently with update
● Maintains multiple version of objects for read
coherency
● Almost zero over heads in read side critical
section
10
Advantages of RCU over read-write
lock
● Concurrent readers & writers – writer writes, readers read
● Wait free reads
– RCU readers have no wait overhead. They can never be blocked by writers
● Existence guarantee
– RCU guarantees that RCU protected data in a readers critical section will remain
in existence till the end of the critical section
● Deadlock immunity
– RCU readers always run in a deterministic time as they never block. This means
that they can never become a part of a deadlock.
● No writer starvation
– As RCU readers don't block, writers can never starve.
11
RCU mechanism
● RCU is made up of three fundamental mechanisms
– Publish-Subscribe Mechanism (for insertion)
– Wait For Pre-Existing RCU Readers to Complete (for
deletion)
– Maintain Multiple Versions of Recently Updated Objects
(for readers)
12
Publish-Subscribe model
● rcu_assign_pointer () for publication
1 struct foo {
2 int a;
3 int b;
4 int c;
5 };
6 struct foo *gp = NULL;
7
8 /* . . . */
9
10 p = malloc (...);
11 p->a = 1;
12 p->b = 2;
13 p->c = 3;
14 gp = p;
1 struct foo {
2 int a;
3 int b;
4 int c;
5 };
6 struct foo *gp = NULL;
7
8 /* . . . */
9
10 p = malloc (...);
11 p->a = 1;
12 p->b = 2;
13 p->c = 3;
14 rcu_assign_pointer(gp, p);
● rcu_dereference () for subscription
1 p = gp;
2 if (p != NULL) {
3 do_something_with(p->a, p->b, p->c);
4 }
1 rcu_read_lock();
2 p = rcu_dereference(gp);
3 if (p != NULL) {
4 do_something_with(p->a, p->b, p->c);
5 }
6 rcu_read_unlock();
13
Publish-Subscribe Model (ii)
● rcu_assign_pointer () & rcu_dereference ()
embedded in special RCU variants of Linux's
list-manipulation API
● rcu_assign_pointer () → list_add_rcu ()
● rcu_dereference () → list_for_each_entry_rcu ()
14
Wait For Pre-Existing RCU Readers to
Complete
● Approach used for deletion
● Synchronous – synchronize_rcu ()
● Asynchronous – call_rcu ()
q = malloc(...);
*q = *p;
q->b = 2;
q->c = 3;
list_replace_rcu(&p->list, &q->list);
synchronize_rcu();
free(p)
q = malloc(...);
*q = *p;
q->b = 2;
q->c = 3;
list_replace_rcu(&p->list, &q->list);
call_rcu (&p->list, cbk); /* cbk will free p */
15
Maintain multiple version objects
● Used for existence gurantee
1. p = search(head, key);
2. list_del_rcu(&p->list);
3. synchronize_rcu();
4. free (p);
1. p = search(head, key);
2. list_del_rcu(&p->list);
3. synchronize_rcu();
4. free (p);
1. p = search(head, key);
2. list_del_rcu(&p->list);
3. synchronize_rcu();
4. free (p);
Maintain multiple version objects
● Used for existence gurantee
1. p = search(head, key);
2. list_del_rcu(&p->list);
3. synchronize_rcu();
4. free (p);
1. p = search(head, key);
2. list_del_rcu(&p->list);
3. synchronize_rcu();
4. free (p);
1. p = search(head, key);
2. list_del_rcu(&p->list);
3. synchronize_rcu();
4. free (p);
16
URCU flavors
● QSBR (quiescent-state-based RCU)
– each thread must periodically invoke rcu_quiescent_state()
– Thread (un)registration required
● Memory-barrier-based RCU
– Preemptible RCU implementation
– Introduces memory barrier in read critical secion, hence high read side
overhead
● “Bullet-proof” RCU (RCU-BP)
– Similar like memory barrier based RCU but thread (un)registration is taken
care
– Primitive overheads but can be used by application without worrying about
thread creation/destruction
17
URCU flavors (ii)
● Signal-based RCU
– Removes memory barrier
– Can be used by library function
– requires that the user application give up a POSIX signal to be
used by synchronize_rcu() in place of the read-side memory
barriers.
– Requires explicit thread registration
● Signal-based RCU using an out-of-tree sys_membarrier() system call
– sys_membarrier() system call instead of POSIX signal
18
URCU APIs
● Atomic-operation and utility APIs
– caa_: Concurrent Architecture Abstraction.
– cmm_: Concurrent Memory Model.
– uatomic_: URCU Atomic Operation.
– https://lwn.net/Articles/573435/
● The URCU APIs
– https://lwn.net/Articles/573439/
● RCU-Protected Lists
– https://lwn.net/Articles/573441
19
When is URCU useful
20
References
● https://lwn.net/Articles/262464/
● https://lwn.net/Articles/263130/
● https://lwn.net/Articles/573424/
● http://www.efficios.com/pub/lpc2011/Presentation-
lpc2011-desnoyers-urcu.pdf
● http://www.rdrop.com/~paulmck/RCU/RCU.IISc-
Bangalore.2013.06.03a.pdf
● http://urcu.so/
21
Q&A

More Related Content

PDF
OSBConf 2015 | Scale out backups with bareos and gluster by niels de vos
ODP
GlusterFS Containers
PDF
State of the_gluster_-_lceu
ODP
Scale out backups-with_bareos_and_gluster
PDF
Integrating gluster fs,_qemu_and_ovirt-vijay_bellur-linuxcon_eu_2013
ODP
Gluster intro-tdose
PDF
Sdc 2012-challenges
ODP
Developing apps and_integrating_with_gluster_fs_-_libgfapi
OSBConf 2015 | Scale out backups with bareos and gluster by niels de vos
GlusterFS Containers
State of the_gluster_-_lceu
Scale out backups-with_bareos_and_gluster
Integrating gluster fs,_qemu_and_ovirt-vijay_bellur-linuxcon_eu_2013
Gluster intro-tdose
Sdc 2012-challenges
Developing apps and_integrating_with_gluster_fs_-_libgfapi

What's hot (20)

ODP
20160130 Gluster-roadmap
PDF
Gluster intro-tdose
ODP
Lcna example-2012
ODP
Accessing gluster ufo_-_eco_willson
PDF
20160401 guster-roadmap
PDF
Gluster as Block Store in Containers
ODP
Persistent Storage in Openshift using GlusterFS
ODP
Gdeploy 2.0
PDF
Gluster Containerized Storage for Cloud Applications
ODP
Gluster technical overview
ODP
20160401 Gluster-roadmap
ODP
Kkeithley ufonfs-gluster summit
PDF
Gluster d2
PDF
Gluster for sysadmins
ODP
Dedupe nmamit
ODP
GlusterD 2.0 - Managing Distributed File System Using a Centralized Store
PDF
Qemu gluster fs
ODP
Lcna tutorial-2012
PDF
Hands On Gluster with Jeff Darcy
ODP
Join the super_colony_-_feb2013
20160130 Gluster-roadmap
Gluster intro-tdose
Lcna example-2012
Accessing gluster ufo_-_eco_willson
20160401 guster-roadmap
Gluster as Block Store in Containers
Persistent Storage in Openshift using GlusterFS
Gdeploy 2.0
Gluster Containerized Storage for Cloud Applications
Gluster technical overview
20160401 Gluster-roadmap
Kkeithley ufonfs-gluster summit
Gluster d2
Gluster for sysadmins
Dedupe nmamit
GlusterD 2.0 - Managing Distributed File System Using a Centralized Store
Qemu gluster fs
Lcna tutorial-2012
Hands On Gluster with Jeff Darcy
Join the super_colony_-_feb2013
Ad

Viewers also liked (13)

PPTX
Welcome to Gluster Developer Summit 2016
ODP
Tiering barcelona
ODP
Leases and-caching final
ODP
YDAL Barcelona
PDF
On demand file-caching_-_gustavo_brand
ODP
Sdc challenges-2012
PDF
Gluster wireshark niels_de_vos
ODP
Bug triage in_gluster
PDF
Debugging with-wireshark-niels-de-vos
ODP
Gsummit apis-2013
ODP
Integrating gluster fs,_qemu_and_ovirt-vijay_bellur-linuxcon_eu_2013
ODP
Gluster fs hadoop_fifth-elephant
ODP
Introduction to highly_availablenfs_server_on_scale-out_storage_systems_based...
Welcome to Gluster Developer Summit 2016
Tiering barcelona
Leases and-caching final
YDAL Barcelona
On demand file-caching_-_gustavo_brand
Sdc challenges-2012
Gluster wireshark niels_de_vos
Bug triage in_gluster
Debugging with-wireshark-niels-de-vos
Gsummit apis-2013
Integrating gluster fs,_qemu_and_ovirt-vijay_bellur-linuxcon_eu_2013
Gluster fs hadoop_fifth-elephant
Introduction to highly_availablenfs_server_on_scale-out_storage_systems_based...
Ad

Similar to Gluster d thread_synchronization_using_urcu_lca2016 (20)

ODP
Glusterd_thread_synchronization_using_urcu_lca2016
ODP
Thread synchronization in GlusterD using URCU
PDF
Introduction to RCU
PDF
Linux Synchronization Mechanism: RCU (Read Copy Update)
PDF
Yet another introduction to Linux RCU
PDF
rcu dan porter read update linux copy.pdf
PPT
PDF
Kernel Recipes 2019 - RCU in 2019 - Joel Fernandes
PDF
Userspace RCU library : what linear multiprocessor scalability means for your...
PPTX
Operating System Assignment Help
PPT
Synchronization linux
PDF
Lockless
PPTX
How to Avoid Learning the Linux-Kernel Memory Model
PDF
Optimization of Remote Core Locking Synchronization in Multithreaded Programs...
ODP
Concurrent Programming with Ruby and Tuple Spaces
PDF
Remote core locking (rcl)
PPT
10 Multicore 07
PDF
AOS Lab 4: If you liked it, then you should have put a “lock” on it
PDF
Lect04
PPTX
Remote core locking-Andrea Lombardo
Glusterd_thread_synchronization_using_urcu_lca2016
Thread synchronization in GlusterD using URCU
Introduction to RCU
Linux Synchronization Mechanism: RCU (Read Copy Update)
Yet another introduction to Linux RCU
rcu dan porter read update linux copy.pdf
Kernel Recipes 2019 - RCU in 2019 - Joel Fernandes
Userspace RCU library : what linear multiprocessor scalability means for your...
Operating System Assignment Help
Synchronization linux
Lockless
How to Avoid Learning the Linux-Kernel Memory Model
Optimization of Remote Core Locking Synchronization in Multithreaded Programs...
Concurrent Programming with Ruby and Tuple Spaces
Remote core locking (rcl)
10 Multicore 07
AOS Lab 4: If you liked it, then you should have put a “lock” on it
Lect04
Remote core locking-Andrea Lombardo

More from Gluster.org (20)

PDF
Automating Gluster @ Facebook - Shreyas Siravara
PDF
nfusr: a new userspace NFS client based on libnfs - Shreyas Siravara
PDF
Facebook’s upstream approach to GlusterFS - David Hasson
PDF
Throttling Traffic at Facebook Scale
PDF
GlusterFS w/ Tiered XFS
PDF
Gluster Metrics: why they are crucial for running stable deployments of all s...
PDF
Up and Running with Glusto & Glusto-Tests in 5 Minutes (or less)
PDF
Data Reduction for Gluster with VDO
PDF
Releases: What are contributors responsible for
PDF
RIO Distribution: Reconstructing the onion - Shyamsundar Ranganathan
PDF
Gluster and Kubernetes
PDF
Native Clients, more the merrier with GFProxy!
PDF
Gluster: a SWOT Analysis
PDF
GlusterD-2.0: What's Happening? - Kaushal Madappa
PDF
Scalability and Performance of CNS 3.6
PDF
What Makes Us Fail
PDF
Gluster as Native Storage for Containers - past, present and future
PDF
Heketi Functionality into Glusterd2
PDF
Architecture of the High Availability Solution for Ganesha and Samba with Kal...
PDF
Challenges with Gluster and Persistent Memory with Dan Lambright
Automating Gluster @ Facebook - Shreyas Siravara
nfusr: a new userspace NFS client based on libnfs - Shreyas Siravara
Facebook’s upstream approach to GlusterFS - David Hasson
Throttling Traffic at Facebook Scale
GlusterFS w/ Tiered XFS
Gluster Metrics: why they are crucial for running stable deployments of all s...
Up and Running with Glusto & Glusto-Tests in 5 Minutes (or less)
Data Reduction for Gluster with VDO
Releases: What are contributors responsible for
RIO Distribution: Reconstructing the onion - Shyamsundar Ranganathan
Gluster and Kubernetes
Native Clients, more the merrier with GFProxy!
Gluster: a SWOT Analysis
GlusterD-2.0: What's Happening? - Kaushal Madappa
Scalability and Performance of CNS 3.6
What Makes Us Fail
Gluster as Native Storage for Containers - past, present and future
Heketi Functionality into Glusterd2
Architecture of the High Availability Solution for Ganesha and Samba with Kal...
Challenges with Gluster and Persistent Memory with Dan Lambright

Recently uploaded (20)

PDF
Machine learning based COVID-19 study performance prediction
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Approach and Philosophy of On baking technology
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Spectral efficient network and resource selection model in 5G networks
PPTX
Big Data Technologies - Introduction.pptx
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
A Presentation on Artificial Intelligence
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
Cloud computing and distributed systems.
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
cuic standard and advanced reporting.pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
Understanding_Digital_Forensics_Presentation.pptx
Machine learning based COVID-19 study performance prediction
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
Chapter 3 Spatial Domain Image Processing.pdf
Unlocking AI with Model Context Protocol (MCP)
Reach Out and Touch Someone: Haptics and Empathic Computing
Approach and Philosophy of On baking technology
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Spectral efficient network and resource selection model in 5G networks
Big Data Technologies - Introduction.pptx
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
A Presentation on Artificial Intelligence
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Cloud computing and distributed systems.
Diabetes mellitus diagnosis method based random forest with bat algorithm
cuic standard and advanced reporting.pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
MYSQL Presentation for SQL database connectivity
Understanding_Digital_Forensics_Presentation.pptx

Gluster d thread_synchronization_using_urcu_lca2016

  • 2. 2 GlusterD Thread Synchronization using user space RCU Atin Mukherjee SSE-Red Hat Gluster Maintainer IRC : atinm on freenode Twitter: @mukherjee_atin Mail: amukherj@redhat.com
  • 3. 3 Agenda ● Introduction to Gluster & GlusterD ● Big lock in thread synchronization in GlusterD ● Issues with Big Lock approach ● Different locking primitives ● What is RCU ● Advantage of RCU over read-write lock ● RCU mechanisms – Insertion, Deletion, Reader ● URCU flavors ● URCU APIs ● URCU use cases ● Q&A
  • 4. 4 Gluster ● Open-source general purpose scale-out distributed file system ● Aggregates storage exports over network interconnect to provide a single unified namespace ● Layered on disk file systems that support extended attributes
  • 5. 5 GlusterD ● Manages the cluster configuration for Gluster ● Responsible for – Peer membership management – Elastic volume management – Configuration consistency – Distributed command execution (orchestration) – Service management (manages GlusterFS daemons)
  • 6. 6 Thread synchronization in GlusterD ● GlusterD was initially designed as single threaded ● Single threaded → Multi threaded to satisfy usecases like snapshot ● Big lock – A coarse grained lock – Only one transaction can work inside big lock – Protects all the shared data structures
  • 7. 7 Issues with Big Lock ● Threads contend for even unrelated data ● Can end up in a deadlock – RPC request's callback also needs big lock ● Shall we release big lock in between a transaction to get rid of above deadlock? Yes we do, but…. ● Here come's the problem - a small window of time when the shared data structures are prone to updates leading to inconsistencies
  • 8. 8 Different locking primitives ● Fine grained locks – Mutex – Read-write lock – Spin lock – Seq lock – Read-Copy-Update (RCU)
  • 9. 9 What is RCU ● Synchronization mechanism ● Not new, added to Linux Kernel in 2002 ● Allows reads to occur concurrently with update ● Maintains multiple version of objects for read coherency ● Almost zero over heads in read side critical section
  • 10. 10 Advantages of RCU over read-write lock ● Concurrent readers & writers – writer writes, readers read ● Wait free reads – RCU readers have no wait overhead. They can never be blocked by writers ● Existence guarantee – RCU guarantees that RCU protected data in a readers critical section will remain in existence till the end of the critical section ● Deadlock immunity – RCU readers always run in a deterministic time as they never block. This means that they can never become a part of a deadlock. ● No writer starvation – As RCU readers don't block, writers can never starve.
  • 11. 11 RCU mechanism ● RCU is made up of three fundamental mechanisms – Publish-Subscribe Mechanism (for insertion) – Wait For Pre-Existing RCU Readers to Complete (for deletion) – Maintain Multiple Versions of Recently Updated Objects (for readers)
  • 12. 12 Publish-Subscribe model ● rcu_assign_pointer () for publication 1 struct foo { 2 int a; 3 int b; 4 int c; 5 }; 6 struct foo *gp = NULL; 7 8 /* . . . */ 9 10 p = malloc (...); 11 p->a = 1; 12 p->b = 2; 13 p->c = 3; 14 gp = p; 1 struct foo { 2 int a; 3 int b; 4 int c; 5 }; 6 struct foo *gp = NULL; 7 8 /* . . . */ 9 10 p = malloc (...); 11 p->a = 1; 12 p->b = 2; 13 p->c = 3; 14 rcu_assign_pointer(gp, p); ● rcu_dereference () for subscription 1 p = gp; 2 if (p != NULL) { 3 do_something_with(p->a, p->b, p->c); 4 } 1 rcu_read_lock(); 2 p = rcu_dereference(gp); 3 if (p != NULL) { 4 do_something_with(p->a, p->b, p->c); 5 } 6 rcu_read_unlock();
  • 13. 13 Publish-Subscribe Model (ii) ● rcu_assign_pointer () & rcu_dereference () embedded in special RCU variants of Linux's list-manipulation API ● rcu_assign_pointer () → list_add_rcu () ● rcu_dereference () → list_for_each_entry_rcu ()
  • 14. 14 Wait For Pre-Existing RCU Readers to Complete ● Approach used for deletion ● Synchronous – synchronize_rcu () ● Asynchronous – call_rcu () q = malloc(...); *q = *p; q->b = 2; q->c = 3; list_replace_rcu(&p->list, &q->list); synchronize_rcu(); free(p) q = malloc(...); *q = *p; q->b = 2; q->c = 3; list_replace_rcu(&p->list, &q->list); call_rcu (&p->list, cbk); /* cbk will free p */
  • 15. 15 Maintain multiple version objects ● Used for existence gurantee 1. p = search(head, key); 2. list_del_rcu(&p->list); 3. synchronize_rcu(); 4. free (p); 1. p = search(head, key); 2. list_del_rcu(&p->list); 3. synchronize_rcu(); 4. free (p); 1. p = search(head, key); 2. list_del_rcu(&p->list); 3. synchronize_rcu(); 4. free (p); Maintain multiple version objects ● Used for existence gurantee 1. p = search(head, key); 2. list_del_rcu(&p->list); 3. synchronize_rcu(); 4. free (p); 1. p = search(head, key); 2. list_del_rcu(&p->list); 3. synchronize_rcu(); 4. free (p); 1. p = search(head, key); 2. list_del_rcu(&p->list); 3. synchronize_rcu(); 4. free (p);
  • 16. 16 URCU flavors ● QSBR (quiescent-state-based RCU) – each thread must periodically invoke rcu_quiescent_state() – Thread (un)registration required ● Memory-barrier-based RCU – Preemptible RCU implementation – Introduces memory barrier in read critical secion, hence high read side overhead ● “Bullet-proof” RCU (RCU-BP) – Similar like memory barrier based RCU but thread (un)registration is taken care – Primitive overheads but can be used by application without worrying about thread creation/destruction
  • 17. 17 URCU flavors (ii) ● Signal-based RCU – Removes memory barrier – Can be used by library function – requires that the user application give up a POSIX signal to be used by synchronize_rcu() in place of the read-side memory barriers. – Requires explicit thread registration ● Signal-based RCU using an out-of-tree sys_membarrier() system call – sys_membarrier() system call instead of POSIX signal
  • 18. 18 URCU APIs ● Atomic-operation and utility APIs – caa_: Concurrent Architecture Abstraction. – cmm_: Concurrent Memory Model. – uatomic_: URCU Atomic Operation. – https://lwn.net/Articles/573435/ ● The URCU APIs – https://lwn.net/Articles/573439/ ● RCU-Protected Lists – https://lwn.net/Articles/573441
  • 19. 19 When is URCU useful
  • 20. 20 References ● https://lwn.net/Articles/262464/ ● https://lwn.net/Articles/263130/ ● https://lwn.net/Articles/573424/ ● http://www.efficios.com/pub/lpc2011/Presentation- lpc2011-desnoyers-urcu.pdf ● http://www.rdrop.com/~paulmck/RCU/RCU.IISc- Bangalore.2013.06.03a.pdf ● http://urcu.so/