WP_query : meta_key with custom rule for specific value

A meta_query is an array of arrays. Look at the examples in the the Codex.

 $args = array(
   'post_type' => 'my_custom_post_type',
   'meta_key' => 'age',
   'orderby' => 'meta_value_num',
   'order' => 'ASC',
   'meta_query' => array(
       array(
           'key' => 'age',
           'value' => array(3, 4),
           'compare' => 'IN',
       )
   )
 );
 $query = new WP_Query($args);

What you have is just an array. That could be causing trouble. What you want to do is this:

$args = array(
   'post_type' => 'post',
   'meta_query'=> array(
      array(
          'key' => 'karma',
          'compare' => '>=', // limit to "karma value = 100"
          'value' => 0, // limit to "karma value = 100"
          'type' => 'numeric'
       )
    ),
   'posts_per_page' => 9,
   'meta_key' => 'karma',
   'orderby' => 'meta_value_num', 
   'order' => 'DESC',
   'post__not_in' => $dont_show_me
);

However, to get to the question itself, you can’t do logic as complicated as you need …

Show all posts with karma >= 0 (it works fine with this code). BUT if
there are posts with karma = 100 only show 3 of them + the rest of
posts.

… with a single WP_Query. That sounds like you want to pull 3, and only 3, posts with karma greater than 100, and fill in the rest with anything else. That would be tricky with pure SQL. I think it is possible in SQL but I would have to think a lot to be sure, much less to make it work.

I would suggest two queries– one to get the “greater than 100” and a second to get the rest.

$dont_show_me = array(1);
$args = array(
   'post_type' => 'post',
   'meta_query'=> array(
      array(
          'key' => 'karma',
          'compare' => '>=', 
          'value' => 100,
          'type' => 'numeric'
       )
    ),
   'posts_per_page' => 3,
   'meta_key' => 'karma',
   'orderby' => 'meta_value_num', 
   'order' => 'DESC',
   'post__not_in' => $dont_show_me
);
$karma_qry = new WP_Query($args);

if (!empty($karma_qry->posts)) {
  $args['posts_per_page'] = 9 - $karma_qry->found_posts;
  $args['meta_query'][0]['value'] = 0;
  foreach ($karma_qry->posts as $p) {
      // assuming $dont_show_me is an array
      $dont_show_me[] = $p->ID;
  }
  $args['post__not_in'] = $dont_show_me;
} else {
  $args['posts_per_page'] = 9;
  $args['meta_query'][0]['value'] = 0;
}

$the_rest_qry = new WP_Query($args);

I can’t test that as I don’t have your karma data on my server, but I am fairly sure that is correct. It ought to get you most of the way, at least.