Did you try your code?
When I execute your code 
require 'rake'
task :environment 
desc "foo1"
task :foo1, [ :mode ] => :environment do |t, args|
  mode = args[:mode]
  puts "foo1 mode = #{mode}"
end
desc "foo2"
task :foo2, [ :mode ] => :environment do |t, args|
  mode = args[:mode]
  puts "foo2 mode = #{mode}"
end
desc "all_foos"
task :all_foos, [ :mode ] => [ :foo1, :foo2 ]
Rake.application['all_foos'].invoke('par1')
I get
foo1 mode = par1
foo2 mode = par1
With 
Rake.application['all_foos'].invoke('par2')
I get: 
foo1 mode = par2
foo2 mode = par2
This is the solution you want.
Remark:
Rake.application['all_foos'].invoke('par2') is the same as an external rake call rake all_foos[par2]
To go further: You can also use different parameters.
CHeck this code:
require 'rake'
task :environment 
desc "foo1"
task :foo1, [ :mode1 ] => :environment do |t, args|
  mode = args[:mode1]
  puts "foo1 mode = #{mode}"
end
desc "foo2"
task :foo2, [ :mode2 ] => :environment do |t, args|
  mode = args[:mode2]
  puts "foo2 mode = #{mode}"
end
desc "all_foos"
task :all_foos, [ :mode1, :mode2 ] => [ :foo1, :foo2 ]
Rake.application['all_foos'].invoke('par1', 'par2')
With Rake.application['all_foos'].invoke('par1', 'par2') (or rake all_foos[par1,par2]) I get:
foo1 mode = par1
foo2 mode = par2
With Rake.application['all_foos'].invoke('par1', 'par2') (or rake all_foos[par1,par2]) I get:
foo1 mode = par1
foo2 mode = par2
With Rake.application['all_foos'].invoke(nil, 'par2') I get
foo1 mode = 
foo2 mode = par2
With Rake.application['all_foos'].invoke('par1') I get
foo1 mode = par1
foo2 mode = 
If your main task contains all parameter names, you can pick the needed parameters in your subtasks.
Disadvantage: The sequence in the call differs between main task and subtasks.