@@ -1877,13 +1877,27 @@ static struct notifier_block kprobe_exceptions_nb = {
18771877#ifdef CONFIG_KRETPROBES
18781878
18791879#if !defined(CONFIG_KRETPROBE_ON_RETHOOK )
1880+
1881+ /* callbacks for objpool of kretprobe instances */
1882+ static int kretprobe_init_inst (void * nod , void * context )
1883+ {
1884+ struct kretprobe_instance * ri = nod ;
1885+
1886+ ri -> rph = context ;
1887+ return 0 ;
1888+ }
1889+ static int kretprobe_fini_pool (struct objpool_head * head , void * context )
1890+ {
1891+ kfree (context );
1892+ return 0 ;
1893+ }
1894+
18801895static void free_rp_inst_rcu (struct rcu_head * head )
18811896{
18821897 struct kretprobe_instance * ri = container_of (head , struct kretprobe_instance , rcu );
1898+ struct kretprobe_holder * rph = ri -> rph ;
18831899
1884- if (refcount_dec_and_test (& ri -> rph -> ref ))
1885- kfree (ri -> rph );
1886- kfree (ri );
1900+ objpool_drop (ri , & rph -> pool );
18871901}
18881902NOKPROBE_SYMBOL (free_rp_inst_rcu );
18891903
@@ -1892,7 +1906,7 @@ static void recycle_rp_inst(struct kretprobe_instance *ri)
18921906 struct kretprobe * rp = get_kretprobe (ri );
18931907
18941908 if (likely (rp ))
1895- freelist_add ( & ri -> freelist , & rp -> freelist );
1909+ objpool_push ( ri , & rp -> rph -> pool );
18961910 else
18971911 call_rcu (& ri -> rcu , free_rp_inst_rcu );
18981912}
@@ -1929,23 +1943,12 @@ NOKPROBE_SYMBOL(kprobe_flush_task);
19291943
19301944static inline void free_rp_inst (struct kretprobe * rp )
19311945{
1932- struct kretprobe_instance * ri ;
1933- struct freelist_node * node ;
1934- int count = 0 ;
1935-
1936- node = rp -> freelist .head ;
1937- while (node ) {
1938- ri = container_of (node , struct kretprobe_instance , freelist );
1939- node = node -> next ;
1940-
1941- kfree (ri );
1942- count ++ ;
1943- }
1946+ struct kretprobe_holder * rph = rp -> rph ;
19441947
1945- if (refcount_sub_and_test ( count , & rp -> rph -> ref )) {
1946- kfree ( rp -> rph ) ;
1947- rp -> rph = NULL ;
1948- }
1948+ if (! rph )
1949+ return ;
1950+ rp -> rph = NULL ;
1951+ objpool_fini ( & rph -> pool );
19491952}
19501953
19511954/* This assumes the 'tsk' is the current task or the is not running. */
@@ -2087,19 +2090,17 @@ NOKPROBE_SYMBOL(__kretprobe_trampoline_handler)
20872090static int pre_handler_kretprobe (struct kprobe * p , struct pt_regs * regs )
20882091{
20892092 struct kretprobe * rp = container_of (p , struct kretprobe , kp );
2093+ struct kretprobe_holder * rph = rp -> rph ;
20902094 struct kretprobe_instance * ri ;
2091- struct freelist_node * fn ;
20922095
2093- fn = freelist_try_get ( & rp -> freelist );
2094- if (!fn ) {
2096+ ri = objpool_pop ( & rph -> pool );
2097+ if (!ri ) {
20952098 rp -> nmissed ++ ;
20962099 return 0 ;
20972100 }
20982101
2099- ri = container_of (fn , struct kretprobe_instance , freelist );
2100-
21012102 if (rp -> entry_handler && rp -> entry_handler (ri , regs )) {
2102- freelist_add ( & ri -> freelist , & rp -> freelist );
2103+ objpool_push ( ri , & rph -> pool );
21032104 return 0 ;
21042105 }
21052106
@@ -2193,7 +2194,6 @@ int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long o
21932194int register_kretprobe (struct kretprobe * rp )
21942195{
21952196 int ret ;
2196- struct kretprobe_instance * inst ;
21972197 int i ;
21982198 void * addr ;
21992199
@@ -2227,19 +2227,12 @@ int register_kretprobe(struct kretprobe *rp)
22272227 rp -> maxactive = max_t (unsigned int , 10 , 2 * num_possible_cpus ());
22282228
22292229#ifdef CONFIG_KRETPROBE_ON_RETHOOK
2230- rp -> rh = rethook_alloc ((void * )rp , kretprobe_rethook_handler );
2231- if (!rp -> rh )
2232- return - ENOMEM ;
2230+ rp -> rh = rethook_alloc ((void * )rp , kretprobe_rethook_handler ,
2231+ sizeof (struct kretprobe_instance ) +
2232+ rp -> data_size , rp -> maxactive );
2233+ if (IS_ERR (rp -> rh ))
2234+ return PTR_ERR (rp -> rh );
22332235
2234- for (i = 0 ; i < rp -> maxactive ; i ++ ) {
2235- inst = kzalloc (struct_size (inst , data , rp -> data_size ), GFP_KERNEL );
2236- if (inst == NULL ) {
2237- rethook_free (rp -> rh );
2238- rp -> rh = NULL ;
2239- return - ENOMEM ;
2240- }
2241- rethook_add_node (rp -> rh , & inst -> node );
2242- }
22432236 rp -> nmissed = 0 ;
22442237 /* Establish function entry probe point */
22452238 ret = register_kprobe (& rp -> kp );
@@ -2248,24 +2241,18 @@ int register_kretprobe(struct kretprobe *rp)
22482241 rp -> rh = NULL ;
22492242 }
22502243#else /* !CONFIG_KRETPROBE_ON_RETHOOK */
2251- rp -> freelist .head = NULL ;
22522244 rp -> rph = kzalloc (sizeof (struct kretprobe_holder ), GFP_KERNEL );
22532245 if (!rp -> rph )
22542246 return - ENOMEM ;
22552247
2256- rp -> rph -> rp = rp ;
2257- for (i = 0 ; i < rp -> maxactive ; i ++ ) {
2258- inst = kzalloc (struct_size (inst , data , rp -> data_size ), GFP_KERNEL );
2259- if (inst == NULL ) {
2260- refcount_set (& rp -> rph -> ref , i );
2261- free_rp_inst (rp );
2262- return - ENOMEM ;
2263- }
2264- inst -> rph = rp -> rph ;
2265- freelist_add (& inst -> freelist , & rp -> freelist );
2248+ if (objpool_init (& rp -> rph -> pool , rp -> maxactive , rp -> data_size +
2249+ sizeof (struct kretprobe_instance ), GFP_KERNEL ,
2250+ rp -> rph , kretprobe_init_inst , kretprobe_fini_pool )) {
2251+ kfree (rp -> rph );
2252+ rp -> rph = NULL ;
2253+ return - ENOMEM ;
22662254 }
2267- refcount_set (& rp -> rph -> ref , i );
2268-
2255+ rp -> rph -> rp = rp ;
22692256 rp -> nmissed = 0 ;
22702257 /* Establish function entry probe point */
22712258 ret = register_kprobe (& rp -> kp );
0 commit comments